Skip to content

E2E Gate workflow_run 30733542874 #24234

E2E Gate workflow_run 30733542874

E2E Gate workflow_run 30733542874 #24234

Workflow file for this run

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
name: E2E / PR Gate Controller
run-name: >-
${{ github.event_name == 'pull_request_target' &&
format('E2E Gate PR #{0} head {1} base {2} gate {3}',
github.event.pull_request.number, github.event.pull_request.head.sha,
github.event.pull_request.base.sha,
github.event.action != 'closed') ||
format('E2E Gate {0} {1}', github.event_name, github.run_id) }}
on:
workflow_run:
workflows: ["CI / Pull Request"]
types: [completed]
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review, edited, closed]
workflow_dispatch:
inputs:
operation:
description: E2E gate action to perform.
required: true
default: approve-e2e
type: choice
options:
- approve-e2e
pr_number:
description: Pull request number for the selected E2E gate action.
required: true
type: string
expected_head_sha:
description: Current 40-character PR head SHA reviewed by the maintainer.
required: true
type: string
expected_base_sha:
description: Current 40-character PR base SHA reviewed by the maintainer.
required: true
type: string
review_reason:
description: Why this PR may run credentialed E2E.
required: true
type: string
permissions: {}
jobs:
initialize:
if: ${{ github.run_attempt == 1 && github.event_name == 'pull_request_target' && github.repository == 'NVIDIA/NemoClaw' && github.event.action != 'closed' && (github.event.action != 'edited' || github.event.changes.base != null) }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
checks: write
contents: read
pull-requests: read
concurrency:
group: pr-e2e-gate-${{ github.repository }}-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-${{ github.event.pull_request.base.sha }}
queue: max
cancel-in-progress: false
steps:
- name: Checkout controller
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.workflow_sha }}
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install controller dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Reserve PR/base SHA gate
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
GITHUB_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode seed
--pr "$PR_NUMBER"
--head "$HEAD_SHA"
--base "$BASE_SHA"
required:
# GitHub treats a skipped required job as passing, so only the running observer can use the required check name.
name: >-
${{ github.event_name == 'pull_request_target' &&
github.repository == 'NVIDIA/NemoClaw' &&
github.event.action != 'closed' &&
'E2E / PR Gate' || 'E2E / PR Gate (not applicable)' }}
if: ${{ github.event_name == 'pull_request_target' && github.repository == 'NVIDIA/NemoClaw' && github.event.action != 'closed' }}
runs-on: ubuntu-latest
timeout-minutes: 360
permissions:
checks: read
contents: read
pull-requests: read
concurrency:
group: pr-e2e-required-${{ github.event.pull_request.number }}
cancel-in-progress: true
steps:
- name: Checkout observer
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.workflow_sha }}
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Wait for trusted PR/base SHA verdict
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
GITHUB_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-required.mts
--pr "$PR_NUMBER"
--head "$HEAD_SHA"
--base "$BASE_SHA"
--timeout-seconds 21480
cancel-superseded:
if: ${{ github.run_attempt == 1 && github.event_name == 'pull_request_target' && github.repository == 'NVIDIA/NemoClaw' && (github.event.action != 'edited' || github.event.changes.base != null) }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
actions: write
checks: write
contents: read
pull-requests: read
steps:
- name: Checkout controller
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.workflow_sha }}
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install controller dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- name: Cancel superseded E2E runs
env:
GITHUB_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
SUPERSEDED_HEAD_SHA: ${{ github.event.before || github.event.pull_request.head.sha }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode cancel
--pr "$PR_NUMBER"
--head "$HEAD_SHA"
--superseded-head "$SUPERSEDED_HEAD_SHA"
coordinate:
if: ${{ github.run_attempt == 1 && github.repository == 'NVIDIA/NemoClaw' && ((github.event_name == 'workflow_run' && github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.path == '.github/workflows/pr.yaml' && endsWith(github.event.workflow_run.display_title, ' gate true')) || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs.operation == 'approve-e2e')) }}
runs-on: ubuntu-latest
timeout-minutes: 330
permissions:
actions: write
checks: write
contents: read
pull-requests: read
concurrency:
group: pr-e2e-gate-${{ github.repository }}-${{ github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].number || inputs.pr_number }}-${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || inputs.expected_head_sha }}-${{ github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].base.sha || inputs.expected_base_sha }}
queue: max
# Let the previous coordinator observe E2E cancellation and close its check.
cancel-in-progress: false
steps:
- name: Checkout controller
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.workflow_sha }}
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install controller dependencies
run: npm ci --ignore-scripts --no-audit --no-fund
- id: workspace
name: Create private workspace
shell: bash
run: |
set -euo pipefail
work_dir="$(mktemp -d "${RUNNER_TEMP}/nemoclaw-pr-e2e-gate.XXXXXX")"
chmod 700 "$work_dir"
printf 'work_dir=%s\n' "$work_dir" >> "$GITHUB_OUTPUT"
- id: start
name: Start evaluation
env:
CI_CONCLUSION: ${{ github.event.workflow_run.conclusion }}
CI_DISPLAY_TITLE: ${{ github.event.workflow_run.display_title }}
CI_RUN_ATTEMPT: ${{ github.event.workflow_run.run_attempt }}
CI_RUN_ID: ${{ github.event.workflow_run.id }}
GATE_RUN_ID: ${{ github.run_id }}
GITHUB_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
HEAD_REPOSITORY: ${{ github.event.workflow_run.head_repository.full_name }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
MAINTAINER: ${{ github.triggering_actor }}
MANUAL_BASE_SHA: ${{ inputs.expected_base_sha }}
MANUAL_HEAD_SHA: ${{ inputs.expected_head_sha }}
MANUAL_PR_NUMBER: ${{ inputs.pr_number }}
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
REVIEW_REASON: ${{ inputs.review_reason }}
WORKFLOW_SHA: ${{ github.workflow_sha }}
WORKFLOW_RUN_ATTEMPT: ${{ github.run_attempt }}
WORK_DIR: ${{ steps.workspace.outputs.work_dir }}
run: |
set -euo pipefail
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts \
--mode approve-e2e \
--pr "$MANUAL_PR_NUMBER" \
--head "$MANUAL_HEAD_SHA" \
--base "$MANUAL_BASE_SHA" \
--workflow-sha "$WORKFLOW_SHA" \
--maintainer "$MAINTAINER" \
--reason "$REVIEW_REASON" \
--gate-run-id "$GATE_RUN_ID" \
--workflow-run-attempt "$WORKFLOW_RUN_ATTEMPT" \
--work-dir "$WORK_DIR"
else
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts \
--mode start \
--head "$HEAD_SHA" \
--head-repo "$HEAD_REPOSITORY" \
--head-branch "$HEAD_BRANCH" \
--workflow-sha "$WORKFLOW_SHA" \
--ci-conclusion "$CI_CONCLUSION" \
--ci-display-title "$CI_DISPLAY_TITLE" \
--ci-run-attempt "$CI_RUN_ATTEMPT" \
--ci-run-id "$CI_RUN_ID" \
--gate-run-id "$GATE_RUN_ID" \
--pr "$PR_NUMBER" \
--work-dir "$WORK_DIR"
fi
- name: Upload risk plan
if: ${{ always() && steps.workspace.outputs.work_dir != '' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-e2e-risk-plan-${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || inputs.expected_head_sha }}
path: ${{ steps.workspace.outputs.work_dir }}/risk-plan.json
if-no-files-found: ignore
retention-days: 14
- id: wait
name: Wait for E2E run
if: ${{ steps.start.outputs.dispatched == 'true' }}
continue-on-error: true
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode wait
--run-id "${{ steps.start.outputs.run_id }}"
- id: evidence
name: Download evidence
if: ${{ always() && steps.start.outputs.dispatched == 'true' }}
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode download
--work-dir "${{ steps.workspace.outputs.work_dir }}"
--run-id "${{ steps.start.outputs.run_id }}"
- id: finish
name: Verify evidence
if: ${{ always() && steps.start.outputs.dispatched == 'true' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode finish
--work-dir "${{ steps.workspace.outputs.work_dir }}"
--state-hash "${{ steps.start.outputs.state_hash }}"
--check-id "${{ steps.start.outputs.check_id }}"
--run-id "${{ steps.start.outputs.run_id }}"
--evidence-outcome "${{ steps.evidence.outcome }}"
- id: retry
name: Retry after hosted runner loss
if: ${{ always() && steps.finish.outputs.runner_loss_retry_authorized == 'true' && github.run_attempt == 1 }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode retry-runner-loss
--work-dir "${{ steps.workspace.outputs.work_dir }}"
--state-hash "${{ steps.start.outputs.state_hash }}"
--check-id "${{ steps.start.outputs.check_id }}"
--run-id "${{ steps.start.outputs.run_id }}"
--workflow-run-attempt "${{ github.run_attempt }}"
- id: retry_wait
name: Wait for retry E2E run
if: ${{ steps.retry.outputs.dispatched == 'true' }}
continue-on-error: true
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode wait
--run-id "${{ steps.retry.outputs.run_id }}"
- id: retry_evidence
name: Download retry evidence
if: ${{ always() && steps.retry.outputs.dispatched == 'true' }}
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode download
--slot runner-loss-retry
--work-dir "${{ steps.workspace.outputs.work_dir }}"
--run-id "${{ steps.retry.outputs.run_id }}"
- id: retry_finish
name: Verify retry evidence
if: ${{ always() && steps.retry.outputs.dispatched == 'true' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode finish
--slot runner-loss-retry
--work-dir "${{ steps.workspace.outputs.work_dir }}"
--state-hash "${{ steps.retry.outputs.state_hash }}"
--check-id "${{ steps.retry.outputs.check_id }}"
--run-id "${{ steps.retry.outputs.run_id }}"
--evidence-outcome "${{ steps.retry_evidence.outcome }}"
- name: Close incomplete retry check
if: ${{ always() && steps.retry.outputs.check_id != '' && steps.retry.outputs.finalized != 'true' && steps.retry_finish.outputs.finalized != 'true' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode abandon
--check-id "${{ steps.retry.outputs.check_id }}"
--run-id "${{ steps.retry.outputs.run_id }}"
- name: Terminalize interrupted retry setup
if: ${{ always() && steps.finish.outputs.runner_loss_retry_authorized == 'true' && steps.retry.outcome != 'success' && steps.retry.outputs.check_id == '' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode abandon-runner-loss-retry
--check-id "${{ steps.start.outputs.check_id }}"
--run-id "${{ steps.start.outputs.run_id }}"
--workflow-run-attempt "${{ github.run_attempt }}"
- name: Close incomplete check
if: ${{ always() && steps.start.outputs.check_id != '' && steps.start.outputs.finalized != 'true' && steps.finish.outputs.finalized != 'true' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
node --experimental-strip-types tools/e2e/pr-e2e-gate.mts
--mode abandon
--check-id "${{ steps.start.outputs.check_id }}"
--run-id "${{ steps.start.outputs.run_id }}"
- name: Remove private workspace
if: ${{ always() && steps.workspace.outputs.work_dir != '' }}
run: rm -rf -- "${{ steps.workspace.outputs.work_dir }}"