feat(ci): opt-in pre-merge testgrid for core changes via label + RC-tagged staging build - #6085
Draft
kriscoleman wants to merge 3 commits into
Draft
feat(ci): opt-in pre-merge testgrid for core changes via label + RC-tagged staging build#6085kriscoleman wants to merge 3 commits into
kriscoleman wants to merge 3 commits into
Conversation
…taging build (ku-adc) Add .github/workflows/testgrid-pr.yaml: an opt-in, pre-merge Testgrid run for core kURL changes, triggered by the 'run-testgrid' label or workflow_dispatch. Builds the PR's kURL with a core-only strategy, publishes under a unique RC tag to a per-PR versioned staging path, queues tgrun against it, and comments the run URL on the PR — without ever touching staging/VERSION. Recovers the deleted deploy-branch-staging.yaml as the base and adapts it: - pull_request[labeled] + workflow_dispatch triggers (no pull_request_target) - label-gating (write access) + testgrid-pr GitHub Environment for secrets - os-firstlast subset by default, os-full via 'testgrid-full' label - build-and-upload ordered after copy-packages so the fresh PR build always wins over stale copies on overlapping .tmpl/extra packages - reuses mshick/add-pr-comment for the PR run-URL comment Refs #6084. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
BLOCKING: - Stop using AWS_PROD_* in testgrid-pr.yaml. Use a dedicated least-privilege secret (AWS_STAGING_PR_ACCESS_KEY_ID/SECRET) that must be IAM-scoped to s3://kurl-sh/staging/* with DENY on dist/* and staging/VERSION. Since the credentialed jobs run PR-authored make targets, the IAM policy is the real blast-radius boundary. Documented as a hard provisioning prerequisite. - Add VERSIONED_ONLY mode to bin/generate-addons.js and set it in testgrid-pr; drop the non-atomic restore step. The RC build now never writes the shared unversioned staging metadata, so there is no write-then-restore race under cancel-in-progress and no fragile prev-version rollback. LOW: - Document testgrid-pr GitHub Environment required reviewers as a HARD prerequisite (not optional) in the workflow header and README. - SHA-pin token/secret-receiving third-party actions: mshick/add-pr-comment@v3 and docker/login-action@v4. - Document that label runs reuse kurl-util:alpha and rebuild only the core batch; extra-packages / build-kurl-util-image require workflow_dispatch. - Wrap S3 copy/upload calls in exponential-backoff retry (mirrors bin/upload-dist-staging.sh); note the AWS CLI list-objects-v2 auto-pagination in bin/list-packages-s3.sh so the core-only copy set stays complete. Verified: actionlint PASS (integrated shellcheck), shellcheck list-packages-s3 PASS, node --check generate-addons.js PASS, workflow YAML parses. Refs #6084. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…testgrid-pr (ku-adc) Round 2 review (2 LOW): LOW-A: tighten the documented least-privilege IAM prerequisite so an exfiltrated staging credential cannot clobber shared staging state. The workflow only writes under staging/<rc-tag>/ (staging/*-rc-*), so the documented policy now: allow ListBucket+GetObject on staging/* (read for the copy-from-previous-release step); allow PutObject/DeleteObject ONLY on staging/*-rc-*; explicit DENY on dist/*, staging/VERSION, and the shared unversioned staging/addons-gen.json + staging/supported-versions-gen.json. Notes not to deny staging/*-gen.json broadly (would block the versioned staging/<rc-tag>/addons-gen.json this workflow must write). LOW-B: fix doc contradiction — the security-model bullet no longer claims the run-testgrid label 'requires write access / only maintainers can start a run'. It now states the label is Triage-addable and the testgrid-pr Environment's required reviewers is the real gate on secret exposure. Verified every workflow write targets staging/<rc-tag>/. actionlint PASS, node --check PASS, YAML parses. Refs #6084. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Member
Author
Review record (con-voyage escort)Reviewed across 3 rounds by independent GitHub-Actions/Bash code and security reviewers. The security review was the primary gate (this workflow builds and runs PR-authored code with S3 + Testgrid credentials). Security review — found and closed 2 BLOCKING issues, then tightened the IAM contract; final verdict PASS ("airtight"):
Code review — PASS: triggers/concurrency, RC-tag uniqueness, core-only build completeness (copy prev + rebuild core = complete installable version), and the tgrun/PR-comment wiring all verified.
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Core kURL changes (
scripts/,packages/, staging metadata) only get exercised in Testgrid after they land onmain, whendeploy-staging.yamlruns on push. So a core regression stays invisible until it's already merged. That's exactly how the Ubuntu 26.04kubelet: command not foundbug (#6072) slipped through and needed a follow-up fix (#6082).This brings back a pre-merge Testgrid path for core changes. It existed once as
deploy-branch-staging.yamland got deleted right after 26.04 shipped, so I recovered it from git history and reworked it into a label-driven, PR-safe workflow.This workflow hands repository secrets to jobs that build and run PR-authored code, so two things must be provisioned first. Without them it's a security risk, not a feature.
1. A dedicated least-privilege IAM user for
AWS_STAGING_PR_ACCESS_KEY_ID/AWS_STAGING_PR_SECRET_ACCESS_KEY. This must NOT be the prod credential (AWS_PROD_*). The workflow only ever writes under the per-PR RC prefix, so scope the policy to exactly that:s3:ListBucket+s3:GetObjectonstaging/*(read, to copy packages from the previous staging release).s3:PutObject/s3:DeleteObjectonly onstaging/*-rc-*(the RC prefix, not all ofstaging/*).dist/*,staging/VERSION,staging/addons-gen.json, andstaging/supported-versions-gen.json. (Don't denystaging/*-gen.jsonbroadly, or you'll also block the versionedstaging/<rc-tag>/addons-gen.jsonthis workflow legitimately writes.)Since the credentialed jobs run PR code, that IAM policy (not the workflow text) is the real blast-radius boundary. An exfiltrated credential is only as powerful as the policy lets it be.
2. The
testgrid-prGitHub Environment configured with required reviewers. Therun-testgridlabel is addable at Triage-level access, so it's not a strong gate on its own. The Environment's required reviewers is what actually gates who can start a credentialed run.How it works
Trigger: add the
run-testgridlabel to a PR, or run it manually viaworkflow_dispatchwith a branch input.*.tmpl,common.tar.gz,kurl-bin-utils) from the PR's source and copies everything else from the last staging release. A label run reuseskurl-util:alpha; to rebuild extra packages or a branch-specific util image, useworkflow_dispatchwith theextra-packages/build-kurl-util-imageinputs.<latest-tag>-rc-pr<num>-<sha>, to a per-PR paths3://kurl-sh/staging/<rc-tag>/. It never runsset-current-versionand never touches the sharedstaging/VERSIONpointer or the unversioned staging metadata (aVERSIONED_ONLYmode ingenerate-addons.jskeeps the shared*-gen.jsonuntouched).tgrunagainst that RC version. OS pool defaults to theos-firstlastsubset to keep cost down; add thetestgrid-fulllabel for the full matrix. Concurrency is capped to one run per PR.RC builds are never promoted to prod. Artifacts land under
staging/v20...-rc-.../and get swept by the existingbin/cleanup-staging-s3.sh(30-day cutoff); a tighter S3 lifecycle rule onstaging/*-rc-*is a nice-to-have.Security model
Plain
pull_request, notpull_request_target, so fork code never runs with secrets. Fork PRs are skipped; a maintainer pushes the branch and usesworkflow_dispatchto test a fork. Third-party actions that receive tokens are SHA-pinned. Privileged jobs run in thetestgrid-prEnvironment (see prereq 2 above).What I verified
A GitHub Actions workflow can't really run locally, so I validated what I could:
actionlint(which runs shellcheck on every embedded script),shellcheckon the edited shell,node --checkongenerate-addons.js, and a YAML parse. I traced the build, copy, publish, and queue chain against the existing scripts by hand.What still needs a live run with CI + S3 + Testgrid creds: the actual build/upload to the versioned path, the
tgrunqueue, the PR comment, and the acceptance criterion of demonstrating it on a real core-change PR. That's why this stays a draft.Fixes #6084.
🤖 Generated with Claude Code