test(ci): add label-gated upgrade qualification

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar
2026-10-01 13:54:37 +02:00
parent 49667f11df
commit cd7d6409f7
3 changed files with 72 additions and 7 deletions
+58 -2
View File
@@ -26,6 +26,7 @@ jobs:
run_integration: ${{ steps.labels.outputs.run_core_e2e }}
run_core_e2e: ${{ steps.labels.outputs.run_core_e2e }}
run_gpu_e2e: ${{ steps.labels.outputs.run_gpu_e2e }}
run_integration_upgrades: ${{ steps.labels.outputs.run_integration_upgrades }}
run_kubernetes_ha_e2e: ${{ steps.labels.outputs.run_kubernetes_ha_e2e }}
run_kubernetes_credential_drivers_e2e: ${{ steps.labels.outputs.run_kubernetes_credential_drivers_e2e }}
run_any_e2e: ${{ steps.labels.outputs.run_any_e2e }}
@@ -47,8 +48,14 @@ jobs:
push)
run_core_e2e="$(jq -r 'index("test:e2e") != null' <<< "$LABELS_JSON")"
run_gpu_e2e="$(jq -r 'index("test:e2e-gpu") != null' <<< "$LABELS_JSON")"
<<<<<<< HEAD
run_kubernetes_ha_e2e="$(jq -r 'index("test:e2e-kubernetes") != null' <<< "$LABELS_JSON")"
run_kubernetes_credential_drivers_e2e="$(jq -r 'index("test:e2e-kubernetes") != null' <<< "$LABELS_JSON")"
=======
run_integration_upgrades="$(jq -r 'index("test:upgrade") != null' <<< "$LABELS_JSON")"
run_kubernetes_ha_e2e=false
run_kubernetes_credential_drivers_e2e=false
>>>>>>> bedd141c0 (test(ci): add label-gated upgrade qualification)
;;
merge_group)
# Merge groups have no PR labels. When GPU E2E is required as documented
@@ -56,17 +63,19 @@ jobs:
# and ejects the PR. HA stays off until stable.
run_core_e2e=true
run_gpu_e2e=true
run_integration_upgrades=false
run_kubernetes_ha_e2e=false
run_kubernetes_credential_drivers_e2e=false
;;
*)
run_core_e2e=true
run_gpu_e2e=true
run_integration_upgrades=false
run_kubernetes_ha_e2e=false
run_kubernetes_credential_drivers_e2e=false
;;
esac
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ] || [ "$run_kubernetes_credential_drivers_e2e" = "true" ]; then
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_integration_upgrades" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ] || [ "$run_kubernetes_credential_drivers_e2e" = "true" ]; then
run_any_e2e=true
else
run_any_e2e=false
@@ -75,6 +84,7 @@ jobs:
{
echo "run_core_e2e=$run_core_e2e"
echo "run_gpu_e2e=$run_gpu_e2e"
echo "run_integration_upgrades=$run_integration_upgrades"
echo "run_kubernetes_ha_e2e=$run_kubernetes_ha_e2e"
echo "run_kubernetes_credential_drivers_e2e=$run_kubernetes_credential_drivers_e2e"
echo "run_any_e2e=$run_any_e2e"
@@ -89,6 +99,7 @@ jobs:
timeout-minutes: 5
outputs:
cargo: ${{ steps.version.outputs.cargo }}
deb: ${{ steps.version.outputs.deb }}
rpm_version: ${{ steps.version.outputs.rpm_version }}
rpm_release: ${{ steps.version.outputs.rpm_release }}
steps:
@@ -101,10 +112,12 @@ jobs:
id: version
run: |
cargo="$(python3 tasks/scripts/release.py get-version --cargo)"
deb="$(python3 tasks/scripts/release.py get-version --dev --deb)"
rpm_version="$(python3 tasks/scripts/release.py get-version --dev --rpm-version)"
rpm_release="$(python3 tasks/scripts/release.py get-version --dev --rpm-release)"
{
echo "cargo=$cargo"
echo "deb=$deb"
echo "rpm_version=$rpm_version"
echo "rpm_release=$rpm_release"
} >> "$GITHUB_OUTPUT"
@@ -191,7 +204,7 @@ jobs:
build-vm-driver:
needs: [pr_metadata, version, build-binaries]
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.run_core_e2e == 'true' || needs.pr_metadata.outputs.run_integration_upgrades == 'true'
permissions:
contents: read
uses: ./.github/workflows/build-vm-driver.yml
@@ -233,6 +246,49 @@ jobs:
with:
rpm-artifact-name: rpm-linux-x86_64
build-deb-upgrade:
name: Build Debian package for upgrade qualification
needs: [pr_metadata, version, build-binaries, build-vm-driver]
if: needs.pr_metadata.outputs.run_integration_upgrades == 'true'
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/deb-package.yml
with:
deb-version: ${{ needs.version.outputs.deb }}
checkout-ref: ${{ github.sha }}
prepare-integration-upgrades:
name: Prepare upgrade qualification inputs
needs: [pr_metadata, build-binaries, build-images, build-deb-upgrade]
if: needs.pr_metadata.outputs.run_integration_upgrades == 'true'
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/prepare-integration-inputs.yml
with:
deb-artifact-name: deb-linux-amd64
include-deb-upgrade-source: true
integration-upgrades:
name: Integration upgrades
needs: prepare-integration-upgrades
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
with:
category: upgrades
source-sha: ${{ needs.prepare-integration-upgrades.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration-upgrades.outputs.integration_inputs_artifact_id }}
test-matrix: >-
[
{"environment":"ubuntu-docker-rootful","installer":"deb-upgrade-source","testsuite":"deb-upgrade"}
]
# Run driver-independent conformance tests.
conformance-integration:
needs: prepare-integration
+6 -1
View File
@@ -19,7 +19,7 @@ permissions: {}
jobs:
hint:
name: Post next-step hint for E2E label
if: github.event.label.name == 'test:e2e' || github.event.label.name == 'test:e2e-gpu' || github.event.label.name == 'test:e2e-kubernetes'
if: github.event.label.name == 'test:e2e' || github.event.label.name == 'test:e2e-gpu' || github.event.label.name == 'test:e2e-kubernetes' || github.event.label.name == 'test:upgrade'
runs-on: ubuntu-latest
permissions:
pull-requests: write
@@ -50,6 +50,11 @@ jobs:
build_summary="supervisor image"
status_summary="The matching required CI gate status on this PR will flip green automatically once the run finishes."
;;
test:upgrade)
suite_summary="the Debian upgrade qualification"
build_summary="the Debian package, VM driver, sandbox image, and supervisor image"
status_summary="This is an optional proof-of-life suite; failures are visible in the workflow run but do not publish a required CI gate status."
;;
test:e2e-kubernetes)
suite_summary="Kubernetes HA and credential-driver E2E"
build_summary="gateway, sandbox, and supervisor images"
+8 -4
View File
@@ -28,11 +28,15 @@ runs without optional E2E labels. Core integration qualification installs the
CLI and gateway RPMs on Fedora with rootful and rootless Podman and runs conformance using
the matching runtime images. Release Dev and Release Tag run the same RPM lane.
Three opt-in labels enable the long-running E2E suites:
Four opt-in labels enable the long-running E2E suites:
- `test:e2e` runs the Docker, rootless Podman, Kubernetes, and VM E2E suites
with both managed and standalone compute drivers in `Branch E2E Checks`
- `test:e2e-gpu` runs GPU E2E in `Branch E2E Checks`
- `test:upgrade` runs tmachine Debian upgrade qualification in
`Branch E2E Checks`: the latest retained prerelease is installed first, then
the PR's Debian package is installed and both existing and new sandboxes are
verified
- `test:e2e-kubernetes` runs Kubernetes E2E with the HA Helm overlay
(`replicaCount: 2` and bundled PostgreSQL) and the credential-driver suite
(Kubernetes Secrets plus Vault) in `Branch E2E Checks`
@@ -342,7 +346,7 @@ Flow:
1. Open the PR. copy-pr-bot mirrors it to `pull-request/<N>` automatically.
2. The mirror push runs `Branch Checks` automatically. `Required CI Gates` keeps the PR blocked until the mirror exists, matches the PR head SHA, and the required push-based workflow succeeds. The first `Branch E2E Checks` run only resolves metadata and skips expensive jobs unless an E2E label is already set.
3. A maintainer applies `test:e2e`, `test:e2e-gpu`, and/or `test:e2e-kubernetes`. `E2E Label Help` posts a comment with a link to the existing gated workflow run.
3. A maintainer applies `test:e2e`, `test:e2e-gpu`, `test:upgrade`, and/or `test:e2e-kubernetes`. `E2E Label Help` posts a comment with a link to the existing gated workflow run.
4. The maintainer opens that link and clicks **Re-run all jobs**. This time `pr_metadata` sees the label and the build/E2E jobs run.
5. When the run finishes, the matching `OpenShell / ...` gate status flips to green automatically.
6. New commits push to the mirror automatically and re-trigger `Branch Checks` plus any labeled E2E jobs in `Branch E2E Checks`.
@@ -381,7 +385,7 @@ its own stable result status.
Merge-group runs use the `merge_group` event. The event is distinct from `pull_request` and `push`, and GitHub will not report required checks for queued PRs unless the workflows include it. In this repository:
- `Branch Checks` runs the standard non-E2E gates on the merge-group SHA.
- `Branch E2E Checks` runs core E2E and GPU E2E for merge groups. Kubernetes HA E2E remains optional and label-driven on PRs.
- `Branch E2E Checks` runs core E2E and GPU E2E for merge groups. Debian upgrade qualification and Kubernetes HA E2E remain optional and label-driven on PRs.
- `Helm Lint` runs for merge groups without the PR diff optimization, because the merge-group branch is the final integration state.
- `Trivy Changes` compares the merge-group configuration with its base and rejects new High or Critical findings.
- `Required CI Gates` posts the same `OpenShell / ...` statuses to the merge-group SHA and does not require a `pull-request/<N>` mirror for merge-group events.
@@ -407,7 +411,7 @@ The bot's full administrator documentation is internal to NVIDIA. The only comma
| File | Role |
|---|---|
| `.github/workflows/branch-checks.yml` | Required non-E2E checks. Triggers on `push: pull-request/[0-9]+` for PR mirrors and `merge_group` for queued merges. |
| `.github/workflows/branch-e2e.yml` | Standard, GPU, Kubernetes HA, and Kubernetes credential-driver E2E. PR mirror pushes use `test:e2e`, `test:e2e-gpu`, and `test:e2e-kubernetes` labels; merge groups run core and GPU E2E. |
| `.github/workflows/branch-e2e.yml` | Standard, GPU, Debian upgrade, Kubernetes HA, and Kubernetes credential-driver E2E. PR mirror pushes use `test:e2e`, `test:e2e-gpu`, `test:upgrade`, and `test:e2e-kubernetes` labels; merge groups run core and GPU E2E. |
| `.github/workflows/build-binaries.yml`, `build-vm-driver.yml` | Shared binary matrices used by branch and release workflows. The VM driver remains separate because its build consumes the runtime binaries. |
| `.github/workflows/build-images.yml` | Builds and pushes multi-platform images, then uploads the same OCI images as workflow artifacts. |
| `.github/workflows/package-release-binaries.yml` | Packages raw build artifacts into release tarballs without rebuilding them. |