Skip to content

ci: block merges that skip CHANGELOG.md or contributor credit - #128

Merged
shivamlalakiya merged 7 commits into
PhilanthroPy-Project:mainfrom
slegarraga:ci/credit-guard
Aug 24, 2026
Merged

ci: block merges that skip CHANGELOG.md or contributor credit#128
shivamlalakiya merged 7 commits into
PhilanthroPy-Project:mainfrom
slegarraga:ci/credit-guard

Conversation

@slegarraga

Copy link
Copy Markdown
Contributor

Closes #113.

What

  • scripts/check_credit.sh: given base/head SHAs and the PR author login, fails when the diff touches files under philanthropy/ without also touching CHANGELOG.md, or when the author's handle is absent from CONTRIBUTORS.md. Emits GitHub ::error:: annotations so the failure surfaces inline on the Files tab.
  • A standalone credit-guard job in ci.yml wires it up on pull_request events only — direct pushes to main and history that predates the guard are never re-litigated, per the issue's done-when.

Verified locally against real diffs:

Scenario Result
Source change, no changelog ✗ exit 1
Source change, author not in CONTRIBUTORS.md ✗ exit 1
Source change, changelog + credited author ✓ exit 0
Tests/docs-only diff skipped

Design choices worth flagging:

  • The author check keys on the @handle string in CONTRIBUTORS.md, matching the file's existing format.
  • No maintainer exemption was added: the issue allows one 'if necessary', but since release/chore commits go straight to main they never hit a PR check anyway. Easy to add later if it chafes.
  • My own open fix: reject network-scheme paths at the read boundary #123 needed a CHANGELOG entry to comply — updated in that branch already. The guard works on its author first.

Closes PhilanthroPy-Project#113. A credit-guard job runs scripts/check_credit.sh on every
pull request: if the diff touches philanthropy/, the PR must also touch
CHANGELOG.md and its author must already appear in CONTRIBUTORS.md.
Runs only on pull_request events, so direct pushes and pre-guard
history are never re-litigated. Verified against four scenarios
locally: source change without changelog (fails), uncredited author
(fails), credited author with changelog (passes), tests-only diff
(skips).
@shivamlalakiya

Copy link
Copy Markdown
Contributor

CI is green and the script/workflow wiring looks solid, but per AGENTS.md every PR needs an entry under ## [Unreleased] in CHANGELOG.md (you're already in CONTRIBUTORS.md, so that part's covered). A bit ironic for the credit-guard PR itself to skip it. Could you add a line describing the new credit-guard job? Holding the merge until then.

Per AGENTS.md, every PR needs an entry under [Unreleased]. Describes the
new scripts/check_credit.sh wiring and its two gates (changelog touched,
author credited) for PRs that touch philanthropy/.
@slegarraga

Copy link
Copy Markdown
Contributor Author

Done in c4c159a: added the entry under ## [Unreleased] describing the
credit-guard job (what it gates, how it's wired into ci.yml, and that it
runs on pull_request events only). Good catch on the irony; the guard now
has nothing left to catch on this one.

slegarraga and others added 2 commits August 22, 2026 13:23
Signed-off-by: slegarraga <slegarraga@users.noreply.github.com>
@shivamlalakiya

Copy link
Copy Markdown
Contributor

Reviewed. The script and the intent look right, but this cannot merge as-is: the credit-guard job has no event guard.

ci.yml triggers on push: branches: [main] as well as pull_request. On a push event github.event.pull_request is null, so BASE_SHA, HEAD_SHA and PR_AUTHOR all expand to empty strings, and scripts/check_credit.sh "" "" "" runs git diff --name-only "" "", which fails under set -e. Every post-merge run on main would go red. The CHANGELOG entry already claims the job is "wired into ci.yml on pull_request events only" -- that needs to be true in the YAML:

  credit-guard:
    name: Changelog and contributor credit (issue #113)
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest

Two smaller notes, neither blocking:

  • grep -qE "@${author}(...)" interpolates the login into a regex. Human logins are [A-Za-z0-9-] so they are safe, but a bot author (dependabot[bot]) would be read as a character class. Bot PRs do not touch philanthropy/ today, so this is latent, not live.
  • The changelog check only asserts that CHANGELOG.md was touched, not that the new line landed under [Unreleased]. Fine as a guard, worth knowing it is not the stronger check.

Also: GitHub still reports this branch as CONFLICTING, but that state is stale -- git merge-tree --write-tree origin/main on the head commit merges clean. Run gh pr update-branch (or rebase) after adding the if: and it should go green.

- credit-guard now has 'if: github.event_name == pull_request' so post-merge
  pushes to main do not invoke check_credit.sh with empty SHAs (review note
  from shivamlalakiya; makes the CHANGELOG claim literally true in YAML).
- check_credit.sh matches the @login token literally via awk index instead of
  interpolating it into an ERE, so bot logins like dependabot[bot] are not
  parsed as a character class. Verified with a 7-case harness covering
  human/bot/prefix/skip/changelog/empty-author paths.
@slegarraga

Copy link
Copy Markdown
Contributor Author

Fixed both points and pushed as 0af3a45 (branch also merged current main; GitHub now reports MERGEABLE):

  • credit-guard carries if: github.event_name == 'pull_request', exactly as sketched, so push builds to main skip the job instead of invoking check_credit.sh with empty SHAs. The CHANGELOG's "on pull_request events only" claim is now literally true in the YAML.
  • Closed the latent bot-login note too while there: check_credit.sh matches the @login token literally (awk index() plus a boundary check) rather than interpolating the author into an ERE, so a future dependabot[bot] source PR cannot be misparsed as a character class. Kept the error text identical so annotations stay stable.

Verification before pushing:

  • bash -n clean; workflow parses and asserts equal to your suggested expression.
  • A 7-case harness against a scratch repo, all passing: human listed -> OK; prefix trap (@ana vs listed @anakin) -> correctly rejected; @dependabot[bot] listed -> OK via literal match; bot missing -> rejected; diff without philanthropy/ files -> skipped; missing CHANGELOG -> rejected; empty author -> rejected with the "could not be determined" annotation.
  • On CI at this head: Changelog and contributor credit pass (5s), lint/typecheck, CodeQL, build + dist checks and the full test matrix are green.

On your last note, agreed the touched-file check is the weaker form; leaving it as-is for this guard per your framing. And thanks for the sharp catch, every post-merge run on main going red would have been an embarrassing debut for issue #113's job. Congrats on landing #140 and #141 as well.

@shivamlalakiya
shivamlalakiya merged commit c5d6ac3 into PhilanthroPy-Project:main Aug 24, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI: make CONTRIBUTORS.md/CHANGELOG.md updates a merge-blocking check

2 participants