rust-release¶
The Rust half of a colophon release. Colophon
proposes the release MR, writes the new version into Cargo.toml and
Cargo.lock, and tags when the MR merges. It never touches a registry. This
component does the two things a Rust release needs beyond that:
rust-semverrunscargo semver-checkson colophon's release MR, against the versions on crates.io. If the API change needs a bigger bump than the version colophon wrote, the job is red and so is the release MR.rust-publishruns on the tag pipeline. It checks that every crate that publishes carries the tag's version, then publishes once: the whole workspace in dependency order, or the single crate.
It is a separate component from colophon so that a Go or Node project
including colophon never gets a Rust job. Wiki spec
0116
records the design; colophon's side is its spec
0027.
Jobs¶
| Job | Runs on | What it does |
|---|---|---|
rust-semver |
the release MR (colophon/release/*) |
cargo semver-checks check-release, one --package per publishing member that crates.io has. A crate never published, or with publish = false, is skipped, because there is no baseline. |
rust-publish |
a tag matching tag_pattern |
Reads the version from the tag, then stops red if any publishing member has another version. Asks crates.io for each one: all present exits 0 having done nothing, some present stops red naming both lists, none present publishes with --locked (and --workspace when the root Cargo.toml has a [workspace]). |
A re-run is safe. If the tag pipeline is retried after a complete publish,
rust-publish finds every crate on crates.io and is green. If a workspace
publish stopped part-way, the job does not guess: it names what is published and
what is missing, and finishing it is a person's call.
The semver gate only runs on the release MR. On any other MR the version in
Cargo.toml is still the last release's, so every API change would read as
unreleased and the check would always fail.
The version a tag carries is the trailing X.Y.Z (and any pre-release
suffix) after the last v, -v, /v or @. v0.9.1 and rtb-error-v0.6.5
both work, which are the estate's two shapes. The colophon component's
colophon-release job derives $COLOPHON_VERSION the same way.
Inputs¶
| Input | Type | Default | Description |
|---|---|---|---|
image |
string | rust-tools:v0.2.5 |
Needs cargo, jq, curl and cargo-semver-checks. rust-tools has cargo-semver-checks from v0.2.0. A project's rust-toolchain.toml still picks the toolchain. |
semver_stage |
string | test |
Stage for rust-semver. |
semver_if |
string | '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^colophon\/release\//' |
Gating rules:if: for rust-semver. Matches the branch the colophon component derives. Change it only alongside colophon's release_branch. |
stage |
string | release |
Stage for rust-publish. |
tag_pattern |
string | v root tags and <crate>-v tags |
RE2 pattern a tag must match for rust-publish to run. |
token |
string | $CARGO_REGISTRY_TOKEN |
crates.io API token. Read only by rust-publish, and only when there is something to publish. |
cache_prune_days |
number | 7 |
As for the other rust-* components: when the runner exports RUST_CACHE_DIR, the target directory is keyed by compiler and libc, and unused keys are pruned after this many days. Wiki spec 0106. A key last used before a newer key appeared goes after one idle day regardless (wiki spec 0119). |
extra_before_script |
string | "" |
Shell snippet run first in both jobs, for native build dependencies. Both jobs compile. |
resource_group |
string | "$CI_PROJECT_PATH_SLUG-rust-compile" |
Serialises rust-semver with the project's other compile jobs. rust-publish has its own group, so two tag pipelines never publish at once. |
Protect the release tags
CARGO_REGISTRY_TOKEN is a protected variable, so it only reaches
pipelines for protected refs. Protect the tag shapes the project releases
(v*, or <crate>-v*). An unprotected tag runs rust-publish without a
token, which stops red before cargo runs.
Usage¶
A single crate keeping its <crate>-v tags. .colophon.yaml:
.gitlab-ci.yml:
include:
- component: gitlab.com/phpboyscout/cicd/colophon@main
inputs:
release_files: "CHANGELOG.md **/CHANGELOG.md Cargo.toml **/Cargo.toml Cargo.lock"
- component: gitlab.com/phpboyscout/cicd/rust-release@main
A lockstep workspace leaves out versioning.tag and releases on a v root tag.
The includes are the same.
release_files has to admit the manifests and the lock file, because colophon
writes the version into them. Its default admits changelogs only, and would
fail every release MR.
See also¶
colophon, which proposes, tags and announcesrelease-plz, which this replaces and is deprecated