fix(ipam): stop random allocation of excludeIps after IPPool reconcile #301
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: Dispatch x86 E2E from PR comments | |
| on: | |
| issue_comment: | |
| types: [created] | |
| pull_request_target: | |
| types: [opened, reopened, synchronize, labeled, unlabeled, closed] | |
| push: | |
| branches: | |
| - master | |
| - 'release-*' | |
| workflow_dispatch: | |
| inputs: | |
| prNumber: | |
| description: Pull request number with a recorded approval marker | |
| required: true | |
| type: number | |
| headSHA: | |
| description: Exact approved pull request HEAD | |
| required: true | |
| type: string | |
| approvalGeneration: | |
| description: Exact durable approval generation | |
| required: true | |
| type: number | |
| permissions: | |
| contents: read | |
| actions: write | |
| checks: read | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| record-controlled-label: | |
| name: Record trusted x86 E2E controlled labels | |
| if: >- | |
| github.event_name == 'pull_request_target' && | |
| (github.event.action == 'labeled' || github.event.action == 'unlabeled') && | |
| startsWith(github.event.label.name, 'e2e:') | |
| runs-on: ubuntu-24.04 | |
| env: | |
| ACTION: ${{ github.event.action }} | |
| GH_TOKEN: ${{ github.token }} | |
| LABEL_NAME: ${{ github.event.label.name }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| PYTHONPATH: hack | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| SENDER: ${{ github.actor }} | |
| steps: | |
| - name: Check out trusted control logic | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.event.repository.default_branch }} | |
| persist-credentials: false | |
| - name: Validate and record the controlled label transition | |
| run: | | |
| set -euo pipefail | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > label-pull-request.json | |
| baseRef=$(jq -r '.base.ref' label-pull-request.json) | |
| if ! [[ "$baseRef" == master || "$baseRef" =~ ^release-[A-Za-z0-9._-]+$ ]]; then | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/contents/.github/e2e-selection.json?ref=$baseRef" \ | |
| --jq '.content' | base64 --decode > label-catalog.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > label-comments.json | |
| permission=$(gh api \ | |
| "repos/$GITHUB_REPOSITORY/collaborators/$SENDER/permission" \ | |
| --jq '.permission' 2>/dev/null || printf 'none') | |
| known=$(python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| catalog = json.loads(Path("label-catalog.json").read_text()) | |
| known = {"e2e:full"} | {f"e2e:{group}" for group in catalog["groups"]} | |
| print("true" if os.environ["LABEL_NAME"] in known else "false") | |
| PY | |
| ) | |
| authorized=false | |
| if [[ "$permission" == admin || "$permission" == maintain || "$permission" == write ]] && \ | |
| [ "$known" = true ]; then | |
| authorized=true | |
| fi | |
| if [ "$authorized" != true ]; then | |
| encodedLabel=$(jq -rn --arg value "$LABEL_NAME" '$value | @uri') | |
| if [ "$ACTION" = labeled ]; then | |
| gh api --method DELETE \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/labels/$encodedLabel" \ | |
| >/dev/null 2>&1 || true | |
| else | |
| restore=$(python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| catalog = json.loads(Path("label-catalog.json").read_text()) | |
| pages = json.loads(Path("label-comments.json").read_text()) | |
| labels = e2eControl.trustedControlledLabels( | |
| catalog, | |
| pages, | |
| [os.environ["LABEL_NAME"]], | |
| ) | |
| print("true" if os.environ["LABEL_NAME"] in labels else "false") | |
| PY | |
| ) | |
| if [ "$restore" = true ]; then | |
| gh api --method POST "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/labels" \ | |
| -f "labels[]=$LABEL_NAME" >/dev/null | |
| fi | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body="Rejected controlled label \`$LABEL_NAME\`: repository write permission and a catalog-defined label are required." | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > confirmed-label-pull-request.json | |
| present=$(jq -r --arg label "$LABEL_NAME" \ | |
| 'any(.labels[]; .name == $label)' confirmed-label-pull-request.json) | |
| expectedPresent=false | |
| [ "$ACTION" != labeled ] || expectedPresent=true | |
| if [ "$present" != "$expectedPresent" ]; then | |
| echo 'Controlled label state changed before provenance could be recorded.' | |
| exit 0 | |
| fi | |
| marker=$(python3 - "$LABEL_NAME" "$expectedPresent" <<'PY' | |
| import sys | |
| import e2e_control as e2eControl | |
| print(e2eControl.renderControlledLabelMarker(sys.argv[1], sys.argv[2] == "true")) | |
| PY | |
| ) | |
| body=$(printf "Recorded trusted x86 E2E label transition by \`%s\`: \`%s\` is now \`%s\`.\n\n%s" \ | |
| "$SENDER" "$LABEL_NAME" "$expectedPresent" "$marker") | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" -f body="$body" | |
| cancel-stale: | |
| name: Cancel obsolete x86 E2E executors | |
| if: github.event_name == 'pull_request_target' | |
| runs-on: ubuntu-24.04 | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| steps: | |
| - name: Cancel executors for obsolete pull request HEADs | |
| run: | | |
| set -euo pipefail | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > live-pull-request.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&per_page=100" \ | |
| | jq '{workflow_runs: [.[].workflow_runs[]]}' > executor-runs.json | |
| python3 - "$PR_NUMBER" <<'PY' > stale-runs.txt | |
| import json | |
| import sys | |
| from pathlib import Path | |
| pullRequest = json.loads(Path("live-pull-request.json").read_text()) | |
| prefix = f"x86-e2e pr={sys.argv[1]} " | |
| currentHead = f"head={pullRequest['head']['sha']} " | |
| runs = json.loads(Path("executor-runs.json").read_text())["workflow_runs"] | |
| for run in runs: | |
| title = run.get("display_title") or "" | |
| if ( | |
| title.startswith(prefix) | |
| and run.get("actor", {}).get("login") == "github-actions[bot]" | |
| and run.get("status") in {"queued", "in_progress"} | |
| and (pullRequest.get("state") != "open" or currentHead not in title) | |
| ): | |
| print(run["id"]) | |
| PY | |
| while IFS= read -r runId; do | |
| [ -n "$runId" ] || continue | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > live-pull-request.json | |
| gh api "repos/$GITHUB_REPOSITORY/actions/runs/$runId" > candidate-run.json | |
| liveState=$(jq -r '.state' live-pull-request.json) | |
| liveHead=$(jq -r '.head.sha' live-pull-request.json) | |
| runTitle=$(jq -r '.display_title // ""' candidate-run.json) | |
| runStatus=$(jq -r '.status' candidate-run.json) | |
| if [ "$runStatus" != queued ] && [ "$runStatus" != in_progress ]; then | |
| continue | |
| fi | |
| if [ "$liveState" = open ] && [[ "$runTitle" == *" head=$liveHead "* ]]; then | |
| continue | |
| fi | |
| if ! gh api --method POST "repos/$GITHUB_REPOSITORY/actions/runs/$runId/cancel"; then | |
| echo "Executor run $runId finished before cancellation." >&2 | |
| fi | |
| done < stale-runs.txt | |
| automatic: | |
| name: Start trusted automatic x86 E2E coverage | |
| needs: | |
| - record-controlled-label | |
| - cancel-stale | |
| if: >- | |
| always() && | |
| github.event_name == 'pull_request_target' && | |
| ( | |
| github.event.action == 'opened' || | |
| github.event.action == 'reopened' || | |
| github.event.action == 'synchronize' || | |
| ( | |
| (github.event.action == 'labeled' || github.event.action == 'unlabeled') && | |
| startsWith(github.event.label.name, 'e2e:') | |
| ) | |
| ) | |
| concurrency: | |
| group: x86-e2e-automatic-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }} | |
| cancel-in-progress: true | |
| permissions: | |
| actions: write | |
| contents: write | |
| issues: read | |
| pull-requests: read | |
| runs-on: ubuntu-24.04 | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| PYTHONPATH: hack | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| steps: | |
| - name: Check out trusted automatic dispatcher logic | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.event.repository.default_branch }} | |
| persist-credentials: false | |
| - name: Dispatch automatic smoke or fail-closed full coverage | |
| env: | |
| DISPATCH_GENERATION: ${{ github.run_id }} | |
| run: | | |
| set -euo pipefail | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > automatic-pull-request.json | |
| if [ "$(jq -r '.state' automatic-pull-request.json)" != open ]; then | |
| exit 0 | |
| fi | |
| headSHA=$(jq -r '.head.sha' automatic-pull-request.json) | |
| baseSHA=$(jq -r '.base.sha' automatic-pull-request.json) | |
| baseRef=$(jq -r '.base.ref' automatic-pull-request.json) | |
| if ! [[ "$baseRef" == master || "$baseRef" =~ ^release-[A-Za-z0-9._-]+$ ]]; then | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/contents/.github/e2e-selection.json?ref=$baseRef" \ | |
| --jq '.content' | base64 --decode > automatic-catalog.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > automatic-comments.json | |
| python3 - <<'PY' > automatic-context.json | |
| import json | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| import e2e_selector as e2eSelector | |
| pullRequest = json.loads(Path("automatic-pull-request.json").read_text()) | |
| catalog = json.loads(Path("automatic-catalog.json").read_text()) | |
| e2eSelector.validateCatalog(catalog) | |
| pages = json.loads(Path("automatic-comments.json").read_text()) | |
| liveLabels = [label["name"] for label in pullRequest.get("labels", [])] | |
| labels = e2eControl.trustedControlledLabels(catalog, pages, liveLabels) | |
| print(json.dumps({ | |
| "catalogRevision": e2eSelector.catalogRevision(catalog), | |
| "controlledLabels": labels, | |
| })) | |
| PY | |
| catalogRevision=$(jq -r '.catalogRevision' automatic-context.json) | |
| controlledLabels=$(jq -c '.controlledLabels' automatic-context.json) | |
| controlledLabelNames=$(jq -r \ | |
| '.controlledLabels | if length == 0 then "-" else join(",") end' \ | |
| automatic-context.json) | |
| approvalGeneration=1 | |
| requestKey="automatic-$PR_NUMBER-$headSHA" | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&per_page=100" \ | |
| | jq '{workflow_runs: [.[].workflow_runs[]]}' > automatic-executor-runs.json | |
| python3 - "$PR_NUMBER" "$headSHA" <<'PY' > stale-automatic-runs.txt | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| runs = json.loads(Path("automatic-executor-runs.json").read_text())["workflow_runs"] | |
| for runId in e2eControl.inProgressAutomaticExecutorRunIds( | |
| runs, int(sys.argv[1]), sys.argv[2] | |
| ): | |
| print(runId) | |
| PY | |
| while IFS= read -r runId; do | |
| [ -n "$runId" ] || continue | |
| if ! gh api --method POST "repos/$GITHUB_REPOSITORY/actions/runs/$runId/cancel"; then | |
| echo "Automatic executor run $runId finished before cancellation." >&2 | |
| fi | |
| done < stale-automatic-runs.txt | |
| executorRef=$(python3 - "$PR_NUMBER" "$approvalGeneration" "$DISPATCH_GENERATION" <<'PY' | |
| import sys | |
| import e2e_control as e2eControl | |
| print(e2eControl.executorHeadBranch({ | |
| "prNumber": int(sys.argv[1]), | |
| "approvalGeneration": int(sys.argv[2]), | |
| "dispatchGeneration": int(sys.argv[3]), | |
| })) | |
| PY | |
| ) | |
| refPath="refs/heads/$executorRef" | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/$executorRef" \ | |
| > automatic-executor-ref.json || true | |
| refAction=$(python3 - "$baseSHA" <<'PY' | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| print(e2eControl.isolatedExecutorRefAction( | |
| Path("automatic-executor-ref.json").read_text(), | |
| sys.argv[1], | |
| )) | |
| PY | |
| ) | |
| if [ "$refAction" = reject ]; then | |
| echo 'The isolated automatic executor ref points at an unexpected revision.' >&2 | |
| exit 1 | |
| fi | |
| createdRef=false | |
| if [ "$refAction" = create ]; then | |
| gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \ | |
| -f ref="$refPath" -f sha="$baseSHA" | |
| createdRef=true | |
| fi | |
| if ! gh api --method POST \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/dispatches" \ | |
| -f ref="$executorRef" \ | |
| -f "inputs[prNumber]=$PR_NUMBER" \ | |
| -f "inputs[headSHA]=$headSHA" \ | |
| -f "inputs[baseSHA]=$baseSHA" \ | |
| -f "inputs[approvalGeneration]=$approvalGeneration" \ | |
| -f 'inputs[automatic]=true' \ | |
| -f "inputs[dispatchGeneration]=$DISPATCH_GENERATION" \ | |
| -f 'inputs[requestedGroups]=[]' \ | |
| -f 'inputs[requestedGroupNames]=-' \ | |
| -f "inputs[controlledLabels]=$controlledLabels" \ | |
| -f "inputs[controlledLabelNames]=$controlledLabelNames" \ | |
| -f 'inputs[full]=false' \ | |
| -f "inputs[requestKey]=$requestKey" \ | |
| -f "inputs[catalogRevision]=$catalogRevision"; then | |
| [ "$createdRef" = false ] || gh api --method DELETE \ | |
| "repos/$GITHUB_REPOSITORY/git/refs/heads/$executorRef" | |
| exit 1 | |
| fi | |
| expectedTitle="x86-e2e pr=$PR_NUMBER head=$headSHA approval=$approvalGeneration generation=$DISPATCH_GENERATION mode=automatic groups=- labels=$controlledLabelNames full=0" | |
| runVisible=false | |
| for _ in $(seq 1 24); do | |
| runVisible=$(gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&branch=$executorRef&per_page=100" \ | |
| | jq -r --arg branch "$executorRef" --arg sha "$baseSHA" --arg title "$expectedTitle" \ | |
| 'any(.[].workflow_runs[]; .path == ".github/workflows/build-x86-image.yaml" and | |
| .actor.login == "github-actions[bot]" and .head_branch == $branch and | |
| .head_sha == $sha and .display_title == $title)') | |
| [ "$runVisible" = true ] && break | |
| sleep 5 | |
| done | |
| if [ "$runVisible" != true ]; then | |
| echo 'The isolated automatic executor run was not visible; its temporary ref was retained.' >&2 | |
| exit 1 | |
| fi | |
| gh api --method DELETE "repos/$GITHUB_REPOSITORY/git/refs/heads/$executorRef" | |
| invalidate-base: | |
| name: Invalidate x86 E2E gates after a base update | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-24.04 | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PYTHONPATH: hack | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| steps: | |
| - name: Check out the updated trusted base | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.sha }} | |
| persist-credentials: false | |
| - name: Block fixed gates bound to the previous base revision | |
| run: | | |
| set -euo pipefail | |
| catalogRevision=$(python3 - <<'PY' | |
| import json | |
| from pathlib import Path | |
| import e2e_selector as e2eSelector | |
| catalog = json.loads(Path(".github/e2e-selection.json").read_text()) | |
| e2eSelector.validateCatalog(catalog) | |
| print(e2eSelector.catalogRevision(catalog)) | |
| PY | |
| ) | |
| gh api --paginate \ | |
| "repos/$GITHUB_REPOSITORY/pulls?state=open&base=$GITHUB_REF_NAME&per_page=100" \ | |
| --jq '.[] | [.number, .head.sha] | @tsv' > open-pulls.tsv | |
| while IFS=$'\t' read -r prNumber headSHA; do | |
| [ -n "$prNumber" ] || continue | |
| hasGate=$(gh api \ | |
| -H 'Accept: application/vnd.github+json' \ | |
| "repos/$GITHUB_REPOSITORY/commits/$headSHA/check-runs?check_name=x86-e2e%20%2F%20required-gate&per_page=100" \ | |
| | jq -r 'any(.check_runs[]; .name == "x86-e2e / required-gate")') | |
| [ "$hasGate" = true ] || continue | |
| gh api --method POST \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/x86-e2e-gate.yaml/dispatches" \ | |
| -f ref="$GITHUB_REF_NAME" \ | |
| -f "inputs[prNumber]=$prNumber" \ | |
| -f "inputs[headSHA]=$headSHA" \ | |
| -f "inputs[baseSHA]=$GITHUB_SHA" \ | |
| -f 'inputs[approvalGeneration]=1' \ | |
| -f "inputs[catalogRevision]=$catalogRevision" \ | |
| -f 'inputs[requestedGroups]=[]' \ | |
| -f 'inputs[full]=false' \ | |
| -f 'inputs[recordIntent]=false' \ | |
| -f 'inputs[baseRefresh]=true' | |
| done < open-pulls.tsv | |
| dispatch: | |
| name: Validate and record x86 E2E commands | |
| if: >- | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| (startsWith(github.event.comment.body, '/test e2e') || | |
| startsWith(github.event.comment.body, '/retest e2e-failed')) | |
| permissions: | |
| actions: write | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| outputs: | |
| accepted: ${{ steps.decision.outputs.accepted }} | |
| action: ${{ steps.decision.outputs.action }} | |
| runs-on: ubuntu-24.04 | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PYTHONPATH: hack | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| steps: | |
| - name: Check out the trusted default branch | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.event.repository.default_branch }} | |
| persist-credentials: false | |
| - name: Validate command, permission, and current HEAD | |
| id: decision | |
| env: | |
| COMMENT_ID: ${{ github.event.comment.id }} | |
| COMMENTER: ${{ github.event.comment.user.login }} | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| run: | | |
| set -euo pipefail | |
| permission=$(gh api \ | |
| "repos/$GITHUB_REPOSITORY/collaborators/$COMMENTER/permission" \ | |
| --jq '.permission' 2>/dev/null || printf 'none') | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > pull-request.json | |
| if ! gh api "repos/$GITHUB_REPOSITORY/issues/comments/$COMMENT_ID" > live-comment.json; then | |
| printf 'null\n' > live-comment.json | |
| fi | |
| baseRef=$(jq -r '.base.ref' pull-request.json) | |
| if ! [[ "$baseRef" == master || "$baseRef" =~ ^release-[A-Za-z0-9._-]+$ ]]; then | |
| echo 'Pull request base branch is outside the supported trusted set.' >&2 | |
| exit 1 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/contents/.github/e2e-selection.json?ref=$baseRef" \ | |
| --jq '.content' | base64 --decode > trusted-catalog.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > controlled-label-comments.json | |
| python3 - <<'PY' > controlled-labels.json | |
| import json | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| pullRequest = json.loads(Path("pull-request.json").read_text()) | |
| catalog = json.loads(Path("trusted-catalog.json").read_text()) | |
| pages = json.loads(Path("controlled-label-comments.json").read_text()) | |
| liveLabels = [label["name"] for label in pullRequest.get("labels", [])] | |
| print(json.dumps(e2eControl.trustedControlledLabels(catalog, pages, liveLabels))) | |
| PY | |
| confirmedHead=$(gh api \ | |
| "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \ | |
| --jq '.head.sha') | |
| python3 hack/e2e_control.py dispatch \ | |
| --event-file "$GITHUB_EVENT_PATH" \ | |
| --catalog trusted-catalog.json \ | |
| --permission "$permission" \ | |
| --pull-request-file pull-request.json \ | |
| --confirmed-head-sha "$confirmedHead" \ | |
| --live-comment-file live-comment.json \ | |
| --controlled-labels-file controlled-labels.json \ | |
| --decision-file dispatch-decision.json | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| decision = json.loads(Path("dispatch-decision.json").read_text()) | |
| with Path(os.environ["GITHUB_OUTPUT"]).open("a") as stream: | |
| stream.write(f"recognized={'true' if decision is not None else 'false'}\n") | |
| if decision is not None: | |
| stream.write(f"accepted={'true' if decision['accepted'] else 'false'}\n") | |
| stream.write(f"action={decision['action']}\n") | |
| PY | |
| - name: Reply with rejection reason | |
| if: steps.decision.outputs.recognized == 'true' && steps.decision.outputs.accepted != 'true' | |
| env: | |
| PR_NUMBER: ${{ github.event.issue.number }} | |
| run: | | |
| reason=$(jq -r '.reason' dispatch-decision.json) | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body="x86 E2E request rejected: $reason." | |
| - name: Record the approved request | |
| if: steps.decision.outputs.accepted == 'true' | |
| id: request | |
| run: | | |
| set -euo pipefail | |
| prNumber=$(jq -r '.prNumber' dispatch-decision.json) | |
| action=$(jq -r '.action' dispatch-decision.json) | |
| headSHA=$(jq -r '.headSHA' dispatch-decision.json) | |
| baseSHA=$(jq -r '.baseSHA' dispatch-decision.json) | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$prNumber" > confirmed-pull-request.json | |
| confirmedHead=$(jq -r '.head.sha' confirmed-pull-request.json) | |
| confirmedBase=$(jq -r '.base.sha' confirmed-pull-request.json) | |
| if [ "$confirmedHead" != "$headSHA" ] || [ "$confirmedBase" != "$baseSHA" ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments" \ | |
| -f body='x86 E2E request became stale before dispatch; comment again for the current HEAD and target revision.' | |
| exit 1 | |
| fi | |
| if [ "$action" = dispatch ]; then | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments?per_page=100" \ | |
| > admission-comments.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&per_page=100" \ | |
| > admission-run-pages.json | |
| duplicate=$(python3 - <<'PY' | |
| import json | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| decision = json.loads(Path("dispatch-decision.json").read_text()) | |
| pullRequest = json.loads(Path("confirmed-pull-request.json").read_text()) | |
| catalog = json.loads(Path("trusted-catalog.json").read_text()) | |
| pages = json.loads(Path("admission-comments.json").read_text()) | |
| prior = e2eControl.approvedRequest(pullRequest, catalog, pages) | |
| intents = e2eControl.approvalIntents(pullRequest, catalog, pages) | |
| request = e2eControl.mergeApprovedRequests( | |
| decision, | |
| ([prior] if prior is not None else []) + intents, | |
| ) | |
| runPages = json.loads(Path("admission-run-pages.json").read_text()) | |
| runs = [run for page in runPages for run in page["workflow_runs"]] | |
| latest = e2eControl.latestExecutorRun( | |
| runs, | |
| request["prNumber"], | |
| request["headSHA"], | |
| request["baseRef"], | |
| request["catalogRevision"], | |
| request["baseSHA"], | |
| ) | |
| if latest is not None: | |
| metadata = e2eControl.parseExecutorRunName(latest["display_title"]) | |
| metadata["baseSHA"] = request["baseSHA"] | |
| metadata["catalogRevision"] = request["catalogRevision"] | |
| status = latest.get("status") | |
| conclusion = latest.get("conclusion") | |
| authorizedAttempt = e2eControl.isAuthorizedRunAttempt( | |
| latest, | |
| pages, | |
| request["headSHA"], | |
| request["baseSHA"], | |
| ) | |
| if ( | |
| authorizedAttempt | |
| and e2eControl.executorRequestKey(metadata) == request["requestKey"] | |
| and (status != "completed" or conclusion in {"success", "failure"}) | |
| ): | |
| print(latest["id"]) | |
| PY | |
| ) | |
| if [ -n "$duplicate" ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments" \ | |
| -f body="The cumulative x86 E2E request is already recorded by trusted executor run $duplicate." | |
| action=duplicate | |
| fi | |
| fi | |
| if [ "$action" = dispatch ]; then | |
| defaultBranch=$(jq -r '.repository.default_branch' "$GITHUB_EVENT_PATH") | |
| approvalGeneration=$(jq -r '.approvalGeneration' dispatch-decision.json) | |
| catalogRevision=$(jq -r '.catalogRevision' dispatch-decision.json) | |
| requestedGroups=$(jq -c '.requestedGroups' dispatch-decision.json) | |
| full=$(jq -r '.full' dispatch-decision.json) | |
| dispatchGate() { | |
| local recordIntent=$1 | |
| gh api --method POST \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/x86-e2e-gate.yaml/dispatches" \ | |
| -f ref="$defaultBranch" \ | |
| -f "inputs[prNumber]=$prNumber" \ | |
| -f "inputs[headSHA]=$headSHA" \ | |
| -f "inputs[baseSHA]=$baseSHA" \ | |
| -f "inputs[approvalGeneration]=$approvalGeneration" \ | |
| -f "inputs[catalogRevision]=$catalogRevision" \ | |
| -f "inputs[requestedGroups]=$requestedGroups" \ | |
| -f "inputs[full]=$full" \ | |
| -f "inputs[recordIntent]=$recordIntent" \ | |
| -f 'inputs[baseRefresh]=false' | |
| } | |
| if ! dispatchGate false; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments" \ | |
| -f body='The trusted x86 E2E gate reservation could not be started; no approval was recorded.' | |
| exit 1 | |
| fi | |
| intentReady=false | |
| for _ in $(seq 1 24); do | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments?per_page=100" \ | |
| > reserved-comments.json | |
| intentReady=$(python3 - "$approvalGeneration" "$requestedGroups" "$full" "$headSHA" "$baseSHA" "$catalogRevision" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| pages = json.loads(Path("reserved-comments.json").read_text()) | |
| expectedGeneration = int(sys.argv[1]) | |
| expectedGroups = json.loads(sys.argv[2]) | |
| expectedFull = sys.argv[3] == "true" | |
| expectedHeadSHA = sys.argv[4] | |
| expectedBaseSHA = sys.argv[5] | |
| expectedCatalogRevision = sys.argv[6] | |
| for page in pages: | |
| for comment in page: | |
| user = comment.get("user", {}) | |
| if user.get("login") != "github-actions[bot]" or user.get("type") != "Bot": | |
| continue | |
| try: | |
| intent = e2eControl.parseApprovalIntent(comment.get("body", "")) | |
| except ValueError: | |
| continue | |
| if intent is not None and ( | |
| intent["approvalGeneration"] == expectedGeneration | |
| and intent["headSHA"] == expectedHeadSHA | |
| and intent["baseSHA"] == expectedBaseSHA | |
| and intent["catalogRevision"] == expectedCatalogRevision | |
| and intent["requestedGroups"] == expectedGroups | |
| and intent["full"] == expectedFull | |
| ): | |
| print("true") | |
| raise SystemExit | |
| print("false") | |
| PY | |
| ) | |
| if [ "$intentReady" = true ]; then | |
| break | |
| fi | |
| sleep 5 | |
| done | |
| if [ "$intentReady" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments" \ | |
| -f body='The trusted x86 E2E reservation did not become durable; no approval was recorded.' | |
| exit 1 | |
| fi | |
| fi | |
| requestKey=$(jq -r '.requestKey' dispatch-decision.json) | |
| if [ "$action" = rerun-failed ]; then | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$prNumber/comments?per_page=100" \ | |
| > rerun-comments.json | |
| requestKey=$(python3 - <<'PY' | |
| import json | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| pullRequest = json.loads(Path("confirmed-pull-request.json").read_text()) | |
| catalog = json.loads(Path("trusted-catalog.json").read_text()) | |
| pages = json.loads(Path("rerun-comments.json").read_text()) | |
| request = e2eControl.approvedRequest(pullRequest, catalog, pages) | |
| print(request["requestKey"] if request is not None else "") | |
| PY | |
| ) | |
| fi | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&per_page=100" \ | |
| | jq '{workflow_runs: [.[].workflow_runs[]]}' > executor-runs.json | |
| { | |
| echo "action=$action" | |
| echo "baseRef=$(jq -r '.baseRef' dispatch-decision.json)" | |
| echo "baseSHA=$(jq -r '.baseSHA' dispatch-decision.json)" | |
| echo "approvalGeneration=$(jq -r '.approvalGeneration' dispatch-decision.json)" | |
| echo "catalogRevision=$(jq -r '.catalogRevision' dispatch-decision.json)" | |
| echo "full=$(jq -r '.full' dispatch-decision.json)" | |
| echo "headSHA=$headSHA" | |
| echo "prNumber=$prNumber" | |
| echo "requestKey=$requestKey" | |
| echo "requestedGroupNames=$(jq -r '.requestedGroups | if length == 0 then "-" else join(",") end' dispatch-decision.json)" | |
| echo "requestedGroups=$(jq -c '.requestedGroups' dispatch-decision.json)" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Rerun the latest failed executor request | |
| if: steps.request.outputs.action == 'rerun-failed' | |
| env: | |
| BASE_REF: ${{ steps.request.outputs.baseRef }} | |
| BASE_SHA: ${{ steps.request.outputs.baseSHA }} | |
| CATALOG_REVISION: ${{ steps.request.outputs.catalogRevision }} | |
| HEAD_SHA: ${{ steps.request.outputs.headSHA }} | |
| PR_NUMBER: ${{ steps.request.outputs.prNumber }} | |
| REQUEST_KEY: ${{ steps.request.outputs.requestKey }} | |
| run: | | |
| runId=$(python3 - "$PR_NUMBER" "$HEAD_SHA" "$BASE_REF" "$CATALOG_REVISION" "$BASE_SHA" "$REQUEST_KEY" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| runs = json.loads(Path("executor-runs.json").read_text())["workflow_runs"] | |
| latestRun = e2eControl.latestExecutorRun( | |
| runs, | |
| int(sys.argv[1]), | |
| sys.argv[2], | |
| sys.argv[3], | |
| sys.argv[4], | |
| sys.argv[5], | |
| ) | |
| if latestRun is not None and latestRun.get("conclusion") == "failure": | |
| metadata = e2eControl.parseExecutorRunName(latestRun["display_title"]) | |
| metadata["baseSHA"] = sys.argv[5] | |
| metadata["catalogRevision"] = sys.argv[4] | |
| if e2eControl.executorRequestKey(metadata) == sys.argv[6]: | |
| print(latestRun["id"]) | |
| PY | |
| ) | |
| if [ -z "$runId" ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='No failed x86 E2E executor run exists for the current HEAD.' | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/actions/runs/$runId" > rerun-state.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > pre-marker-comments.json | |
| currentAttemptAuthorized=$(python3 - "$HEAD_SHA" "$BASE_SHA" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| run = json.loads(Path("rerun-state.json").read_text()) | |
| pages = json.loads(Path("pre-marker-comments.json").read_text()) | |
| print( | |
| "true" | |
| if e2eControl.isAuthorizedRunAttempt(run, pages, sys.argv[1], sys.argv[2]) | |
| else "false" | |
| ) | |
| PY | |
| ) | |
| if [ "$currentAttemptAuthorized" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body="The latest failed attempt was not authorized; use \`/test e2e\` to start a clean trusted executor instead." | |
| exit 0 | |
| fi | |
| nextAttempt=$(( $(jq -r '.run_attempt' rerun-state.json) + 1 )) | |
| python3 - "$runId" "$nextAttempt" "$HEAD_SHA" "$BASE_SHA" <<'PY' > rerun-marker.txt | |
| import sys | |
| import e2e_control as e2eControl | |
| print(e2eControl.renderRerunMarker(*sys.argv[1:])) | |
| PY | |
| marker=$(cat rerun-marker.txt) | |
| body=$(printf "Authorized a failed-job x86 E2E rerun for current HEAD \`%s\`.\n\n%s" "$HEAD_SHA" "$marker") | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" -f body="$body" | |
| markerReady=false | |
| for _ in $(seq 1 24); do | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > rerun-marker-comments.json | |
| markerReady=$(python3 - "$runId" "$nextAttempt" "$HEAD_SHA" "$BASE_SHA" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| pages = json.loads(Path("rerun-marker-comments.json").read_text()) | |
| print("true" if e2eControl.hasAuthorizedRerun(pages, *sys.argv[1:]) else "false") | |
| PY | |
| ) | |
| [ "$markerReady" = true ] && break | |
| sleep 5 | |
| done | |
| if [ "$markerReady" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The failed-job rerun marker was not visible to the trusted gate; no rerun was started.' | |
| exit 1 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > final-rerun-pull-request.json | |
| if [ "$(jq -r '.state' final-rerun-pull-request.json)" != open ] || \ | |
| [ "$(jq -r '.head.sha' final-rerun-pull-request.json)" != "$HEAD_SHA" ] || \ | |
| [ "$(jq -r '.base.sha' final-rerun-pull-request.json)" != "$BASE_SHA" ]; then | |
| gh api --method POST "repos/$GITHUB_REPOSITORY/actions/runs/$runId/cancel" >/dev/null 2>&1 || true | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The pull request changed before the failed-job rerun; no stale rerun was started.' | |
| exit 0 | |
| fi | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > final-rerun-comments.json | |
| currentRequestKey=$(python3 - <<'PY' | |
| import json | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| pullRequest = json.loads(Path("final-rerun-pull-request.json").read_text()) | |
| catalog = json.loads(Path("trusted-catalog.json").read_text()) | |
| pages = json.loads(Path("final-rerun-comments.json").read_text()) | |
| request = e2eControl.approvedRequest(pullRequest, catalog, pages) | |
| print(request["requestKey"] if request is not None else "") | |
| PY | |
| ) | |
| if [ "$currentRequestKey" != "$REQUEST_KEY" ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The cumulative x86 E2E request changed before the failed-job rerun; no superseded rerun was started.' | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/actions/runs/$runId" > final-rerun-state.json | |
| currentAttempt=$(jq -r '.run_attempt' final-rerun-state.json) | |
| currentStatus=$(jq -r '.status' final-rerun-state.json) | |
| currentAttemptAuthorized=$(python3 - "$HEAD_SHA" "$BASE_SHA" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| run = json.loads(Path("final-rerun-state.json").read_text()) | |
| pages = json.loads(Path("final-rerun-comments.json").read_text()) | |
| print( | |
| "true" | |
| if e2eControl.isAuthorizedRunAttempt(run, pages, sys.argv[1], sys.argv[2]) | |
| else "false" | |
| ) | |
| PY | |
| ) | |
| if [ "$currentAttemptAuthorized" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body="The latest failed attempt was not authorized; use \`/test e2e\` to start a clean trusted executor instead." | |
| exit 0 | |
| fi | |
| if [ "$currentAttempt" != "$((nextAttempt - 1))" ] || [ "$currentStatus" != completed ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='Another rerun consumed the authorized attempt; no additional rerun was started.' | |
| exit 0 | |
| fi | |
| if ! gh api --method POST "repos/$GITHUB_REPOSITORY/actions/runs/$runId/rerun-failed-jobs"; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body="The failed-job rerun authorization is durable, but the rerun could not be started; retry \`/retest e2e-failed\`." | |
| exit 1 | |
| fi | |
| reduce: | |
| name: Reduce recorded x86 E2E approvals | |
| needs: dispatch | |
| if: >- | |
| always() && | |
| github.event_name == 'workflow_dispatch' && | |
| github.actor == 'github-actions[bot]' | |
| permissions: | |
| contents: write | |
| actions: write | |
| checks: read | |
| pull-requests: write | |
| issues: write | |
| concurrency: | |
| group: x86-e2e-reduce-${{ inputs.prNumber }}-${{ inputs.approvalGeneration }} | |
| cancel-in-progress: false | |
| runs-on: ubuntu-24.04 | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ inputs.prNumber }} | |
| PYTHONPATH: hack | |
| PYTHONDONTWRITEBYTECODE: "1" | |
| steps: | |
| - name: Check out the trusted default branch | |
| uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ github.event.repository.default_branch }} | |
| persist-credentials: false | |
| - name: Build the current cumulative request | |
| id: request | |
| env: | |
| BRIDGE_APPROVAL_GENERATION: ${{ inputs.approvalGeneration }} | |
| BRIDGE_HEAD_SHA: ${{ inputs.headSHA }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| set -euo pipefail | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > pull-request.json | |
| baseRef=$(jq -r '.base.ref' pull-request.json) | |
| if ! [[ "$baseRef" == master || "$baseRef" =~ ^release-[A-Za-z0-9._-]+$ ]]; then | |
| echo 'hasApprovals=false' >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [ "$(jq -r '.state' pull-request.json)" != open ]; then | |
| echo 'hasApprovals=false' >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/contents/.github/e2e-selection.json?ref=$baseRef" \ | |
| --jq '.content' | base64 --decode > trusted-catalog.json | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments?per_page=100" \ | |
| > pull-request-comments.json | |
| python3 - <<'PY' | |
| import json | |
| import os | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| import e2e_selector as e2eSelector | |
| pullRequest = json.loads(Path("pull-request.json").read_text()) | |
| catalog = json.loads(Path("trusted-catalog.json").read_text()) | |
| e2eSelector.validateCatalog(catalog) | |
| pages = json.loads(Path("pull-request-comments.json").read_text()) | |
| request = e2eControl.approvedRequest(pullRequest, catalog, pages) | |
| if os.environ["EVENT_NAME"] == "workflow_dispatch" and request is not None: | |
| if ( | |
| request["headSHA"] != os.environ["BRIDGE_HEAD_SHA"] | |
| or request["approvalGeneration"] | |
| != int(os.environ["BRIDGE_APPROVAL_GENERATION"]) | |
| ): | |
| request = None | |
| with Path(os.environ["GITHUB_OUTPUT"]).open("a") as stream: | |
| stream.write(f"hasApprovals={'true' if request is not None else 'false'}\n") | |
| if request is None: | |
| raise SystemExit | |
| Path("cumulative-request.json").write_text(json.dumps(request, indent=2) + "\n") | |
| stream.write(f"baseRef={request['baseRef']}\n") | |
| stream.write(f"baseSHA={request['baseSHA']}\n") | |
| stream.write(f"approvalGeneration={request['approvalGeneration']}\n") | |
| stream.write(f"catalogRevision={request['catalogRevision']}\n") | |
| stream.write(f"full={'true' if request['full'] else 'false'}\n") | |
| stream.write(f"headSHA={request['headSHA']}\n") | |
| stream.write(f"requestKey={request['requestKey']}\n") | |
| names = ",".join(request["requestedGroups"]) or "-" | |
| stream.write(f"requestedGroupNames={names}\n") | |
| stream.write( | |
| "requestedGroups=" | |
| + json.dumps(request["requestedGroups"], separators=(",", ":")) | |
| + "\n" | |
| ) | |
| PY | |
| - name: Dispatch the cumulative executor request | |
| if: steps.request.outputs.hasApprovals == 'true' | |
| env: | |
| BASE_REF: ${{ steps.request.outputs.baseRef }} | |
| BASE_SHA: ${{ steps.request.outputs.baseSHA }} | |
| APPROVAL_GENERATION: ${{ steps.request.outputs.approvalGeneration }} | |
| CATALOG_REVISION: ${{ steps.request.outputs.catalogRevision }} | |
| DISPATCH_GENERATION: ${{ github.run_id }} | |
| FULL: ${{ steps.request.outputs.full }} | |
| HEAD_SHA: ${{ steps.request.outputs.headSHA }} | |
| REQUEST_KEY: ${{ steps.request.outputs.requestKey }} | |
| REQUESTED_GROUP_NAMES: ${{ steps.request.outputs.requestedGroupNames }} | |
| REQUESTED_GROUPS: ${{ steps.request.outputs.requestedGroups }} | |
| run: | | |
| set -euo pipefail | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > confirmed-pull-request.json | |
| if [ "$(jq -r '.head.sha' confirmed-pull-request.json)" != "$HEAD_SHA" ] || \ | |
| [ "$(jq -r '.base.sha' confirmed-pull-request.json)" != "$BASE_SHA" ]; then | |
| echo 'The cumulative request became stale before dispatch.' | |
| exit 0 | |
| fi | |
| gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&per_page=100" \ | |
| | jq '{workflow_runs: [.[].workflow_runs[]]}' > executor-runs.json | |
| duplicate=$(python3 - "$PR_NUMBER" "$HEAD_SHA" "$BASE_REF" "$REQUEST_KEY" "$CATALOG_REVISION" "$BASE_SHA" "$APPROVAL_GENERATION" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| runs = json.loads(Path("executor-runs.json").read_text())["workflow_runs"] | |
| commentPages = json.loads(Path("pull-request-comments.json").read_text()) | |
| latestRun = e2eControl.latestExecutorRun( | |
| runs, | |
| int(sys.argv[1]), | |
| sys.argv[2], | |
| sys.argv[3], | |
| sys.argv[5], | |
| sys.argv[6], | |
| ) | |
| if latestRun is not None: | |
| metadata = e2eControl.parseExecutorRunName(latestRun["display_title"]) | |
| metadata["baseSHA"] = sys.argv[6] | |
| metadata["catalogRevision"] = sys.argv[5] | |
| metadataRequestKey = e2eControl.executorRequestKey(metadata) | |
| conclusion = latestRun.get("conclusion") | |
| retryableConclusion = conclusion not in {"success", "failure"} | |
| freshApproval = metadata["approvalGeneration"] < int(sys.argv[7]) | |
| authorizedAttempt = e2eControl.isAuthorizedRunAttempt( | |
| latestRun, | |
| commentPages, | |
| sys.argv[2], | |
| sys.argv[6], | |
| ) | |
| if authorizedAttempt and metadataRequestKey == sys.argv[4] and ( | |
| latestRun.get("status") != "completed" | |
| or conclusion in {"success", "failure"} | |
| or (retryableConclusion and not freshApproval) | |
| ): | |
| print(latestRun["html_url"]) | |
| PY | |
| ) | |
| if [ -n "$duplicate" ]; then | |
| echo "The cumulative x86 E2E request is already recorded: $duplicate" | |
| exit 0 | |
| fi | |
| approvalReady=false | |
| for _ in $(seq 1 24); do | |
| gh api \ | |
| -H 'Accept: application/vnd.github+json' \ | |
| "repos/$GITHUB_REPOSITORY/commits/$HEAD_SHA/check-runs?check_name=x86-e2e%20%2F%20required-gate&per_page=100" \ | |
| > approved-gate-checks.json | |
| approvalReady=$(python3 - "$PR_NUMBER" "$HEAD_SHA" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| checks = json.loads(Path("approved-gate-checks.json").read_text()).get("check_runs") or [] | |
| print( | |
| "true" | |
| if any( | |
| e2eControl.isApprovedGateReservation(check, sys.argv[1], sys.argv[2]) | |
| for check in checks | |
| ) | |
| else "false" | |
| ) | |
| PY | |
| ) | |
| if [ "$approvalReady" = true ]; then | |
| break | |
| fi | |
| sleep 5 | |
| done | |
| if [ "$approvalReady" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The trusted gate did not record the latest approval; no x86 E2E executor was started.' | |
| exit 1 | |
| fi | |
| gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" > final-pull-request.json | |
| if [ "$(jq -r '.state' final-pull-request.json)" != open ] || \ | |
| [ "$(jq -r '.head.sha' final-pull-request.json)" != "$HEAD_SHA" ] || \ | |
| [ "$(jq -r '.base.sha' final-pull-request.json)" != "$BASE_SHA" ]; then | |
| echo 'The cumulative request became stale during gate reconciliation.' | |
| exit 0 | |
| fi | |
| gh api \ | |
| -H 'Accept: application/vnd.github+json' \ | |
| "repos/$GITHUB_REPOSITORY/commits/$HEAD_SHA/check-runs?check_name=x86-e2e%20%2F%20required-gate&per_page=100" \ | |
| > approved-gate-checks.json | |
| ready=$(python3 - "$PR_NUMBER" "$HEAD_SHA" <<'PY' | |
| import json | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| checks = json.loads(Path("approved-gate-checks.json").read_text()).get("check_runs") or [] | |
| print( | |
| "true" | |
| if any( | |
| e2eControl.isApprovedGateReservation(check, sys.argv[1], sys.argv[2]) | |
| for check in checks | |
| ) | |
| else "false" | |
| ) | |
| PY | |
| ) | |
| if [ "$ready" != true ]; then | |
| exit 0 | |
| fi | |
| executorRef=$(python3 - "$PR_NUMBER" "$APPROVAL_GENERATION" "$DISPATCH_GENERATION" <<'PY' | |
| import sys | |
| import e2e_control as e2eControl | |
| request = { | |
| "prNumber": int(sys.argv[1]), | |
| "approvalGeneration": int(sys.argv[2]), | |
| "dispatchGeneration": int(sys.argv[3]), | |
| } | |
| print(e2eControl.executorHeadBranch(request)) | |
| PY | |
| ) | |
| refPath="refs/heads/$executorRef" | |
| gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/$executorRef" \ | |
| > approved-executor-ref.json || true | |
| refAction=$(python3 - "$BASE_SHA" <<'PY' | |
| import sys | |
| from pathlib import Path | |
| import e2e_control as e2eControl | |
| print(e2eControl.isolatedExecutorRefAction( | |
| Path("approved-executor-ref.json").read_text(), | |
| sys.argv[1], | |
| )) | |
| PY | |
| ) | |
| if [ "$refAction" = reject ]; then | |
| echo 'The isolated executor ref points at an unexpected revision.' >&2 | |
| exit 1 | |
| fi | |
| createdRef=false | |
| if [ "$refAction" = create ]; then | |
| gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \ | |
| -f ref="$refPath" -f sha="$BASE_SHA" | |
| createdRef=true | |
| fi | |
| if ! gh api --method POST \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/dispatches" \ | |
| -f ref="$executorRef" \ | |
| -f "inputs[prNumber]=$PR_NUMBER" \ | |
| -f "inputs[headSHA]=$HEAD_SHA" \ | |
| -f "inputs[baseSHA]=$BASE_SHA" \ | |
| -f "inputs[approvalGeneration]=$APPROVAL_GENERATION" \ | |
| -f 'inputs[automatic]=false' \ | |
| -f "inputs[dispatchGeneration]=$DISPATCH_GENERATION" \ | |
| -f "inputs[requestedGroups]=$REQUESTED_GROUPS" \ | |
| -f "inputs[requestedGroupNames]=$REQUESTED_GROUP_NAMES" \ | |
| -f 'inputs[controlledLabels]=[]' \ | |
| -f 'inputs[controlledLabelNames]=-' \ | |
| -f "inputs[full]=$FULL" \ | |
| -f "inputs[requestKey]=$REQUEST_KEY" \ | |
| -f "inputs[catalogRevision]=$CATALOG_REVISION"; then | |
| [ "$createdRef" = false ] || gh api --method DELETE \ | |
| "repos/$GITHUB_REPOSITORY/git/refs/heads/$executorRef" | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The trusted x86 E2E executor could not be started; retry the authorized command.' | |
| exit 1 | |
| fi | |
| expectedTitle="x86-e2e pr=$PR_NUMBER head=$HEAD_SHA approval=$APPROVAL_GENERATION generation=$DISPATCH_GENERATION mode=approved groups=$REQUESTED_GROUP_NAMES labels=- full=$([ "$FULL" = true ] && echo 1 || echo 0)" | |
| runVisible=false | |
| for _ in $(seq 1 24); do | |
| runVisible=$(gh api --paginate --slurp \ | |
| "repos/$GITHUB_REPOSITORY/actions/workflows/build-x86-image.yaml/runs?event=workflow_dispatch&branch=$executorRef&per_page=100" \ | |
| | jq -r --arg branch "$executorRef" --arg sha "$BASE_SHA" --arg title "$expectedTitle" \ | |
| 'any(.[].workflow_runs[]; .path == ".github/workflows/build-x86-image.yaml" and | |
| .actor.login == "github-actions[bot]" and .head_branch == $branch and | |
| .head_sha == $sha and .display_title == $title)') | |
| [ "$runVisible" = true ] && break | |
| sleep 5 | |
| done | |
| if [ "$runVisible" != true ]; then | |
| gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ | |
| -f body='The isolated x86 E2E executor run was not visible; its temporary ref was retained for recovery.' | |
| exit 1 | |
| fi | |
| gh api --method DELETE "repos/$GITHUB_REPOSITORY/git/refs/heads/$executorRef" |