Problem
Core kURL changes (scripts/, packages/, staging metadata) cannot be validated in Testgrid until they are merged to main. Only addon PRs get pre-merge Testgrid (.github/workflows/test-addon-pr.yaml, path-filtered to addons/**). Core changes are only exercised when deploy-staging.yaml runs on push to main — it builds packages, uploads them to s3://kurl-sh/staging/<VERSION_TAG>/, writes the active pointer s3://kurl-sh/staging/VERSION, then queues Testgrid against that version.
This means a core regression is invisible until after it lands. It bit us on Ubuntu 26.04 (#6072): kubelet: command not found only surfaced in the post-merge staging Testgrid run, forcing a follow-up fix (#6082).
Prior art (revive, don't reinvent)
This capability existed and was deleted: .github/workflows/deploy-branch-staging.yaml was a workflow_dispatch that built and Testgrid-tested arbitrary branches, with a full vs core-only build strategy, and even carried a temporary push trigger for the ubuntu-2604 branch. It was removed right after 26.04 merged. The repo already gates Testgrid with labels (skip-testgrid, auto-merge), so label-driven CI is idiomatic here.
Proposal
Add an opt-in, pre-merge Testgrid run for core changes, triggered by a label (and workflow_dispatch for manual/branch runs). It builds the PR's kURL version, publishes it under a unique RC tag to a per-PR staging path, queues tgrun against that version, and comments the run URL on the PR — without ever touching the shared staging/VERSION pointer.
- RC tag:
<latest-tag>-rc-pr<num>-<sha> — unique per PR+commit, self-labeling as a pre-merge release candidate that is never promoted to prod.
- Publish path:
s3://kurl-sh/staging/<rc-tag>/ (versioned path only).
- Testgrid consumption:
tgrun queue --staging with installerVersion: <rc-tag>.
Acceptance Criteria
Notes
- Reuse:
bin/upload-dist-staging.sh (versioned upload + change detection), the pr-<num>-<sha> prefix convention (bin/addon-has-changes-matrix.sh), replicated/tgrun:latest queue, and testgrid/specs/*.
- Security refs: GitHub Security Lab "preventing pwn requests"; GitHub Docs "securely using pull_request_target".
- Design brainstorm (full analysis): saved at
.claude/plans/brainstorm-testgrid-pr-label.md.
Problem
Core kURL changes (scripts/, packages/, staging metadata) cannot be validated in Testgrid until they are merged to main. Only addon PRs get pre-merge Testgrid (
.github/workflows/test-addon-pr.yaml, path-filtered toaddons/**). Core changes are only exercised whendeploy-staging.yamlruns on push tomain— it builds packages, uploads them tos3://kurl-sh/staging/<VERSION_TAG>/, writes the active pointers3://kurl-sh/staging/VERSION, then queues Testgrid against that version.This means a core regression is invisible until after it lands. It bit us on Ubuntu 26.04 (#6072):
kubelet: command not foundonly surfaced in the post-merge staging Testgrid run, forcing a follow-up fix (#6082).Prior art (revive, don't reinvent)
This capability existed and was deleted:
.github/workflows/deploy-branch-staging.yamlwas aworkflow_dispatchthat built and Testgrid-tested arbitrary branches, with afullvscore-onlybuild strategy, and even carried a temporarypushtrigger for theubuntu-2604branch. It was removed right after 26.04 merged. The repo already gates Testgrid with labels (skip-testgrid,auto-merge), so label-driven CI is idiomatic here.Proposal
Add an opt-in, pre-merge Testgrid run for core changes, triggered by a label (and
workflow_dispatchfor manual/branch runs). It builds the PR's kURL version, publishes it under a unique RC tag to a per-PR staging path, queuestgrunagainst that version, and comments the run URL on the PR — without ever touching the sharedstaging/VERSIONpointer.<latest-tag>-rc-pr<num>-<sha>— unique per PR+commit, self-labeling as a pre-merge release candidate that is never promoted to prod.s3://kurl-sh/staging/<rc-tag>/(versioned path only).tgrun queue --stagingwithinstallerVersion: <rc-tag>.Acceptance Criteria
testgrid-pr.yaml) triggers onpull_requestlabeledwith a dedicated label (e.g.run-testgrid) AND onworkflow_dispatch(branch input), reusing the deleteddeploy-branch-staging.yamlas the starting point.pull_request_targetwith a PR-head checkout + secrets (pwn-request risk); prefer label-gating (label add = write access) and/or GitHub Environment protection on the secrets.s3://kurl-sh/staging/<rc-tag>/where<rc-tag>is unique per PR+sha.set-current-versionand does NOT overwrites3://kurl-sh/staging/VERSION.tgrunis queued againstinstallerVersion=<rc-tag>with a selected spec + OS list. Defaults to a subset OS list (e.g.testgrid/specs/os-firstlast.yaml) with atestgrid-fulllabel to opt into the full matrix (cost control)..github/actions/testgrid-checkercomment machinery).staging/*-rc-*) and run concurrency is capped.Notes
bin/upload-dist-staging.sh(versioned upload + change detection), thepr-<num>-<sha>prefix convention (bin/addon-has-changes-matrix.sh),replicated/tgrun:latest queue, andtestgrid/specs/*..claude/plans/brainstorm-testgrid-pr-label.md.