bug(fragment-check): a PR that DELETES a fragment and adds none is classified fragment-present #1033

Closed
opened 2026-08-28 16:07:14 +02:00 by bosun · 0 comments
Owner

changedFragmentPaths matches on name with no existence check, so a PR that DELETES a fragment and adds none is classified fragment-present.

Split from rt#1028's AC2, which the three-dot fix narrowed but did not close.

Measured on the fixed workflow

reusable-changelog-fragment-check.yml:227
    git diff --name-only "$BASE_SHA...$HEAD_SHA" -- "$FRAGMENTS_DIR"
    diff-filter occurrences: 0

Three-dot reports what the branch changed relative to the merge-base — and that includes the branch's own DELETIONS. changedFragmentPaths (internal/gates/fragment_coverage.go) then matches the deleted path on name, with no os.Stat and no read.

🔑 rt#1028 shrank the population from "any PR open across a cut" — common — to "a PR that deletes a fragment" — rare. This tracker owns what is left.

Two candidate fixes, and they should be costed against each other

--diff-filter=d      exclude deletions at the diff. One flag. Cheapest.
                     ⚠️ also excludes RENAMES seen as delete+add — check that
                     a renamed fragment still counts

existence check      os.Stat each candidate against the head. Explicit, and it
                     states the intent: a path that does not exist is not a
                     fragment this PR provides

The flag is smaller; the check is more legible. Neither is obviously right and the tracker should not pre-decide it.

Acceptance criteria

  • A PR that deletes a fragment and adds none is not classified fragment-present — DONE: --diff-filter=d excludes D-status entries. Reproduced independently: bare [changelog.d/one.md], filtered []. PR#1045, merged 90f30ba4.
  • A PR that renames a fragment still counts as providing one — DONE: reproduced independently in both rename shapes — git-detected (R-status, new path only) and undetected (D+A pair): filtered set keeps [changelog.d/renamed.md].
  • An arm for each, mutation-verified — the rename case is the one a --diff-filter fix can break silentlyDONE: two arms in tests/workflows.bats, both extracting the shipped line via the #1028 helper so a retyped copy cannot drift; mutation-verified by stripping the flag and confirming both redden.

📌 Split by @bosun from rt#1028's AC2, after measuring that the three-dot fix leaves deletions in the set. Not urgent: the remaining population is a PR that removes a changelog fragment without adding one, which is rare and usually deliberate.

`changedFragmentPaths` matches on name with no existence check, so a PR that DELETES a fragment and adds none is classified fragment-present. Split from `rt#1028`'s AC2, which the three-dot fix narrowed but did not close. ## Measured on the fixed workflow ``` reusable-changelog-fragment-check.yml:227 git diff --name-only "$BASE_SHA...$HEAD_SHA" -- "$FRAGMENTS_DIR" diff-filter occurrences: 0 ``` **Three-dot reports what the branch changed relative to the merge-base — and that includes the branch's own DELETIONS.** `changedFragmentPaths` (`internal/gates/fragment_coverage.go`) then matches the deleted path **on name**, with no `os.Stat` and no read. 🔑 **`rt#1028` shrank the population from *"any PR open across a cut"* — common — to *"a PR that deletes a fragment"* — rare. This tracker owns what is left.** ## Two candidate fixes, and they should be costed against each other ``` --diff-filter=d exclude deletions at the diff. One flag. Cheapest. ⚠️ also excludes RENAMES seen as delete+add — check that a renamed fragment still counts existence check os.Stat each candidate against the head. Explicit, and it states the intent: a path that does not exist is not a fragment this PR provides ``` **The flag is smaller; the check is more legible.** *Neither is obviously right and the tracker should not pre-decide it.* ## Acceptance criteria - [x] A PR that deletes a fragment and adds none is **not** classified fragment-present — **DONE:** `--diff-filter=d` excludes D-status entries. Reproduced independently: bare `[changelog.d/one.md]`, filtered `[]`. PR#1045, merged `90f30ba4`. - [x] A PR that **renames** a fragment still counts as providing one — **DONE:** reproduced independently in both rename shapes — git-detected (R-status, new path only) and undetected (D+A pair): filtered set keeps `[changelog.d/renamed.md]`. - [x] An arm for each, mutation-verified — *the rename case is the one a `--diff-filter` fix can break silently* — **DONE:** two arms in `tests/workflows.bats`, both extracting the shipped line via the #1028 helper so a retyped copy cannot drift; mutation-verified by stripping the flag and confirming both redden. 📌 Split by **@bosun** from `rt#1028`'s AC2, after measuring that the three-dot fix leaves deletions in the set. **Not urgent:** the remaining population is a PR that removes a changelog fragment without adding one, which is rare and usually deliberate.
bosun closed this issue 2026-08-28 18:27:18 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#1033
No description provided.