Spec: release-plz checkout the pipeline commit (v0.10.6)¶
- Repository:
gitlab.com/phpboyscout/cicd - Component touched:
release-plz - Release: patch —
fix:→ v0.10.6
Problem¶
The release-plz component's .release-plz-base before_script does:
GitLab CI checks out a detached HEAD at $CI_COMMIT_SHA; the checkout
re-attaches to the branch so release-plz can resolve its upstream. But a
bare git checkout <branch> moves to whatever commit the local
branch ref points at. On a runner that reuses its build directory
(GIT_STRATEGY=fetch, common on self-hosted runners) that local ref can
be stale from a previous job — git fetch updates
refs/remotes/origin/<branch> but not the local refs/heads/<branch>.
So release-plz ends up analysing an older commit than the one the
pipeline is for.
Observed¶
On phpboyscout/rust-tool-base, the v0.5.3 publish pipeline merged the
Release MR (Cargo.toml at 0.5.3) but release-plz:release logged
Previous HEAD position was <sha> chore: release v0.5.3 (the bare
checkout moving away from the correct commit) followed by
rtb-* 0.5.2: Already published for every crate — it ran against a
0.5.2 tree and published nothing. The publish only succeeded after
the consumer added a git update-ref refs/heads/<branch> $CI_COMMIT_SHA
guard to its own extra_before_script. This spec moves that fix into
the component so every consumer is covered and the workaround can be
dropped.
Decision¶
Force the local branch to the pipeline's commit, and fetch tags:
checkout -B creates-or-resets the branch to $CI_COMMIT_SHA (always
present — it is the detached HEAD CI checked out) and switches to it, so
a stale local ref cannot survive. The tag fetch ensures release-plz sees
the per-crate release tags it keys off, independent of what the reused
workspace had. git branch --set-upstream-to and the token remote swap
that follow are unchanged.
Why not rely on GIT_STRATEGY: clone¶
Forcing a full clone per job would also avoid stale refs but is far more expensive on every release pipeline; consumers should not have to change their git strategy to get a correct release. The two-line fix is self-contained in the component.
Scope & non-goals¶
- In scope: the checkout in
.release-plz-base(shared by bothrelease-plz:prandrelease-plz:release). No input-shape changes. - Non-goals: the v0.10.4 pr-after-release ordering (unchanged); the v0.10.3 two-job split (unchanged); tokens / forge / bootstrap.
Downstream¶
rust-tool-base bumps its pin to v0.10.6 and removes the
git update-ref + tag-fetch workaround from its .release-plz-setup
anchor (now redundant). Its next release pipeline must publish on the
correct tree with no spurious same-version MR.
Testing¶
tests/release-plz/.gitlab-ci.yml includes the component against a repo
with no Cargo workspace; both jobs still hit the documented non-zero exit
and are allow_failure-tolerated. checkout -B <branch> $CI_COMMIT_SHA
behaves identically to the bare checkout on a fresh clone (the local ref
already equals the SHA), so the self-test is unaffected; the
self-test:release-plz trigger stays green.