Remove identifying labels with v4-only forensic audit uploads (#1779) #3569
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: | |
| pull_request: | |
| push: | |
| branches: | |
| - master | |
| merge_group: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_INCREMENTAL: "0" | |
| CARGO_PROFILE_TEST_DEBUG: "0" | |
| jobs: | |
| changes: | |
| name: Classify CI changes | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| run_full: ${{ steps.classify.outputs.run_full }} | |
| run_c: ${{ steps.classify.outputs.run_c }} | |
| run_conformance: ${{ steps.classify.outputs.run_conformance }} | |
| run_ios: ${{ steps.classify.outputs.run_ios }} | |
| run_formal: ${{ steps.classify.outputs.run_formal }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Classify changed paths | |
| id: classify | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "$EVENT_NAME" == "workflow_dispatch" \ | |
| || -z "$BASE_SHA" \ | |
| || "$BASE_SHA" =~ ^0+$ ]] \ | |
| || ! git cat-file -e "${BASE_SHA}^{commit}"; then | |
| python3 scripts/classify_ci_changes.py --all --github-output "$GITHUB_OUTPUT" </dev/null | |
| else | |
| # Disable rename detection so a code-to-Markdown rename exposes | |
| # both the removed code path and the added documentation path. | |
| git diff --no-renames --name-only -z "$BASE_SHA" "$GITHUB_SHA" \ | |
| | python3 scripts/classify_ci_changes.py --github-output "$GITHUB_OUTPUT" | |
| fi | |
| rust-format: | |
| name: Rust format | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal --component rustfmt | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Check formatting | |
| run: cargo fmt --all --check | |
| - name: Naming gate (retired legacy tokens) | |
| run: ./scripts/check_legacy_naming.sh | |
| - name: C binding command-surface parity gate | |
| run: python3 scripts/check_c_binding_parity.py | |
| - name: Install example SHA-256 gate | |
| run: | | |
| python3 scripts/check_install_example_sha256.py | |
| python3 scripts/test_install_example_sha256_gate.py | |
| - name: Campaign and QUIC broker image toolchain gate | |
| run: | | |
| ./scripts/check_campaign_toolchain.sh | |
| ./scripts/tests/test_campaign_toolchain.sh | |
| - name: Agent install documentation gate | |
| run: ./scripts/check_agent_install_docs.sh | |
| - name: CI policy and path-classifier gates | |
| run: | | |
| ./scripts/check_convergence_constant_ledger.sh | |
| python3 scripts/test_check_cargo_audit_ci.py | |
| python3 scripts/test_classify_ci_changes.py | |
| rust-audit: | |
| name: Rust audit | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Install cargo-audit | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 | |
| with: | |
| tool: cargo-audit@0.22.1 | |
| - name: Audit Rust dependencies | |
| # Cargo consumes --locked before dispatching to cargo-audit; cargo-audit | |
| # itself does not accept --locked after the subcommand. | |
| run: cargo --locked audit | |
| terminal-harness-installers: | |
| name: Terminal harness installer tests | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Test Codex, Pi, and OpenCode installers | |
| run: | | |
| set -euo pipefail | |
| integrations/terminal-harness/tests/test_installer.sh codex | |
| integrations/terminal-harness/tests/test_installer.sh pi | |
| integrations/terminal-harness/tests/test_installer.sh opencode | |
| rust-check: | |
| name: Rust check | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Check workspace | |
| run: RUSTFLAGS='-D warnings' cargo check --workspace --all-targets --locked | |
| - name: Check all features | |
| run: RUSTFLAGS='-D warnings' cargo check --workspace --all-targets --all-features --locked | |
| rust-wasm-check: | |
| name: Rust WASM check | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustup target add wasm32-unknown-unknown | |
| rustc --version | |
| cargo --version | |
| clang --version | |
| # Preflight the C toolchain before compiling ring for this target. | |
| clang --print-targets | grep wasm32 | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| # Compile-only regression gate. Browser runtime behavior belongs in | |
| # downstream headless-browser acceptance tests. | |
| - name: Build browser WASM libraries | |
| env: | |
| CC_wasm32_unknown_unknown: clang | |
| RUSTFLAGS: -D warnings | |
| run: | | |
| cargo build --locked --target wasm32-unknown-unknown \ | |
| -p cgka-traits \ | |
| -p cgka-engine \ | |
| -p transport-nostr-peeler | |
| rust-clippy: | |
| name: Rust clippy | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal --component clippy | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run clippy | |
| run: cargo clippy --workspace --all-targets --locked -- -D warnings | |
| - name: Run clippy with all features | |
| run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings | |
| c-smoke: | |
| name: C bindings smoke | |
| needs: changes | |
| if: needs.changes.outputs.run_c == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Install cbindgen | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 | |
| with: | |
| tool: cbindgen@0.29.4 | |
| - name: Header diff gate | |
| run: | | |
| set -euo pipefail | |
| # Pin the exact version so a newer cbindgen can't reformat the | |
| # checked-in header and fail the diff gate on unrelated PRs. | |
| # RUSTC_BOOTSTRAP=1 lets cbindgen expand the mirror-generating | |
| # macros on stable; it only affects header generation. | |
| RUSTC_BOOTSTRAP=1 cbindgen --config crates/marmot-c/cbindgen.toml --crate marmot-c \ | |
| --output crates/marmot-c/include/marmot.h crates/marmot-c | |
| git diff --exit-code crates/marmot-c/include/marmot.h | |
| - name: Alloc-audit tests | |
| run: cargo test -p marmot-c --features alloc-audit --locked | |
| - name: Compile and run debug C smoke test (gcc) | |
| run: ./crates/marmot-c/c-smoke.sh --debug gcc | |
| ios-account-clippy: | |
| name: iOS account keychain clippy | |
| needs: changes | |
| if: needs.changes.outputs.run_ios == 'true' | |
| runs-on: macos-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal --component clippy | |
| rustup default "$toolchain" | |
| rustup target add aarch64-apple-ios | |
| rustc --version | |
| cargo --version | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Check iOS account keychain code | |
| run: cargo clippy -p marmot-account --target aarch64-apple-ios --locked -- -D warnings | |
| # The broader integration matrix explicitly enables test-policy-overrides. | |
| # This focused default-feature job proves ordinary debug/release consumers | |
| # reject every non-v1 convergence policy (mdk#970). | |
| convergence-policy-pin: | |
| name: Convergence policy pin (release assertions) | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run default-build convergence policy pin tests | |
| # Keep in sync with `just test-convergence-policy-pin`. | |
| run: cargo test -p cgka-engine --test convergence_policy_pin --locked | |
| rust-test: | |
| name: Rust tests (${{ matrix.partition }}/4) | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| partition: [1, 2, 3, 4] | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 # nextest | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run workspace tests | |
| # The subprocess-heavy `wn-cli::cli` suite runs in its own | |
| # `cli-e2e` job so its fan-out never starves these fast unit tests | |
| # (issue #103). `relay_runtime` keeps its own serial job. | |
| run: cargo nextest run --workspace --exclude cgka-conformance-simulator --features wn-cli/test-policy-overrides,cgka-engine/test-crash-hooks --locked --profile ci --partition count:${{ matrix.partition }}/4 -E 'not (package(marmot-app) & binary(relay_runtime)) and not (package(wn-cli) & binary(cli))' | |
| - name: Run doctests | |
| if: matrix.partition == 1 | |
| run: cargo test --workspace --exclude cgka-conformance-simulator --doc --locked | |
| - name: Test consent and both diagnostic exporters | |
| if: matrix.partition == 1 | |
| run: | | |
| cargo test -p marmot-app --features otlp-export,product-analytics-export --lib product_analytics:: --locked | |
| cargo test -p marmot-app --features otlp-export,product-analytics-export --lib backend_maintenance_collects --locked | |
| cargo test -p marmot-app --features otlp-export,product-analytics-export --test relay_telemetry_otlp --locked | |
| cargo test -p marmot-c --features otlp-export,product-analytics-export,alloc-audit product_analytics --locked | |
| cargo test -p agent-connector --features otlp-export,product-analytics-export usage_diagnostics:: --locked | |
| cli-e2e: | |
| name: CLI e2e (mock relay) | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 # nextest | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run CLI end-to-end tests | |
| # Dedicated job: this subprocess-heavy suite is capped by the `cli-e2e` | |
| # test-group and the `ci` profile adds retries + a hung-test backstop. | |
| # The real-relay test self-skips here; it has its own `Relay CLI E2E` | |
| # job with a docker relay stack. | |
| run: cargo nextest run -p wn-cli --test cli --features test-policy-overrides --locked --profile ci | |
| relay-runtime: | |
| name: Relay runtime tests | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run relay runtime tests serially | |
| env: | |
| RUST_BACKTRACE: "1" | |
| run: cargo test -p marmot-app --test relay_runtime --features test-policy-overrides --locked -- --test-threads=1 | |
| - name: Run held peer-index upgrade lookup | |
| run: cargo test -p marmot-app --test startup_hydration --features test-policy-overrides --locked -- --exact existing_direct_conversation_is_not_a_miss_while_upgrade_backfill_is_held | |
| relay-e2e: | |
| name: Relay CLI E2E | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 # nextest | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Start local relay stack | |
| run: docker compose up -d setup nostr-rs-relay strfry-nostr-relay | |
| - name: Wait for local relays | |
| run: | | |
| docker compose ps | |
| ./scripts/wait_for_relays.sh | |
| - name: Run real relay CLI E2E | |
| env: | |
| MDK_E2E_REQUIRE_RELAYS: "1" | |
| run: cargo nextest run -p wn-cli --test cli --features test-policy-overrides --locked --profile ci -E 'test(=real_local_relays_deliver_cli_messages_over_sdk_path)' | |
| - name: Dump local relay logs | |
| if: failure() | |
| run: docker compose logs nostr-rs-relay strfry-nostr-relay || true | |
| - name: Stop local relay stack | |
| if: always() | |
| run: docker compose down -v | |
| conformance: | |
| name: Simulator and vectors | |
| needs: changes | |
| if: needs.changes.outputs.run_conformance == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Rust toolchain | |
| run: | | |
| set -euo pipefail | |
| toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml)" | |
| rustup toolchain install "$toolchain" --profile minimal | |
| rustup default "$toolchain" | |
| rustc --version | |
| cargo --version | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 # nextest | |
| - name: Install just | |
| uses: taiki-e/install-action@b18fb392e1a1b90971f7c7572c92790fa54f23d5 # just | |
| with: | |
| tool: just | |
| - name: Cache Cargo artifacts | |
| uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | |
| - name: Run simulator smoke tests | |
| # Multi-minute generated reliability batches and the adversarial | |
| # campaign run in the scheduled Simulator Nightly workflow. Independent | |
| # convergence checks run in their dedicated fast gate below. | |
| run: just simulator-smoke | |
| - name: Validate convergence execution-lane policy | |
| run: just convergence-lane-policy | |
| - name: Validate convergence failure-corpus lifecycle | |
| run: just convergence-failure-corpus | |
| - name: Run focused convergence regressions | |
| run: just focused-convergence-regressions | |
| - name: Run simulator doctests | |
| run: cargo test -p cgka-conformance-simulator --doc --locked | |
| - name: Verify convergence with independent models | |
| run: just convergence-verification-ci | |
| formal: | |
| name: Tamarin proofs | |
| needs: changes | |
| if: needs.changes.outputs.run_formal == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install Tamarin dependencies | |
| timeout-minutes: 15 | |
| run: | | |
| set -euo pipefail | |
| for attempt in 1 2 3; do | |
| if sudo timeout --kill-after=15s 180s apt-get \ | |
| -o Acquire::Retries=3 \ | |
| -o Acquire::http::Timeout=30 \ | |
| -o Acquire::https::Timeout=30 \ | |
| update; then | |
| break | |
| fi | |
| if [[ "$attempt" == 3 ]]; then | |
| echo "apt-get update failed after $attempt attempts" >&2 | |
| exit 1 | |
| fi | |
| echo "apt-get update attempt $attempt failed; retrying" >&2 | |
| done | |
| sudo apt-get \ | |
| -o Acquire::Retries=3 \ | |
| -o Acquire::http::Timeout=30 \ | |
| -o Acquire::https::Timeout=30 \ | |
| -o DPkg::Lock::Timeout=60 \ | |
| install -y --no-install-recommends graphviz maude | |
| - name: Install Tamarin | |
| env: | |
| TAMARIN_VERSION: 1.12.0 | |
| run: | | |
| set -euo pipefail | |
| curl -L --fail --show-error --silent \ | |
| "https://github.com/tamarin-prover/tamarin-prover/releases/download/${TAMARIN_VERSION}/tamarin-prover-${TAMARIN_VERSION}-linux64-ubuntu.tar.gz" \ | |
| -o /tmp/tamarin-prover.tar.gz | |
| tar -xzf /tmp/tamarin-prover.tar.gz -C /tmp | |
| sudo install -m 0755 /tmp/tamarin-prover /usr/local/bin/tamarin-prover | |
| tamarin-prover --version | |
| - name: Run Tamarin proofs | |
| run: make -C formal/tamarin prove | |
| hermes-installer-auth: | |
| name: Hermes installer auth | |
| needs: changes | |
| if: needs.changes.outputs.run_full == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| persist-credentials: false | |
| - name: Install system dependencies | |
| timeout-minutes: 15 | |
| run: | | |
| set -euo pipefail | |
| venv_check_dir="${RUNNER_TEMP}/hermes-venv-check" | |
| if command -v python3 >/dev/null \ | |
| && command -v git >/dev/null \ | |
| && python3 -m venv "$venv_check_dir"; then | |
| rm -rf "$venv_check_dir" | |
| exit 0 | |
| fi | |
| rm -rf "$venv_check_dir" | |
| for attempt in 1 2 3; do | |
| if sudo timeout --kill-after=15s 180s apt-get \ | |
| -o Acquire::Retries=3 \ | |
| -o Acquire::http::Timeout=30 \ | |
| -o Acquire::https::Timeout=30 \ | |
| update; then | |
| break | |
| fi | |
| if [[ "$attempt" == 3 ]]; then | |
| echo "apt-get update failed after $attempt attempts" >&2 | |
| exit 1 | |
| fi | |
| echo "apt-get update attempt $attempt failed; retrying" >&2 | |
| done | |
| sudo apt-get \ | |
| -o Acquire::Retries=3 \ | |
| -o Acquire::http::Timeout=30 \ | |
| -o Acquire::https::Timeout=30 \ | |
| -o DPkg::Lock::Timeout=60 \ | |
| install -y --no-install-recommends python3 python3-venv git | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0 | |
| - name: Hermes configure_gateway Python unit tests | |
| run: | | |
| set -euo pipefail | |
| env -i HOME="$HOME" PATH="$PATH" USER="${USER:-runner}" \ | |
| python3 -m unittest discover -s integrations/hermes/tests/marmot -v | |
| - name: Prepare isolated Hermes environment for authorization E2E | |
| run: | | |
| set -euo pipefail | |
| ./scripts/hermes_marmot_dev_setup.sh \ | |
| --root "$RUNNER_TEMP/hermes-installer-auth" \ | |
| --install-pinned-wheel | |
| - name: Hermes installer unit and mock regressions | |
| run: | | |
| set -euo pipefail | |
| bash -n scripts/install-hermes-marmot.sh | |
| bash -n integrations/hermes/tests/marmot/test_installer_env.sh | |
| bash -n scripts/hermes_marmot_deterministic_e2e.sh | |
| python3 -m py_compile scripts/hermes_marmot_configure_gateway.py integrations/hermes/tests/marmot/e2e_gateway_auth.py | |
| integrations/hermes/tests/marmot/test_dev_scripts.sh | |
| - name: Real Hermes authorization and deterministic Marmot E2E | |
| run: | | |
| set -euo pipefail | |
| # The deterministic runner sources the pinned dev root, runs | |
| # test_installer_env.sh against its real GatewayRunner, then runs the | |
| # adapter E2E. A missing Hermes venv is a hard failure, not a skip. | |
| ./scripts/hermes_marmot_deterministic_e2e.sh --root "$RUNNER_TEMP/hermes-installer-auth" | |
| required-ci: | |
| name: Required CI | |
| if: always() | |
| needs: | |
| - changes | |
| - rust-format | |
| - rust-audit | |
| - terminal-harness-installers | |
| - rust-check | |
| - rust-wasm-check | |
| - rust-clippy | |
| - c-smoke | |
| - ios-account-clippy | |
| - convergence-policy-pin | |
| - rust-test | |
| - cli-e2e | |
| - relay-runtime | |
| - relay-e2e | |
| - conformance | |
| - formal | |
| - hermes-installer-auth | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Require every selected core CI job to succeed | |
| env: | |
| NEEDS: ${{ toJSON(needs) }} | |
| run: | | |
| jq --exit-status 'all(.[]; .result == "success" or .result == "skipped")' <<<"$NEEDS" |