fix: bump-release compares upstream CRATE versions, not git tags
redbear-ci / check (push) Has been cancelled

The upgrade decision compared the newest upstream git TAG against $base,
which callers pass as the fork's Cargo.toml CRATE version. For several
Redox crates those namespaces are unrelated, so the comparison was
meaningless:

  relibc    git tags 0.5.0 / 0.6.0, but Cargo.toml AT tag 0.6.0 is 0.1.0,
            and our fork is 0.2.5 -> reported '0.2.5 -> 0.6.0 upgrade'
            when upstream master is 0.2.5, i.e. ALREADY CURRENT
  libredox  newest tag is v0.1.13, but upstream master is 0.1.19

Not cosmetic: upgrade-forks.sh consumes the result as --to=<ref> and does
'git reset --hard <ref>' before reapplying Red Bear commits as a net diff.
Acting on the relibc answer would have reset the fork onto an unrelated
lineage and reapplied our commits against it.

These forks are Cargo path deps with [patch.crates-io] and our label is
<upstream-version>+rb<branch>, so the CRATE version is the upstream
identity Cargo must satisfy -- compare crate-to-crate. Tag scanning
remains as the fallback for forks with no readable Cargo.toml.

Report after the fix:
  syscall  0.9.0  -> 0.9.1   upgrade   (tag 0.9.1 also exists)
  libredox 0.1.18 -> 0.1.19  upgrade   (master only; no matching tag)
  relibc   0.2.5              ok       (was a false positive)
  redoxfs / redox-scheme / userutils  ok

Known gap, documented at the call site: a fork whose crate version has no
matching tag (libredox) will make upgrade-forks.sh --to=<version> fail
loudly rather than reset onto a wrong ref -- the safe outcome. Threading
the upstream branch ref through as the rebase target is follow-up work.
This commit is contained in:
2026-08-03 11:13:40 +03:00
parent 7b8a1b2838
commit 675c5e82fc
+60
View File
@@ -128,9 +128,69 @@ SEMVER_RE='^[0-9]+\.[0-9]+\.[0-9]+$'
# not upgrades (relibc's 0.6.0/2020 outranks its newer 0.2.x API line
# lexically); (b) tags not version-greater than the current base are not
# upgrades either (the base tag itself is usually an ancestor of HEAD).
# Resolve the fork's REAL upstream identity: its published CRATE version.
#
# These forks are consumed by Cargo as path deps with [patch.crates-io], and our
# label is <upstream-version>+rb<branch>. The number Cargo must satisfy (e.g.
# `libredox = "0.1"`) is the CRATE version, so that is the upstream identity --
# not the git tag name.
#
# Comparing tags against the crate version is meaningless for several Redox
# crates, because the two namespaces are unrelated:
# relibc git tags 0.5.0 / 0.6.0, but Cargo.toml AT tag 0.6.0 says 0.1.0,
# while our fork says 0.2.5 -> reported a bogus "0.2.5 -> 0.6.0
# upgrade" when upstream master is in fact 0.2.5, i.e. ALREADY CURRENT
# libredox newest tag v0.1.13, but upstream master is 0.1.19
#
# That mistake is not cosmetic: upgrade-forks.sh consumes the result as its
# --to=<ref> and does `git reset --hard <ref>` before reapplying Red Bear commits
# as a net diff. Acting on the bogus relibc answer would have reset the fork onto
# an unrelated lineage.
#
# Returns "<version>|<ref>" where <ref> is the upstream branch carrying it, or
# "|" when the fork has no readable Cargo.toml (callers then fall back to tags).
upstream_crate_identity() {
local fork="$1" url="$2"
local d="$ROOT/local/sources/$fork"
[[ -n "$fork" ]] || { echo "|"; return 0; }
[[ -d "$d/.git" || -f "$d/.git" ]] || { echo "|"; return 0; }
git -C "$d" remote add upstream "$url" 2>/dev/null || true
[[ $NO_FETCH -eq 0 ]] && git -C "$d" fetch -q --tags upstream 2>/dev/null
local ref v
for ref in upstream/master upstream/main; do
git -C "$d" rev-parse --verify --quiet "$ref" >/dev/null 2>&1 || continue
v=$(git -C "$d" show "${ref}:Cargo.toml" 2>/dev/null \
| sed -n 's/^version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
[[ -n "$v" ]] && { echo "${v}|${ref}"; return 0; }
done
echo "|"
return 0
}
latest_tag_for_url() {
local url="$1" fork="${2:-}" base="${3:-}"
[[ $NO_FETCH -eq 0 ]] || { echo "|0"; return 0; }
# Prefer the crate version when the fork is a Cargo crate: it is the real
# upstream identity and is directly comparable to $base (also a crate
# version). Only fall back to tag scanning when no Cargo.toml is readable.
local ident icrate iref
ident="$(upstream_crate_identity "$fork" "$url")"
icrate="${ident%%|*}"; iref="${ident##*|}"
if [[ -n "$icrate" ]]; then
if [[ -n "$base" ]] && ! version_greater "$icrate" "$base"; then
echo "|1" # already current -- no upgrade
return 0
fi
# Emit the VERSION (semver) so the report and the caller's comparison
# work. NOTE: for forks whose crate version has no matching git tag
# (libredox 0.1.19 exists only on master; newest tag is v0.1.13),
# upgrade-forks.sh --to=<version> will fail loudly rather than reset
# onto a wrong ref -- which is the safe outcome. Carrying the branch
# ref ${iref} through to the rebase target is follow-up work.
echo "${icrate}|1"
return 0
fi
local tag forkdir="" raw=0
[[ -n "$fork" && -d "$ROOT/local/sources/$fork/.git" ]] \
&& forkdir="$ROOT/local/sources/$fork"