mirror of
https://github.com/cozystack/cozystack.git
synced 2026-10-30 16:47:20 +09:00
ci(release): stop finalize persisting credentials so the tag push triggers tags.yaml
pull-requests-release.yaml's finalize job checked out the repo with the default persist-credentials, leaving GITHUB_TOKEN embedded as http.extraheader. Every later tag/branch push re-injects the CI app token via `git remote set-url`, but a persisted extraheader silently wins over the URL credential — so those pushes authenticated as GITHUB_TOKEN. A GITHUB_TOKEN-authenticated push creates no workflow run (GitHub anti-recursion), which is exactly why v1.6.0's stable tag never triggered tags.yaml: the generate-changelog and update-website-docs backstops never ran. Set persist-credentials: false on the finalize checkout, so the set-url app token actually authenticates the pushes — the same handling promote-rc.yaml already uses. Audited every git/gh step in the job: both tag steps set-url the app token before pushing, and Ensure-maintenance-branch / Publish-draft-release / the retag+chart steps use the app token via github-script or a separate registry login — none depends on the persisted GITHUB_TOKEN extraheader. Pin it in hack/promote-gate-contract.bats. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
This commit is contained in:
3 files changed
+29
-1
No files matched your search
@@ -81,6 +81,15 @@ jobs:
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# Do NOT persist GITHUB_TOKEN as http.extraheader. Every tag/branch push
|
||||
# below re-injects the app token via `git remote set-url`, but a persisted
|
||||
# extraheader silently wins over the URL credential — so those pushes
|
||||
# would authenticate as GITHUB_TOKEN, and a GITHUB_TOKEN push creates no
|
||||
# workflow run (GitHub anti-recursion). That is exactly why v1.6.0's
|
||||
# stable tag triggered no tags.yaml run (the generate-changelog and
|
||||
# update-website-docs backstops never fired). With this false, the set-url
|
||||
# app token authenticates, matching how promote-rc.yaml already pushes.
|
||||
persist-credentials: false
|
||||
|
||||
# Create the release tag at the merge commit — write-once.
|
||||
#
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ Reviewer checklist:
|
||||
|
||||
Fires on merge of a PR that is merged, carries the `release` label, and is authored by `cozystack-ci[bot]` (the last guard closes the "name a branch `release-X.Y.Z`, get it labelled, merge it" hole). Head branch must match `release-X.Y.Z[-suffix]`. This is where **every irreversible side effect of a promotion happens** — after the rc's mandatory E2E was checked at dispatch and the PR merged, making promotion transactional. Steps:
|
||||
|
||||
1. **Create the tag at the merge commit** (write-once). The merge commit of `Prepare release vX.Y.Z` did not exist before the PR opened, so there is nothing to move — the tag is created here for the first time. A pre-existing tag at a different commit fails the step loudly rather than being force-moved (see [Tag immutability](#tag-immutability)).
|
||||
1. **Create the tag at the merge commit** (write-once). The merge commit of `Prepare release vX.Y.Z` did not exist before the PR opened, so there is nothing to move — the tag is created here for the first time. A pre-existing tag at a different commit fails the step loudly rather than being force-moved (see [Tag immutability](#tag-immutability)). The checkout uses `persist-credentials: false` so this push authenticates as the **CI app** (via `git remote set-url`), not the default `GITHUB_TOKEN` — a `GITHUB_TOKEN` push creates no workflow run, so a persisted-credential push would silently skip `tags.yaml` entirely and its stable-tag backstops (`generate-changelog`, `update-website-docs`) would never fire.
|
||||
2. **Cut the `api/apps/v1alpha1/vX.Y.Z` Go-module tag** (write-once, stable only) at the same commit, so Go consumers of `api/apps/v1alpha1` get the release. Moved here from `tags.yaml`, whose `prepare-release` body is skipped for a promoted stable (the draft already exists).
|
||||
3. **Ensure the maintenance branch `release-X.Y` exists** at the tag commit. Created if missing; updated fast-forward-only — a non-fast-forward update warns and is left for a maintainer rather than being force-updated.
|
||||
4. **Publish the draft release**, with `docs/changelogs/vX.Y.Z.md` from the merge commit as its body (an absent or whitespace-only file warns and leaves the draft's body in place, rather than publishing blank notes). `make_latest` is computed against published-non-prerelease tags: prereleases stay `false`; tags older than the current max stay `false` (and the current max is force-restored to `latest` if necessary, so an older patch tag cut after a newer minor won't downgrade `latest`).
|
||||
|
||||
@@ -8,6 +8,7 @@ REPO_ROOT="$(cd "$(dirname "${BATS_TEST_FILENAME:-$0}")/.." && pwd)"
|
||||
PROMOTE="$REPO_ROOT/.github/workflows/promote-rc.yaml"
|
||||
PULL_REQUESTS="$REPO_ROOT/.github/workflows/pull-requests.yaml"
|
||||
TAGS="$REPO_ROOT/.github/workflows/tags.yaml"
|
||||
FINALIZE="$REPO_ROOT/.github/workflows/pull-requests-release.yaml"
|
||||
|
||||
job_block() {
|
||||
awk -v job=" $1:" '
|
||||
@@ -217,3 +218,21 @@ code_lines() {
|
||||
grep -qF 'promote-rc.yaml::website-docs' "$TAGS"
|
||||
grep -qiF 'backstop' "$TAGS"
|
||||
}
|
||||
|
||||
@test "finalize checkout does not persist credentials so the app-token tag push triggers tags.yaml" {
|
||||
block="$(job_block finalize "$FINALIZE")"
|
||||
[ -n "$block" ]
|
||||
checkout="$(printf '%s\n' "$block" | awk '
|
||||
/^ - name: Checkout repo$/ { inside = 1; next }
|
||||
/^ - name: / { inside = 0 }
|
||||
inside')"
|
||||
[ -n "$checkout" ]
|
||||
|
||||
# The one-line root-cause fix. Without persist-credentials:false the checkout
|
||||
# persists GITHUB_TOKEN as http.extraheader, which silently defeats the app token
|
||||
# each later `git remote set-url` injects onto the tag pushes — and a
|
||||
# GITHUB_TOKEN-authenticated push creates no workflow run (anti-recursion), so
|
||||
# tags.yaml's stable-tag backstops never fire (v1.6.0's tag never triggered it).
|
||||
count="$(printf '%s\n' "$checkout" | code_lines | rg -cF 'persist-credentials: false' || true)"
|
||||
[ "${count:-0}" -eq 1 ]
|
||||
}
|
||||
Reference in new issue
Block a user