Skip to content

ci: derive release version from the tag and fail loudly on mismatch - #46

Merged
shiftcontrol-dan merged 1 commit into
mainfrom
dan/fix-release-workflow-version
Aug 15, 2026
Merged

ci: derive release version from the tag and fail loudly on mismatch#46
shiftcontrol-dan merged 1 commit into
mainfrom
dan/fix-release-workflow-version

Conversation

@shiftcontrol-dan

Copy link
Copy Markdown
Contributor

Summary

The release workflow has been publishing malformed releases since 0.3.1, while reporting success on every run.

release.yml's Get version step read the crate version with:

run: echo "crate_version=$(grep '^version = ' Cargo.toml | cut -d'\"' -f2)" >> $GITHUB_ENV

In a YAML plain scalar, \" is passed through literally, so cut receives a two-character delimiter and rejects it:

$ grep '^version = ' Cargo.toml | cut -d'\"' -f2
cut: bad delimiter

The failure occurs inside a command substitution, so echo still exits 0. The step goes green having written an empty crate_version.

Impact

Every tag push since 0.3.1 produced a release at tag_name: v with assets named scim_v2_v.tar.gz and scim_v2_v.zip, instead of a release at the intended tag.

That release object is still present. It is titled v0.3.1, points at a tag literally named v, and is currently flagged Latest. The v0.4.2 run reproduced the behaviour today, overwriting its assets again. Cleanup of that stale object is deliberately not in this PR.

crates.io was never affected. publish.yml runs cargo publish, which takes its version from Cargo.toml directly, so 0.4.1 and 0.4.2 published correctly.

Change

The version now comes from GITHUB_REF_NAME, which is authoritative given the workflow only triggers on v*.*.* tags, and is cross-checked against Cargo.toml:

crate_version="${GITHUB_REF_NAME#v}"
manifest_version="$(grep -m1 '^version = ' Cargo.toml | cut -d'"' -f2)"
if [ -z "$crate_version" ] || [ "$crate_version" != "$manifest_version" ]; then
  echo "::error::Tag '${GITHUB_REF_NAME}' does not match Cargo.toml version '${manifest_version}'"
  exit 1
fi

set -euo pipefail plus the explicit guard means the class of bug that caused this, a silent empty value, now fails the job rather than shipping a broken release.

Verification

  • YAML parses; the job still resolves to 5 steps.
  • Old expression reproduced against the current Cargo.toml: cut: bad delimiter, exit 1.
  • New logic with GITHUB_REF_NAME=v0.4.2 against version = "0.4.2" yields crate_version=0.4.2, exit 0.
  • New logic with GITHUB_REF_NAME=v9.9.9 emits the error annotation and exits 1.

No version bump, per the intent to let the next release pick this up.

The `Get version` step read the crate version with `cut -d'\"' -f2`. YAML
passes that through as a literal backslash-quote, so `cut` rejected the
two-character delimiter and exited non-zero. Because the failure happened
inside a command substitution, `echo` still exited 0 and the step stayed
green while writing an empty `crate_version`.

Every release since 0.3.1 therefore published to the tag "v" rather than
"vX.Y.Z", with assets named `scim_v2_v.tar.gz` / `scim_v2_v.zip`. The
v0.4.2 run reproduced it today.

The version now comes from `GITHUB_REF_NAME`, which is authoritative on a
tag-triggered run, and is cross-checked against Cargo.toml so a tag that
disagrees with the manifest fails the job instead of silently producing a
malformed release.
@shiftcontrol-dan
shiftcontrol-dan merged commit ea54b86 into main Aug 15, 2026
4 checks passed
@shiftcontrol-dan
shiftcontrol-dan deleted the dan/fix-release-workflow-version branch August 15, 2026 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant