Skip to content

Commit 79f2dd9

Browse files
kylehgcclaude
andcommitted
fix(release): make the version stamp work on macOS and RPM
The stamp shipped in #83 broke two of the seven build jobs. macOS — `sed: 1: "Cargo.toml`. Two separate GNU-isms, only one of which was obvious: BSD sed reads the argument after -i as a backup suffix, and the `0,/re/` address range used to match only the first occurrence is a GNU extension BSD rejects outright. Fixing the first alone would still have failed. Uses awk instead, which behaves the same on both. RPM — `invalid version "0.1.0-rc.10": contains invalid character (allowed: alphanumeric, '.', '_', '+', '%', '{', '}', '~', '^')`. RPM forbids '-' in a version, but cargo requires semver. The tool's own error names the way out: '+' is legal in RPM, and semver allows it as build metadata. So the pre-release marker becomes +rc.N rather than -rc.N, which cargo, dpkg and rpm all accept. '~' would sort better for rpm and deb, but cargo rejects it. This is the same failure I made earlier today with BSD grep in non_utf8_argv_test: verified against GNU tooling on Windows, shipped to a macOS runner. Checked explicitly for it this time — the awk rewrite was prompted by noticing the 0,/re/ range would fail on BSD even after the -i fix. Verified: - all five tag forms derive correctly - cargo metadata reports 0.1.0+rc.10 - 0.1.0+rc.10 contains only characters rpm's error message lists as legal - the stamp rewrites line 3 only; clap/serde/serde_json versions intact - the stable path yields a bare 0.1.0 - a malformed tag is rejected rather than corrupting the manifest Still unverified locally: the .deb/.rpm filenames, which need cargo-deb and cargo-generate-rpm on Linux, and BSD sed/awk behaviour itself. The next RC's published assets and the macOS job are the checks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent aa0bc39 commit 79f2dd9

1 file changed

Lines changed: 29 additions & 7 deletions

File tree

‎scripts/version-from-tag.sh‎

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,23 @@
1616
# scripts/version-from-tag.sh --test
1717
set -euo pipefail
1818

19-
# fork-dev-0.1.0-rc.9 -> 0.1.0-rc.9 fork-v0.1.0 -> 0.1.0
20-
# dev-0.44.2-rc.344 -> 0.44.2-rc.344 v0.44.1 -> 0.44.1
19+
# fork-dev-0.1.0-rc.9 -> 0.1.0+rc.9 fork-v0.1.0 -> 0.1.0
20+
# dev-0.44.2-rc.344 -> 0.44.2+rc.344 v0.44.1 -> 0.44.1
21+
#
22+
# The pre-release marker becomes `+rc.N` (semver build metadata) rather than
23+
# `-rc.N` (semver pre-release), because RPM forbids `-` in a version:
24+
#
25+
# invalid version "0.1.0-rc.10": contains invalid character
26+
# (allowed: alphanumeric, '.', '_', '+', '%', '{', '}', '~', '^')
27+
#
28+
# `+` is legal in all three: semver, Debian, and RPM. `~` would suit RPM and
29+
# Debian better (it sorts before the release) but cargo rejects it outright.
2130
version_from_tag() {
2231
local v="$1"
2332
v="${v#fork-}"
2433
v="${v#dev-}"
2534
v="${v#v}"
26-
printf '%s' "$v"
35+
printf '%s' "$v" | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)-(.+)$/\1+\2/'
2736
}
2837

2938
if [ "${1:-}" = "--test" ]; then
@@ -38,10 +47,10 @@ if [ "${1:-}" = "--test" ]; then
3847
fail=1
3948
fi
4049
}
41-
check "fork-dev-0.1.0-rc.9" "0.1.0-rc.9"
50+
check "fork-dev-0.1.0-rc.9" "0.1.0+rc.9"
4251
check "fork-v0.1.0" "0.1.0"
4352
check "fork-v1.2.3" "1.2.3"
44-
check "dev-0.44.2-rc.344" "0.44.2-rc.344"
53+
check "dev-0.44.2-rc.344" "0.44.2+rc.344"
4554
check "v0.44.1" "0.44.1"
4655
exit $fail
4756
fi
@@ -53,7 +62,7 @@ VERSION="$(version_from_tag "$TAG")"
5362

5463
# Refuse anything cargo would reject, rather than corrupting the manifest and
5564
# failing later with a confusing parse error.
56-
if ! printf '%s' "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
65+
if ! printf '%s' "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(\+[0-9A-Za-z.]+)?$'; then
5766
echo "::error::Tag '$TAG' does not yield a semver version (got '$VERSION')" >&2
5867
exit 1
5968
fi
@@ -62,7 +71,20 @@ fi
6271

6372
# Only the first `version =` — that is the [package] one. Dependency versions
6473
# appear later in the file and must not be touched.
65-
sed -i "0,/^version = \".*\"/s//version = \"${VERSION}\"/" "$MANIFEST"
74+
#
75+
# awk rather than sed, for two separate portability reasons on macOS runners:
76+
# BSD sed reads the argument after -i as a backup suffix (the GNU form fails with
77+
# `sed: 1: "Cargo.toml`), and the `0,/re/` address range used to match only the
78+
# first occurrence is a GNU extension that BSD sed rejects outright.
79+
awk -v v="$VERSION" '
80+
!done && /^version = "/ {
81+
print "version = \"" v "\""
82+
done = 1
83+
next
84+
}
85+
{ print }
86+
' "$MANIFEST" > "${MANIFEST}.tmp"
87+
mv "${MANIFEST}.tmp" "$MANIFEST"
6688

6789
STAMPED="$(grep -m1 '^version = ' "$MANIFEST" | sed 's/version = "\(.*\)"/\1/')"
6890
if [ "$STAMPED" != "$VERSION" ]; then

0 commit comments

Comments
 (0)