Repository navigation
agent: localization design and plan (Fluent) #1281
Workflow file for this run
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: OpenSecret EIF approval checks | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| branches: [master] | |
| workflow_dispatch: | |
| # Cache writes are not PCR approval, release publication, or deployment. | |
| # OIDC is limited to master and same-repository PRs in the trusted job below. | |
| permissions: | |
| contents: read | |
| concurrency: | |
| # PRs replace superseded runs; master and manual runs are grouped per SHA and | |
| # never cancelled, so every master commit gets its approval verdict. | |
| group: opensecret-eif-${{ github.event_name }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| # opensecret_change_detection.py's outputs for this diff. A PR whose diff | |
| # cannot be classified fails here rather than guessing an approval edit. | |
| changes: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| rust: ${{ steps.classify.outputs.rust }} | |
| nix: ${{ steps.classify.outputs.nix }} | |
| integration: ${{ steps.classify.outputs.integration }} | |
| audit: ${{ steps.classify.outputs.audit }} | |
| eif: ${{ steps.classify.outputs.eif }} | |
| helpers: ${{ steps.classify.outputs.helpers }} | |
| pcr_approvals: ${{ steps.classify.outputs.pcr_approvals }} | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Classify changed paths | |
| id: classify | |
| run: python3 scripts/ci/plan.py opensecret | |
| eif: | |
| name: EIF/PCR approval match (${{ matrix.mode }}) | |
| needs: changes | |
| # PR comparison requires an actual edit to one of the four approval files. | |
| # A selector failure fails the changes job, not a speculative PCR comparison. | |
| if: >- | |
| ${{ | |
| always() && !cancelled() && | |
| ( | |
| (github.event_name == 'workflow_dispatch' && github.ref != 'refs/heads/master') || | |
| (github.event_name == 'pull_request' && | |
| github.event.pull_request.head.repo.full_name != github.repository && | |
| needs.changes.result == 'success' && | |
| needs.changes.outputs.pcr_approvals == 'true') | |
| ) | |
| }} | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 90 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| mode: [dev, prod] | |
| env: | |
| EIF_MODE: ${{ matrix.mode }} | |
| OPENSECRET_DEV_POSTGRES: "0" | |
| OPENSECRET_DEV_ENV: "0" | |
| OPENSECRET_DEV_CONTAINERS: "0" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| fetch-depth: 0 | |
| - name: Install pinned Nix | |
| uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3 | |
| with: | |
| source-tag: v3.23.3 | |
| github-token: "" | |
| - name: Verify pinned Nix runtime | |
| run: bash scripts/ci/verify-nix-runtime.sh | |
| # Fork PRs cannot authenticate to FlakeHub. GitHub scopes cache writes | |
| # to the PR merge ref; those entries cannot populate master's cache. | |
| - name: Reuse branch-scoped Nix cache without FlakeHub credentials | |
| uses: DeterminateSystems/magic-nix-cache-action@3c034b51a9deec0a09ef1df8b436ac5db50fae94 | |
| with: | |
| source-revision: 4cc363589df8090801c098cdcde1bdd42562318a | |
| use-flakehub: disabled | |
| use-gha-cache: enabled | |
| # A PCR mismatch (exit 3) fails a PR that edits this mode's approval files | |
| # and a manual run outside master. On master it is pending approval: a | |
| # notice, with the built PCRs in the step summary. | |
| - name: Build EIF and compare approved measurements | |
| shell: bash | |
| env: | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| log="$RUNNER_TEMP/eif-$EIF_MODE.out" | |
| status=0 | |
| bash scripts/ci/check_opensecret_eif.sh "$EIF_MODE" > "$log" || status=$? | |
| cat -- "$log" | |
| if [[ $status -ne 3 ]]; then | |
| exit "$status" | |
| fi | |
| case "$EIF_MODE" in | |
| dev) approvals=(services/opensecret/pcrDev.json services/opensecret/pcrDevHistory.json) ;; | |
| prod) approvals=(services/opensecret/pcrProd.json services/opensecret/pcrProdHistory.json) ;; | |
| *) exit 1 ;; | |
| esac | |
| required="" # why this mismatch fails the job; empty while it awaits approval | |
| if [[ $GITHUB_EVENT_NAME == pull_request ]]; then | |
| # The PR's own diff from the merge base, as the changes job reads it. | |
| # Both ends must be full commit ids, never options or abbreviations. | |
| if ! [[ $PR_BASE_SHA =~ ^[0-9a-f]{40}$ && $PR_HEAD_SHA =~ ^[0-9a-f]{40}$ ]] || | |
| ! edited=$(git diff --name-only --no-renames "$PR_BASE_SHA...$PR_HEAD_SHA" -- "${approvals[@]}"); then | |
| echo "::error::Cannot tell whether this PR edits the $EIF_MODE approval files." | |
| exit 1 | |
| fi | |
| if [[ -n $edited ]]; then | |
| required="this PR edits the $EIF_MODE approval files" | |
| fi | |
| elif [[ $GITHUB_REF != refs/heads/master ]]; then | |
| required="a manual run outside master must match" | |
| fi | |
| verdict=pending | |
| if [[ -n $required ]]; then | |
| verdict=mismatch | |
| fi | |
| { | |
| echo "### EIF/PCR approval $verdict ($EIF_MODE)" | |
| echo | |
| echo "The built measurements differ from \`${approvals[0]}\`." | |
| echo | |
| echo '```text' | |
| cat -- "$log" | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| if [[ -n $required ]]; then | |
| echo "::error::EIF/PCR approval mismatch ($EIF_MODE): $required." | |
| exit 3 | |
| fi | |
| echo "::notice title=EIF/PCR approval pending ($EIF_MODE)::This revision's $EIF_MODE measurements are not approved yet. Approval is the manual release process, not a CI failure." | |
| eif-trusted: | |
| name: EIF/PCR approval match (trusted, ${{ matrix.mode }}) | |
| needs: changes | |
| # Trust the PR's head repository, not its branch name or author's association. | |
| # Forks and missing head-repository metadata stay in the unprivileged job. | |
| if: >- | |
| ${{ | |
| always() && !cancelled() && | |
| ( | |
| (github.event_name == 'pull_request' && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| needs.changes.result == 'success' && | |
| needs.changes.outputs.pcr_approvals == 'true') || | |
| (github.ref == 'refs/heads/master' && | |
| ( | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && | |
| (needs.changes.result != 'success' || needs.changes.outputs.eif != 'false')) | |
| )) | |
| ) | |
| }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| runs-on: blacksmith-16vcpu-ubuntu-2404-arm | |
| timeout-minutes: 180 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| mode: [dev, prod] | |
| env: | |
| EIF_MODE: ${{ matrix.mode }} | |
| OPENSECRET_DEV_POSTGRES: "0" | |
| OPENSECRET_DEV_ENV: "0" | |
| OPENSECRET_DEV_CONTAINERS: "0" | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| persist-credentials: false | |
| submodules: recursive | |
| fetch-depth: 0 | |
| - name: Install pinned Determinate Nix for FlakeHub authentication | |
| uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3 | |
| with: | |
| source-tag: v3.23.3 | |
| github-token: "" | |
| - name: Verify pinned Nix runtime | |
| run: bash scripts/ci/verify-nix-runtime.sh | |
| - name: Reuse FlakeHub with an Actions cache fallback | |
| uses: DeterminateSystems/flakehub-cache-action@1f9a51a2959d3e26c7838c6f3bf9f48acae525ea # v3 | |
| with: | |
| # Cache substituted paths without forcing a second cache upload. | |
| diff-store: true | |
| # A PCR mismatch (exit 3) fails a PR that edits this mode's approval files | |
| # and a manual run outside master. On master it is pending approval: a | |
| # notice, with the built PCRs in the step summary. | |
| - name: Build EIF and compare approved measurements | |
| shell: bash | |
| env: | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| log="$RUNNER_TEMP/eif-$EIF_MODE.out" | |
| status=0 | |
| bash scripts/ci/check_opensecret_eif.sh "$EIF_MODE" > "$log" || status=$? | |
| cat -- "$log" | |
| if [[ $status -ne 3 ]]; then | |
| exit "$status" | |
| fi | |
| case "$EIF_MODE" in | |
| dev) approvals=(services/opensecret/pcrDev.json services/opensecret/pcrDevHistory.json) ;; | |
| prod) approvals=(services/opensecret/pcrProd.json services/opensecret/pcrProdHistory.json) ;; | |
| *) exit 1 ;; | |
| esac | |
| required="" # why this mismatch fails the job; empty while it awaits approval | |
| if [[ $GITHUB_EVENT_NAME == pull_request ]]; then | |
| # The PR's own diff from the merge base, as the changes job reads it. | |
| # Both ends must be full commit ids, never options or abbreviations. | |
| if ! [[ $PR_BASE_SHA =~ ^[0-9a-f]{40}$ && $PR_HEAD_SHA =~ ^[0-9a-f]{40}$ ]] || | |
| ! edited=$(git diff --name-only --no-renames "$PR_BASE_SHA...$PR_HEAD_SHA" -- "${approvals[@]}"); then | |
| echo "::error::Cannot tell whether this PR edits the $EIF_MODE approval files." | |
| exit 1 | |
| fi | |
| if [[ -n $edited ]]; then | |
| required="this PR edits the $EIF_MODE approval files" | |
| fi | |
| elif [[ $GITHUB_REF != refs/heads/master ]]; then | |
| required="a manual run outside master must match" | |
| fi | |
| verdict=pending | |
| if [[ -n $required ]]; then | |
| verdict=mismatch | |
| fi | |
| { | |
| echo "### EIF/PCR approval $verdict ($EIF_MODE)" | |
| echo | |
| echo "The built measurements differ from \`${approvals[0]}\`." | |
| echo | |
| echo '```text' | |
| cat -- "$log" | |
| echo '```' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| if [[ -n $required ]]; then | |
| echo "::error::EIF/PCR approval mismatch ($EIF_MODE): $required." | |
| exit 3 | |
| fi | |
| echo "::notice title=EIF/PCR approval pending ($EIF_MODE)::This revision's $EIF_MODE measurements are not approved yet. Approval is the manual release process, not a CI failure." |