Spaces:
Sleeping
Sleeping
| name: hermes-ci | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: hermes-ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PYTHONPATH: hermes_overlay | |
| TRADING_MODE: paper | |
| HERMES_EXECUTION_ENABLED: "false" | |
| HERMES_NONPAPER_EXECUTION_ENABLED: "false" | |
| jobs: | |
| quality-and-tests: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: "3.13.5" | |
| cache: pip | |
| cache-dependency-path: | | |
| requirements.lock | |
| requirements-ci.lock | |
| - name: Install locked dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements.lock -r requirements-ci.lock | |
| python -m pip check | |
| - name: Verify deterministic metadata and inventory | |
| run: | | |
| npm ci --ignore-scripts --no-audit --no-fund | |
| npm run check:js | |
| python scripts/generate_dependency_inventory.py --check | |
| python scripts/verify_repository_metadata.py | |
| - name: Compile Python | |
| run: python -m compileall hermes_overlay scripts app.py -q | |
| - name: Lint Python | |
| run: python -m ruff check hermes_overlay scripts app.py | |
| - name: Type-check execution-critical Python | |
| run: | | |
| python -m mypy \ | |
| hermes_overlay/trading/config_validation.py \ | |
| hermes_overlay/trading/domain/execution_service.py \ | |
| hermes_overlay/trading/domain/plan_revalidation.py \ | |
| hermes_overlay/trading/provider_contracts.py \ | |
| scripts/validate_runbook_consistency.py | |
| - name: Check shell and JavaScript syntax | |
| run: | | |
| bash -n scripts/entrypoint.sh | |
| node --check scripts/dns-fix.cjs | |
| find hermes_overlay -type f -name '*.js' -print0 | xargs -0 -r -n1 node --check | |
| - name: Run complete test suite with branch coverage | |
| run: | | |
| python -m pytest hermes_overlay/tests -q \ | |
| --cov=hermes_overlay \ | |
| --cov=scripts \ | |
| --cov-branch \ | |
| --cov-report=term-missing \ | |
| --cov-report=json:coverage.json \ | |
| --cov-report=xml:coverage.xml | |
| - name: Enforce critical-module branch coverage | |
| run: python scripts/check_critical_coverage.py coverage.json | |
| - name: Prove failing tests block CI | |
| run: python scripts/verify_ci_failure_contract.py | |
| - name: Upload coverage artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: coverage | |
| path: coverage.xml | |
| if-no-files-found: error | |
| security-and-data-gates: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 | |
| with: | |
| python-version: "3.13.5" | |
| cache: pip | |
| cache-dependency-path: | | |
| requirements.lock | |
| requirements-ci.lock | |
| - name: Install locked dependencies | |
| run: python -m pip install -r requirements.lock -r requirements-ci.lock | |
| - name: Secret scan | |
| run: python scripts/ci_secret_scan.py | |
| - name: Python dependency vulnerability scan | |
| run: python -m pip_audit -r requirements.lock --no-deps --disable-pip --strict | |
| - name: Dependency license inventory | |
| run: >- | |
| python scripts/check_dependency_licenses.py | |
| --declared-from requirements.lock requirements-ci.lock | |
| --output dependency-licenses.json | |
| - name: Migration verification | |
| run: python scripts/check_migrations.py | |
| - name: Required negative/failure gates | |
| run: python scripts/verify_required_failures.py | |
| - name: Strict runbook consistency | |
| run: python scripts/validate_runbook_consistency.py | |
| - name: Upload dependency evidence | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: dependency-evidence | |
| path: | | |
| docs/dependency_inventory.json | |
| dependency-licenses.json | |
| if-no-files-found: error | |
| container-build: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 75 | |
| needs: [quality-and-tests, security-and-data-gates] | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Verify immutable Docker inputs | |
| run: python -m pytest hermes_overlay/tests/test_build_reproducibility.py hermes_overlay/tests/test_upstream_integration_preflight.py -q | |
| - name: Build exact-pinned container | |
| run: | | |
| docker build \ | |
| --pull \ | |
| --build-arg HERMES_UPSTREAM_REF=8fc278207b0f5b25e567966f9615e1b1737f62af \ | |
| --tag hermesface:${{ github.sha }} \ | |
| . | |
| - name: Inspect pinned upstream marker | |
| run: | | |
| test "$(docker run --rm --entrypoint cat hermesface:${{ github.sha }} /opt/hermes/HERMES_UPSTREAM_COMMIT)" = \ | |
| "8fc278207b0f5b25e567966f9615e1b1737f62af" | |
| - name: Container vulnerability scan | |
| run: | | |
| docker run --rm \ | |
| -v /var/run/docker.sock:/var/run/docker.sock \ | |
| aquasec/trivy:0.72.0 image \ | |
| --exit-code 1 --ignore-unfixed --severity HIGH,CRITICAL \ | |
| hermesface:${{ github.sha }} | |