chore(ci): remove duplicate Trust test suite (#491) #326
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: trust | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: read | |
| jobs: | |
| trust: | |
| name: trust | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | |
| fetch-depth: 0 | |
| - name: Classify an exact metadata-only child | |
| id: child | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| HEAD_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| { | |
| echo "reuse=false" | |
| echo "kind=implementation" | |
| echo "parent_sha=" | |
| } >> "$GITHUB_OUTPUT" | |
| if [[ "$EVENT_NAME" != "pull_request" ]]; then | |
| exit 0 | |
| fi | |
| parent_line="$(git rev-list --parents -n 1 "$HEAD_SHA")" | |
| if [[ "$(wc -w <<<"$parent_line" | tr -d ' ')" != "2" ]]; then | |
| exit 0 | |
| fi | |
| parent_sha="$(git rev-parse "${HEAD_SHA}^")" | |
| classification="$( | |
| git diff --name-status -z -M "$parent_sha" "$HEAD_SHA" \ | |
| | .github/scripts/classify-ci-paths.sh \ | |
| "$GITHUB_WORKSPACE" false name-status | |
| )" | |
| if grep -Fxq "review_only=true" <<<"$classification"; then | |
| kind=review | |
| elif grep -Fxq "archive_only=true" <<<"$classification"; then | |
| kind=archive | |
| else | |
| exit 0 | |
| fi | |
| { | |
| echo "reuse=true" | |
| echo "kind=$kind" | |
| echo "parent_sha=$parent_sha" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Reuse exact parent trust provenance | |
| if: steps.child.outputs.reuse == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REPOSITORY: ${{ github.repository }} | |
| SERVER_URL: ${{ github.server_url }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| PARENT_SHA: ${{ steps.child.outputs.parent_sha }} | |
| CHILD_KIND: ${{ steps.child.outputs.kind }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| checks_file="${RUNNER_TEMP}/specsync-parent-trust-checks.json" | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| "repos/${REPOSITORY}/commits/${PARENT_SHA}/check-runs?per_page=100" \ | |
| > "$checks_file" | |
| export CHECKS_FILE="$checks_file" | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| import re | |
| import subprocess | |
| parent = os.environ["PARENT_SHA"] | |
| repository = os.environ["REPOSITORY"] | |
| server_url = os.environ["SERVER_URL"].rstrip("/") | |
| pull_request = int(os.environ["PR_NUMBER"]) | |
| with open(os.environ["CHECKS_FILE"], encoding="utf-8") as handle: | |
| checks = json.load(handle).get("check_runs", []) | |
| def api(endpoint: str) -> dict: | |
| output = subprocess.check_output( | |
| [ | |
| "gh", | |
| "api", | |
| "-H", | |
| "Accept: application/vnd.github+json", | |
| "-H", | |
| "X-GitHub-Api-Version: 2022-11-28", | |
| endpoint, | |
| ], | |
| text=True, | |
| ) | |
| return json.loads(output) | |
| github_actions_app = api("apps/github-actions") | |
| if ( | |
| github_actions_app.get("slug") != "github-actions" | |
| or github_actions_app.get("name") != "GitHub Actions" | |
| or (github_actions_app.get("owner") or {}).get("login") != "github" | |
| ): | |
| raise SystemExit("could not resolve the official GitHub Actions app") | |
| errors = [] | |
| candidates = sorted( | |
| (check for check in checks if check.get("name") == "trust"), | |
| key=lambda check: int(check.get("id", 0)), | |
| reverse=True, | |
| ) | |
| for check in candidates: | |
| try: | |
| if check.get("head_sha") != parent: | |
| raise ValueError("wrong head SHA") | |
| if ( | |
| check.get("status") != "completed" | |
| or check.get("conclusion") != "success" | |
| ): | |
| raise ValueError("check is not successful") | |
| app = check.get("app") or {} | |
| if ( | |
| app.get("id") != github_actions_app.get("id") | |
| or app.get("slug") != github_actions_app.get("slug") | |
| ): | |
| raise ValueError("check is not from GitHub Actions") | |
| details_url = str(check.get("details_url") or "") | |
| match = re.fullmatch( | |
| ( | |
| rf"{re.escape(server_url)}/{re.escape(repository)}" | |
| r"/actions/runs/([0-9]+)/job/[0-9]+" | |
| ), | |
| details_url, | |
| ) | |
| if match is None: | |
| raise ValueError("invalid GitHub Actions details URL") | |
| run_id = int(match.group(1)) | |
| workflow_run = api( | |
| f"repos/{repository}/actions/runs/{run_id}" | |
| ) | |
| if workflow_run.get("id") != run_id: | |
| raise ValueError("wrong workflow run ID") | |
| if workflow_run.get("head_sha") != parent: | |
| raise ValueError("workflow run has the wrong head SHA") | |
| if workflow_run.get("event") != "pull_request": | |
| raise ValueError("workflow run is not for a pull request") | |
| if ( | |
| workflow_run.get("status") != "completed" | |
| or workflow_run.get("conclusion") != "success" | |
| ): | |
| raise ValueError("workflow run is not successful") | |
| if ( | |
| str(workflow_run.get("path") or "").split("@", 1)[0] | |
| != ".github/workflows/trust.yml" | |
| ): | |
| raise ValueError("workflow run has the wrong path") | |
| if (workflow_run.get("repository") or {}).get( | |
| "full_name" | |
| ) != repository: | |
| raise ValueError("workflow run belongs to another repository") | |
| if not any( | |
| item.get("number") == pull_request | |
| for item in workflow_run.get("pull_requests") or [] | |
| ): | |
| raise ValueError("workflow run is not bound to this PR") | |
| print( | |
| f"Reused trust run {run_id} from exact parent {parent} " | |
| f"for the {os.environ['CHILD_KIND']} child." | |
| ) | |
| break | |
| except ( | |
| json.JSONDecodeError, | |
| subprocess.CalledProcessError, | |
| TypeError, | |
| ValueError, | |
| ) as error: | |
| errors.append(f"check {check.get('id')}: {error}") | |
| else: | |
| detail = "; ".join(errors) if errors else "no matching trust checks" | |
| raise SystemExit(f"parent trust provenance is not reusable: {detail}") | |
| PY | |
| - uses: dtolnay/rust-toolchain@1.89.0 | |
| if: steps.child.outputs.reuse != 'true' | |
| with: | |
| components: rustfmt, clippy | |
| - name: Package SpecSync release candidate for Trust | |
| if: steps.child.outputs.reuse != 'true' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cargo build --release --locked | |
| mirror="${RUNNER_TEMP}/specsync-trust-mirror" | |
| binary="specsync-linux-x86_64" | |
| mkdir -p "$mirror" | |
| cp target/release/specsync "$mirror/$binary" | |
| tar -czf "$mirror/$binary.tar.gz" -C "$mirror" "$binary" | |
| ( | |
| cd "$mirror" | |
| sha256sum "$binary.tar.gz" > "$binary.tar.gz.sha256" | |
| ) | |
| # Trust revalidates this checksum-protected runner-local mirror before | |
| # exercising the pull-request binary as the immutable contract gate. | |
| - name: CorvidLabs Trust gate | |
| if: steps.child.outputs.reuse != 'true' | |
| id: trust | |
| uses: CorvidLabs/trust@a239f78658e5ad0f12fa230f494890e40c6e4d7b # v1.1.1 | |
| with: | |
| specsync-version: "6.0.0" | |
| specsync-download-base-url: file://${{ runner.temp }}/specsync-trust-mirror |