fix: refuse release PRs that strand target fragments #255

Merged
andres merged 3 commits from build/253-stranded-fragments into main 2026-08-24 22:55:26 +00:00
Showing only changes of commit a2b9b30930 - Show all commits

View file

@ -217,6 +217,49 @@ check "a surviving fragment with its entry present fails" 1 "STILL PRESENT" \
check "the survivor refusal names the file" 1 "changelog.d/9.md" \
run survivor base
# A release PR can be faithful to its merge base while the target branch moves
# ahead and gains a fragment during review. That target-only fragment was not
# available to the ceremony, so merging the PR would strand it for the next
# release. The guard must read the target ref as well as their merge base.
seed_flat target-stranded
ceremony target-stranded 0.2.0 2026-07-24
commit_head target-stranded
git -C "$TMP/target-stranded" switch -q base
printf -- '- Landed while the release was under review (#30).\n' \
>"$TMP/target-stranded/changelog.d/30.md"
git -C "$TMP/target-stranded" add -A
git -C "$TMP/target-stranded" commit -qm target-fragment
git -C "$TMP/target-stranded" switch -q main
check "a target-head fragment the release did not consume fails" 1 \
"changelog.d/30.md" run target-stranded base
check "the target-stranding refusal names the rebase remedy" 1 \
"rebase onto the target head" run target-stranded base
check "the target-stranding refusal names the assembler re-run" 1 \
"changelog-assemble '0.2.0'" run target-stranded base
# Removing the target-only fragment makes the same diverged fixture green:
# target drift itself is not the failure, only a stranded fragment is.
git -C "$TMP/target-stranded" switch -q base
rm "$TMP/target-stranded/changelog.d/30.md"
git -C "$TMP/target-stranded" add -A
git -C "$TMP/target-stranded" commit -qm target-fragment-removed
git -C "$TMP/target-stranded" switch -q main
check "the same target fixture is green once no fragment is stranded" 0 \
"byte-for-byte" run target-stranded base
# Spell out the common harmless case independently: the target branch moved,
# but the advancing commit added no fragment.
seed_flat target-unrelated
ceremony target-unrelated 0.2.0 2026-07-24
commit_head target-unrelated
git -C "$TMP/target-unrelated" switch -q base
printf 'unrelated target change\n' >"$TMP/target-unrelated/code.txt"
git -C "$TMP/target-unrelated" add -A
git -C "$TMP/target-unrelated" commit -qm target-unrelated
git -C "$TMP/target-unrelated" switch -q main
check "a target head advanced without a fragment stays green" 0 \
"byte-for-byte" run target-unrelated base
# Fragments consumed, section never stamped: the prose went nowhere.
seed_flat halfdone
rm "$TMP/halfdone/changelog.d/12.md" "$TMP/halfdone/changelog.d/9.md"