build system: fix 3 more silent-failure bugs in the baked-shim port path

Found by extending the edge-case suite to the baked-shim path (E17-E19) after a
sync reported 'ready' but silently dropped a module's Redox shim:
 - git show used an ABSOLUTE recipe path ('HEAD:/mnt/.../source/f') which git
   rejects (needs repo-relative) -> empty content -> garbage delta. Now uses
   ${dir#$ROOT/}.
 - diff|patch under 'set -o pipefail': diff exits 1 whenever files differ (always
   here), so the pipeline looked failed even when patch succeeded -> EVERY shim
   false-rejected. Now captures the delta to a file and checks patch's own exit.
 - a shim whose file was renamed/removed upstream, or unreadable from HEAD, was
   silently skipped. Now: Redox-added files are carried in verbatim; a missing
   target or unreadable HEAD file -> SHIM-REJECT (manual), never a silent drop.
Also: old-version URL derivation now rewrites the major.minor dir component too
(KDE mirrors nest tarballs under .../6.28/foo-6.28.0). CI branch glob widened to
[0-9]* so 0.4.0/0.5.0 release branches keep triggering.
This commit is contained in:
2026-07-31 21:01:23 +03:00
parent 7bffe6c7c3
commit 49377f768c
3 changed files with 70 additions and 11 deletions
+5 -4
View File
@@ -2,10 +2,11 @@ name: redbear-ci
on:
push:
# Glob so a release-branch increment (0.3.1 -> 0.3.2 -> ...) keeps triggering
# CI — including the versioning-machinery checks below — without editing this
# file on every bump.
branches: ["0.3.*", master]
# Any version-like release branch (0.3.1, 0.3.2, 0.4.0, 0.5.0, 1.0.0, ...)
# keeps triggering CI — including the versioning-machinery checks below —
# without editing this file on every bump. Release branches start with a
# digit; master is listed explicitly.
branches: ["[0-9]*", master]
pull_request:
jobs:
+32 -7
View File
@@ -174,18 +174,43 @@ for dir in "${RECIPES[@]}"; do
# --- capture + reapply baked delta (changes beyond patches) ---
breject=0
if [ "$baked" -gt 0 ] && [ "$vold" != unknown ]; then
# Derive the old-version URL: replace the full version, then the
# major.minor directory component (KDE mirrors nest tarballs under a
# major.minor dir, e.g. .../frameworks/6.28/foo-6.28.0.tar.xz -> 6.10/foo-6.10.0).
oldurl="${url//$vnew/$vold}"
vnm="${vnew%.*}"; vom="${vold%.*}"
[ "$vnm" != "$vnew" ] && [ "$vnm" != "$vom" ] && oldurl="${oldurl//$vnm/$vom}"
if download "$oldurl" "$WORK/$name-old.tar"; then
op="$WORK/$name-old"; rm -rf "$op"; mkdir -p "$op"; tar xf "$WORK/$name-old.tar" -C "$op" 2>/dev/null
otop="$(tar tf "$WORK/$name-old.tar" 2>/dev/null | head -1 | cut -d/ -f1)"; mv "$op/$otop" "$op/source" 2>/dev/null
# for each Redox-marker file uncovered by patches, port its delta onto base
while IFS= read -r rel; do
rel="${rel#*/source/}"
[ -f "$op/source/$rel" ] && [ -f "$base/source/$rel" ] || continue
# clean the committed file (drop corruption), diff vs pristine-old, apply to base
gitf="$WORK/gitf"; git -C "$ROOT" show "HEAD:$dir/source/$rel" > "$gitf" 2>/dev/null || continue
# For each Redox-marker file uncovered by patches, port its delta onto base.
# A shim must NEVER be silently dropped: any failure -> breject (manual).
relroot="${dir#$ROOT/}" # repo-relative recipe dir (git show needs this)
while IFS= read -r line; do
rel="${line#*/source/}"
gitf="$WORK/gitf"
if ! git -C "$ROOT" show "HEAD:$relroot/source/$rel" > "$gitf" 2>/dev/null || [ ! -s "$gitf" ]; then
breject=1; continue # cannot read the Redox-modified file from HEAD
fi
decorrupt "$gitf" > "$gitf.clean"
if ! diff -u "$op/source/$rel" "$gitf.clean" 2>/dev/null | patch --fuzz=0 -s "$base/source/$rel" >/dev/null 2>&1; then breject=1; fi
if [ ! -f "$op/source/$rel" ]; then
# Redox-ADDED file (absent from old upstream): carry it into the new tree verbatim.
mkdir -p "$base/source/$(dirname "$rel")"; cp "$gitf.clean" "$base/source/$rel"; continue
fi
if [ ! -f "$base/source/$rel" ]; then
breject=1; continue # file existed in old upstream+HEAD but gone in new -> manual
fi
if diff -q "$op/source/$rel" "$gitf.clean" >/dev/null 2>&1; then
continue # marker is upstream's own (no Redox delta) -> nothing to port
fi
# Capture the delta to a file — do NOT pipe diff|patch. `diff` exits 1
# whenever the files differ (always, here), and under `set -o pipefail`
# that makes the pipeline look failed even when patch succeeded, which
# would false-reject EVERY shim. Check patch's own exit status instead.
diff -u "$op/source/$rel" "$gitf.clean" > "$WORK/delta.patch" 2>/dev/null
if ! patch --fuzz=0 -s "$base/source/$rel" < "$WORK/delta.patch" >/dev/null 2>&1; then
breject=1 # Redox delta will not apply cleanly at new upstream -> manual
fi
done < <(git -C "$ROOT" grep -lI "__redox__\|Q_OS_REDOX\|defined(__redox" HEAD -- "$dir/source" 2>/dev/null)
else breject=1; fi
fi
@@ -190,6 +190,39 @@ assert_eq "E16 source.tar now v2.0.0" "$(tar tf "$d/source.tar" | head -1)" "app
assert_eq "E16 transient blake3 reconciled" "$(grep -m1 blake3 "$d/recipe.toml" | grep -oE '[0-9a-f]{64}')" "$(b3 "$d/source.tar")"
rm -rf "$d"
echo "=== baked-shim port (regression: git-show path bug that silently dropped shims) ==="
gc(){ git -C "$FIX" add -A >/dev/null 2>&1; git -C "$FIX" commit -qm "$1" >/dev/null 2>&1; }
# E17: old==new pristine (shim context stable), HEAD carries the shim -> ported
mk_tar "$FIX/tarballs/shim-1.0.0.tar" "app-1.0.0" "foo.c:int f(){return 0;}\n"
mk_tar "$FIX/tarballs/shim-2.0.0.tar" "app-2.0.0" "foo.c:int f(){return 0;}\n" ".redbear-src-version:2.0.0\n"
d="$(mk_recipe eng_shim "file://$FIX/tarballs/shim-2.0.0.tar" "$(b3 "$FIX/tarballs/shim-2.0.0.tar")")"
mkdir -p "$d/source"; printf '1.0.0\n' >"$d/source/.redbear-src-version"
printf '#ifdef __redox__\n#define REDOX_SHIM 1\n#endif\nint f(){return 0;}\n' >"$d/source/foo.c"; gc eng_shim
$SYNC eng_shim >/dev/null 2>&1
grep -q "__redox__" "$d/source/foo.c" && ok "E17 shim ported into new tree" || no "E17 shim ported" "marker lost"
assert_eq "E17 version bumped" "$(cat "$d/source/.redbear-src-version")" "2.0.0"
rm -rf "$d"; gc rm
# E18: new pristine changed the shim's anchor line -> SHIM-REJECT, no silent drop
mk_tar "$FIX/tarballs/s2-1.0.0.tar" "app-1.0.0" "foo.c:int f(){return 0;}\n"
mk_tar "$FIX/tarballs/s2-2.0.0.tar" "app-2.0.0" "foo.c:long g(void){return 0;}\n" ".redbear-src-version:2.0.0\n"
d="$(mk_recipe eng_shim2 "file://$FIX/tarballs/s2-2.0.0.tar" "$(b3 "$FIX/tarballs/s2-2.0.0.tar")")"
mkdir -p "$d/source"; printf '1.0.0\n' >"$d/source/.redbear-src-version"
printf '#ifdef __redox__\n#define REDOX_SHIM 1\n#endif\nint f(){return 0;}\n' >"$d/source/foo.c"; gc eng_shim2
out="$($SYNC eng_shim2 2>&1)"; rc=$?
assert_contains "E18 moved-context shim -> SHIM-REJECT (not silent)" "$out" "REJECT"
assert_eq "E18 rc=2" "$rc" "2"
assert_eq "E18 source/ untouched on reject" "$(cat "$d/source/.redbear-src-version")" "1.0.0"
rm -rf "$d"; gc rm
# E19: Redox-ADDED file (absent upstream) carried into the new tree verbatim
mk_tar "$FIX/tarballs/s3-1.0.0.tar" "app-1.0.0" "foo.c:x\n"
mk_tar "$FIX/tarballs/s3-2.0.0.tar" "app-2.0.0" "foo.c:x\n" ".redbear-src-version:2.0.0\n"
d="$(mk_recipe eng_shim3 "file://$FIX/tarballs/s3-2.0.0.tar" "$(b3 "$FIX/tarballs/s3-2.0.0.tar")")"
mkdir -p "$d/source"; printf '1.0.0\n' >"$d/source/.redbear-src-version"; printf 'x\n' >"$d/source/foo.c"
printf '#ifdef __redox__\nredox only\n#endif\n' >"$d/source/redoxonly.c"; gc eng_shim3
$SYNC eng_shim3 >/dev/null 2>&1
[ -f "$d/source/redoxonly.c" ] && grep -q "__redox__" "$d/source/redoxonly.c" && ok "E19 Redox-added file carried into new tree" || no "E19 added file carried" "redoxonly.c lost"
rm -rf "$d"; gc rm
echo ""
echo "================ RESULT ================"
echo " PASS: $PASS FAIL: $FAIL"