fix(release): allow draft asset smoke access

This commit is contained in:
rcourtman
2026-08-08 18:57:11 +01:00
parent 76e07be290
commit 52fbcfd341
4 changed files with 30 additions and 2 deletions
+4 -1
View File
@@ -1289,7 +1289,10 @@ jobs:
- validate_release_assets
if: ${{ always() && needs.prepare.result == 'success' && needs.create_release.result == 'success' && needs.validate_release_assets.result == 'success' && needs.prepare.outputs.historical_asset_backfill_only != 'true' && github.event.inputs.draft_only != 'true' }}
permissions:
contents: read
# GitHub's release API requires write-level repository access to read
# assets from an unpublished draft release. The called workflow only
# performs GET requests, but a read-scoped GITHUB_TOKEN receives 403.
contents: write
uses: ./.github/workflows/install-sh-smoke.yml
secrets: inherit
with:
+4
View File
@@ -94,6 +94,10 @@ jobs:
smoke:
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
# Unpublished draft release metadata and assets are unavailable to a
# read-scoped GITHUB_TOKEN even though this job only performs GETs.
contents: write
steps:
- name: Checkout repository (for README key extraction)
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
@@ -1771,6 +1771,13 @@ That same reusable-validation call boundary also owns permission handoff.
`.github/workflows/validate-release-assets.yml` call the write scopes it
requests (`contents: write` and `issues: write`), rather than inheriting the
release pipeline's top-level read-only default and failing at workflow startup.
The staged installer-smoke boundary owns the same fail-closed handoff for
unpublished assets. GitHub requires write-level repository access to read draft
release metadata and asset bytes, even when the consumer only performs GET
requests. The `install_sh_smoke` call in `.github/workflows/create-release.yml`
and the `smoke` job in `.github/workflows/install-sh-smoke.yml` must therefore
grant `contents: write`; the workflow-level default remains read-only and the
smoke job must not receive unrelated write scopes.
That same validation status boundary must preserve release identity when it
annotates a draft or failed release. Every release-body or draft-state PATCH
from `.github/workflows/validate-release-assets.yml` must carry the intended
@@ -433,6 +433,10 @@ func TestCreateReleaseUploadsPowerShellInstaller(t *testing.T) {
t.Fatalf("create-release.yml job %s must skip historical backfill and draft-only runs before invoking downstream workflow_call", job)
}
}
installSmokeJob := workflowJobBlock(t, workflow, "install_sh_smoke")
if !strings.Contains(installSmokeJob, "contents: write") {
t.Fatal("create-release.yml install_sh_smoke must grant contents: write so the called workflow can read unpublished draft assets")
}
readinessJob := workflowJobBlock(t, workflow, "release_readiness")
if !strings.Contains(readinessJob, publishedReleaseGuard) {
t.Fatal("release_readiness must skip historical backfill and draft-only runs")
@@ -1828,7 +1832,8 @@ func TestBuildReleasePackagesPulseMcpForAllPlatforms(t *testing.T) {
// cannot return.
func TestInstallShSmokeWorkflowPresent(t *testing.T) {
assertFileContainsAll(t, repoFile(".github", "workflows", "install-sh-smoke.yml"),
workflowPath := repoFile(".github", "workflows", "install-sh-smoke.yml")
assertFileContainsAll(t, workflowPath,
// Inputs and triggers.
`name: install.sh Smoke (Release Assets)`,
`workflow_call:`,
@@ -1863,6 +1868,15 @@ func TestInstallShSmokeWorkflowPresent(t *testing.T) {
`curl -fsS http://127.0.0.1:7655/api/version`,
`Installed version mismatch. Expected`,
)
workflowBytes, err := os.ReadFile(workflowPath)
if err != nil {
t.Fatalf("read install-sh-smoke workflow: %v", err)
}
smokeJob := workflowJobBlock(t, string(workflowBytes), "smoke")
if !strings.Contains(smokeJob, "contents: write") {
t.Fatal("install-sh-smoke.yml smoke job must grant contents: write to read unpublished draft release assets")
}
}
func TestPromoteFloatingTagsReachableViaWorkflowCall(t *testing.T) {