forked from heavy-duty/ceremony
fix: refuse target-head stranded fragments
This commit is contained in:
parent
a2b9b30930
commit
0f3d3b36eb
1 changed files with 37 additions and 0 deletions
|
|
@ -33,6 +33,12 @@ set -euo pipefail
|
||||||
# no '## ' heading, and changelog_section extracts the body below HEAD's
|
# no '## ' heading, and changelog_section extracts the body below HEAD's
|
||||||
# heading — so the date HEAD stamped into its heading never enters the
|
# heading — so the date HEAD stamped into its heading never enters the
|
||||||
# comparison, and a date difference can never masquerade as a prose one.
|
# comparison, and a date difference can never masquerade as a prose one.
|
||||||
|
#
|
||||||
|
# This guard narrows, but cannot close, the target-movement window: it sees a
|
||||||
|
# fragment present when CI reads the target ref, but one can still land after
|
||||||
|
# the final run and before merge. Requiring release PRs to be up to date with
|
||||||
|
# their target branch before merge is the repository setting that closes that
|
||||||
|
# residual window (#253).
|
||||||
|
|
||||||
base_ref="${1:-${CHANGELOG_ASSEMBLED_BASE:-origin/main}}"
|
base_ref="${1:-${CHANGELOG_ASSEMBLED_BASE:-origin/main}}"
|
||||||
changelog="${2:-${CHANGELOG:-CHANGELOG.md}}"
|
changelog="${2:-${CHANGELOG:-CHANGELOG.md}}"
|
||||||
|
|
@ -169,6 +175,37 @@ frag_count="$(printf '%s' "$base_frags" | grep -c . || true)"
|
||||||
|
|
||||||
failures=0
|
failures=0
|
||||||
|
|
||||||
|
# Refusal: the target branch gained a fragment after this release PR's merge
|
||||||
|
# base, so the ceremony could not have consumed it. Merging this tree would
|
||||||
|
# strand that fragment for the next release and misattribute when it shipped.
|
||||||
|
stranded=""
|
||||||
|
while IFS= read -r -d '' entry; do
|
||||||
|
meta="${entry%%$'\t'*}"
|
||||||
|
path="${entry#*$'\t'}"
|
||||||
|
otype="$(printf '%s\n' "$meta" | awk '{ print $2 }')"
|
||||||
|
name="${path##*/}"
|
||||||
|
case "$otype:$name" in
|
||||||
|
blob:README.md) ;;
|
||||||
|
blob:*.md)
|
||||||
|
if ! printf '%s' "$base_frags" | grep -Fxq "$path"; then
|
||||||
|
stranded="${stranded} ${path}"$'\n'
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < <(git ls-tree -z "$base_ref" -- "$dir/")
|
||||||
|
if [ -n "$stranded" ]; then
|
||||||
|
{
|
||||||
|
echo "changelog-assembled: fragment(s) on target '$base_ref' were not consumed by this release PR:"
|
||||||
|
echo
|
||||||
|
printf '%s' "$stranded"
|
||||||
|
echo
|
||||||
|
echo " Merging now would strand these entries for the next release and"
|
||||||
|
echo " misattribute when they shipped."
|
||||||
|
echo " Fix: rebase onto the target head and re-run bin/changelog-assemble '$ver'."
|
||||||
|
} >&2
|
||||||
|
failures=$((failures + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
# Refusal: a fragment the ceremony consumed is still present on HEAD. The
|
# Refusal: a fragment the ceremony consumed is still present on HEAD. The
|
||||||
# ceremony deletes exactly what it assembles (#112) — a fragment that
|
# ceremony deletes exactly what it assembles (#112) — a fragment that
|
||||||
# survives its own release sits in the directory and is assembled AGAIN
|
# survives its own release sits in the directory and is assembled AGAIN
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue