Spec: Order release-plz:pr after release-plz:release (v0.10.4)¶
- Repository:
gitlab.com/phpboyscout/cicd - Component touched:
release-plz - Release: patch —
fix:→ v0.10.4
Problem¶
v0.10.3 split release-plz into two jobs — release-plz:pr and
release-plz:release — sharing a hidden .release-plz-base (see
2026-06-12-release-plz-split-jobs-v0.10.3.md). Both sit in the same
stage with no ordering, so they run concurrently.
On the pipeline that merges a Release MR, release publishes the new
crates and pushes the per-crate vX.Y.Z tags, while pr independently
re-derives the next version from the repo + registry. Because they run
at the same time, pr can observe the pre-publish view — the
crates.io sparse-index entry and/or the freshly-pushed git tags have not
propagated to pr's checkout yet — and conclude the last release is the
previous version. It then opens a Release MR proposing the version
release is in the middle of shipping.
Observed¶
On phpboyscout/rust-tool-base, after v0.5.1→v0.5.2 the release-plz:pr
job repeatedly opened chore: release v0.5.2 MRs (!36, !38, !41) even
though 0.5.2 was already (being) published. The MRs are spurious: they
re-propose the in-flight version. They self-correct on a later pipeline
once the index + tags have propagated (the next run correctly opened
chore: release v0.5.3), but each one is operator noise and, if merged,
would drive release to re-tag an existing version.
Decision¶
Make release-plz:pr depend on release-plz:release:
release-plz:pr:
extends: .release-plz-base
needs:
- job: release-plz:release
optional: true
script: ...
needs orders pr after release within the stage (no new stage or
input). On a Release-MR-merge pipeline pr now runs only once release
has finished publishing + tagging, so it analyses the settled
post-release state and computes the correct next version. On an ordinary
push release is a fast no-op and pr follows it as before.
Both jobs share the same rules: (inputs.if), so they are always
added to the pipeline together — the needs reference is never
dangling. optional: true is defensive belt-and-braces against a
consumer overriding one job's rules.
Behaviour notes¶
- Production: a genuinely failed
release(e.g. a publish error) now blockspr. That is correct — an incomplete release should not spawn a next-version MR; the next pipeline retries both. - Self-test:
releaseisallow_failure(the cicd repo has no Cargo workspace, so release-plz exits non-zero), and aneedsdependent still runs after anallow_failurejob, sopris still exercised.
Scope & non-goals¶
- In scope: add
needs:torelease-plz:printemplates/release-plz.yml; adjust the self-test if the ordering affects it. No input-shape changes. - Non-goals: the v0.10.3 working-tree-isolation split (unchanged); tokens, forge, bootstrap (unchanged); any other component.
Testing¶
tests/release-plz/.gitlab-ci.yml includes the component against a repo
with no Cargo workspace; both jobs hit the documented non-zero exit and
are allow_failure-tolerated. Under this change release-plz:pr runs
after release-plz:release; the allow_failure overrides on both job
names still apply, and the self-test:release-plz trigger stays green.
The real ordering is verified downstream: rust-tool-base bumps its pin
to v0.10.4 and its next release-merge pipeline must produce no
spurious same-version Release MR.