Change development environment setup repository URL #98
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================================== | |
| # File: .github/workflows/ci.yml | |
| # Project: Apotropaios - Firewall Manager (Python Variant) | |
| # Synopsis: Continuous integration pipeline | |
| # Description: Runs on every push and PR: static lint (pyflakes), mypy | |
| # strict type checking, pytest suite across Python 3.12 and | |
| # 3.13 with coverage artifact upload, dedicated security-test | |
| # job, and repository consistency verification (version | |
| # locations and documentation accuracy). | |
| # Notes: - Action pins follow the project standard: checkout@v6, | |
| # upload-artifact@v6 | |
| # - Concurrency cancels superseded runs per ref | |
| # Version: 1.6.2 | |
| # ============================================================================== | |
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ============================================================================ | |
| # Static Lint (pyflakes) | |
| # ============================================================================ | |
| lint: | |
| name: Lint (pyflakes) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install pyflakes | |
| run: pip3 install pyflakes | |
| - name: Run pyflakes (intentional re-export/registration imports excepted) | |
| run: | | |
| python3 -m pyflakes apotropaios/ scripts/ tests/ | |
| - name: Run pyflakes on tests | |
| run: python3 -m pyflakes tests/ | |
| # ============================================================================ | |
| # Type Checking (mypy --strict) | |
| # ============================================================================ | |
| typecheck: | |
| name: Type Check (mypy --strict) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install mypy | |
| run: pip3 install mypy | |
| - name: Run mypy strict | |
| run: python3 -m mypy apotropaios/ --strict --python-version 3.12 | |
| # ============================================================================ | |
| # Test Suite (pytest across Python matrix) | |
| # ============================================================================ | |
| test: | |
| name: Test (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.12", "3.13"] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| - name: Install dev dependencies | |
| # PyYAML is required by the CI meta-suite (tests/ci); without it those | |
| # tests skip silently and the suite total drops below the documented count | |
| run: pip3 install pytest pytest-cov pyyaml | |
| - name: Run test suite with coverage | |
| run: | | |
| python3 -m pytest tests/ -v --tb=short \ | |
| --cov=apotropaios --cov-report=xml --cov-report=term | |
| - name: Upload coverage artifact | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: coverage-py${{ matrix.python-version }} | |
| path: coverage.xml | |
| retention-days: 14 | |
| # ============================================================================ | |
| # Security Tests (injection, traversal) | |
| # ============================================================================ | |
| security: | |
| name: Security Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install pytest | |
| run: pip3 install pytest | |
| - name: Run security tests | |
| run: python3 -m pytest tests/security/ -v --tb=short | |
| # ============================================================================ | |
| # Repository Consistency (versions + documentation accuracy) | |
| # ============================================================================ | |
| consistency: | |
| name: Consistency (versions, docs) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install pytest and PyYAML | |
| # The docs validator verifies the collected suite total; PyYAML must be | |
| # present or the CI meta-suite is excluded from collection and the | |
| # documented count cannot match | |
| run: pip3 install pytest pyyaml | |
| - name: Verify version consistency | |
| run: python3 scripts/check_version_consistency.py | |
| - name: Verify documentation accuracy | |
| run: python3 scripts/validate_docs.py | |
| # ============================================================================ | |
| # Badge Publication (main only, after all gates pass) | |
| # ============================================================================ | |
| badges: | |
| name: Publish Badge Data | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| needs: [lint, typecheck, test, security, consistency] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| - name: Install pytest and PyYAML | |
| run: pip3 install pytest pyyaml | |
| - name: Download coverage artifact | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: coverage-py3.12 | |
| path: . | |
| - name: Generate badge endpoint JSON | |
| # mypy passes by gate (needs: typecheck); test count from collection; | |
| # coverage percent parsed from the matrix job's coverage.xml artifact | |
| run: | | |
| mkdir -p badge-data | |
| COUNT=$(python3 -m pytest tests/ --collect-only -q 2>/dev/null | grep -oP '\d+(?= tests collected)') | |
| COVERAGE=$(python3 -c "import xml.etree.ElementTree as ET; print(f\"{float(ET.parse('coverage.xml').getroot().get('line-rate'))*100:.0f}\")") | |
| python3 - "$COUNT" "$COVERAGE" << 'PYEOF' | |
| import json | |
| import sys | |
| count, coverage = sys.argv[1], sys.argv[2] | |
| badges = { | |
| "mypy.json": { | |
| "schemaVersion": 1, "label": "mypy", | |
| "message": "strict passing", "color": "brightgreen", | |
| }, | |
| "tests.json": { | |
| "schemaVersion": 1, "label": "pytest", | |
| "message": f"{count} passing", "color": "brightgreen", | |
| }, | |
| "coverage.json": { | |
| "schemaVersion": 1, "label": "coverage", | |
| "message": f"{coverage}%", "color": "brightgreen", | |
| }, | |
| } | |
| for name, payload in badges.items(): | |
| with open(f"badge-data/{name}", "w", encoding="utf-8") as f: | |
| json.dump(payload, f) | |
| PYEOF | |
| - name: Publish to badges branch | |
| run: | | |
| cd badge-data | |
| git init -q -b badges | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add . | |
| git commit -qm "Update badge data for ${GITHUB_SHA}" | |
| git push -f "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" badges | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |