hardening: deploy payload guard; 0.6.3 (#11) #31
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
| name: CI | |
| on: | |
| push: { branches: [main] } | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| python: | |
| uses: CitrateNetwork/.github/.github/workflows/reusable-python-ci.yml@db5f1a6ddaec28275708265b56762eb1dfc3571b # main | |
| # PBA-L6b-041: uv.lock drifted from pyproject (it locked cryptography 46.0.7 | |
| # while pyproject requires >=48.0.1) because nothing checked it. Fail when the | |
| # lock no longer matches pyproject.toml. | |
| uv-lock-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.11' | |
| - run: python -m pip install "uv==0.12.19" | |
| - name: uv.lock matches pyproject.toml | |
| run: uv lock --check | |
| # The shared python job installs with an unpinned `pip install -e .[dev]`, | |
| # which can resolve newer dependencies than uv.lock. This job runs the same | |
| # lint, type and test steps inside the frozen lockfile environment, so CI | |
| # and a local `uv sync --frozen` see the same dependency versions. | |
| locked-env: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.11' | |
| - run: python -m pip install "uv==0.12.19" | |
| - name: Install from uv.lock (frozen) | |
| run: uv sync --frozen --all-extras --python 3.11 | |
| - name: Lint (ruff) | |
| run: uv run --frozen ruff check . | |
| - name: Type-check (mypy) | |
| run: uv run --frozen mypy . | |
| - name: Test (pytest, locked dependencies) | |
| run: uv run --frozen pytest -q | |
| - name: Dependency audit of the locked set (pip-audit) | |
| run: uv run --frozen --with "pip-audit==2.10.0" pip-audit --skip-editable | |
| # PBA-L6b-003 tripwire on the BUILT wheel: build it the way a release does, | |
| # import citrate_sdk from the unpacked wheel only, and assert that no subset | |
| # of the deploy_model calldata reconstructs the model key. The source-tree | |
| # twin is tests/test_pba_r2_l6b_keyshares.py. | |
| keyshare-wheel-tripwire: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.11' | |
| - run: python -m pip install --upgrade pip && pip install -e . | |
| - name: Key-share leak tripwire (built wheel) | |
| run: python scripts/check_keyshare_wheel.py | |
| # CL-C2 / SW-092: fail the build if the vendored federation_contract artifact | |
| # drifts from the canonical federation intermediate (which federation's | |
| # contract-artifact-drift gate keeps fresh vs citrate-chain). The reusable | |
| # python CI only runs ruff/mypy/pytest, so vendored-address drift shipped | |
| # silently. Requires a read-only token for CitrateNetwork/citrate-federation; | |
| # inert until GitHub Actions + CITRATE_FEDERATION_READ_TOKEN are available (the | |
| # local mirror scripts/check-contract-drift.sh runs the identical check). | |
| contract-drift: | |
| runs-on: ubuntu-latest | |
| # Internal-only gate (checks the vendored artifact against the canonical intermediate in the | |
| # PRIVATE citrate-federation). Skips on public/fork CI (no token) so public CI never touches a | |
| # private repo; runs authoritatively on internal pushes once CITRATE_FEDERATION_READ_TOKEN is set. | |
| env: | |
| FED_TOKEN: ${{ secrets.CITRATE_FEDERATION_READ_TOKEN }} | |
| steps: | |
| - name: Skipped on public/fork CI (no federation read token) | |
| if: env.FED_TOKEN == '' | |
| run: echo "contract-drift is an internal supply-chain gate; skipped without CITRATE_FEDERATION_READ_TOKEN." | |
| - name: Checkout this repo | |
| if: env.FED_TOKEN != '' | |
| uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| path: citrate-sdk-python | |
| - name: Checkout canonical citrate-federation intermediate (sparse) | |
| if: env.FED_TOKEN != '' | |
| uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| repository: CitrateNetwork/citrate-federation | |
| ref: main | |
| token: ${{ secrets.CITRATE_FEDERATION_READ_TOKEN }} | |
| path: citrate-federation | |
| sparse-checkout: | | |
| contract | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| if: env.FED_TOKEN != '' | |
| with: | |
| python-version: '3.11' | |
| - name: Contract-artifact drift gate (blocking) | |
| if: env.FED_TOKEN != '' | |
| run: python scripts/sync_contract.py --check | |
| working-directory: citrate-sdk-python |