The `<<EOF` heredoc inside the `run: |` step body broke YAML parsing —
heredoc bodies have to start at column 0, but YAML block scalars
require consistent indentation. Both runs of the new workflow on the
v0.8.31 push failed at the workflow-file validation stage with
`expected a comment or a line break, but found '$'` at line 128.
Switching to `printf '%s\n' "line1" "line2" ...` keeps every line of
the message at the same indent as the surrounding shell code, so the
YAML `|` scalar stays consistent. Behaviour is identical from the
contributor's perspective.
Confirmed locally with `python3 -c 'import yaml; yaml.safe_load(...)'`
before pushing.
Solves the long-standing hygiene problem where contributor PRs whose
code lands via maintainer cherry-pick stay open + CONFLICTING forever,
even though their fix is credited in the CHANGELOG. v0.8.29 alone left
~5 such PRs open (#1421, #1429, #1442, #1465 — verified separately).
New workflow `.github/workflows/auto-close-harvested.yml`:
* Triggers on push to main.
* For each commit in the push, scans the commit body for lines
matching `harvested from (PR )?#N` (case-insensitive).
* For each matched PR number, closes the PR with a templated
thank-you that links back to the merged commit, thanks the
contributor by handle, and points them at CONTRIBUTING for
landing future PRs via the faster direct-merge path.
* Idempotent — already-closed PRs are skipped with a log line,
not an error.
* Concurrency-guarded so two near-simultaneous main pushes can't
both try to close the same PR.
Two commit-message patterns are recognised:
* `Harvested from PR #1234 by @username` (preferred form, used
in the templates the maintainer paste-uses for harvests)
* `harvested from #1234` (case-insensitive
fallback for older / shorter forms)
The convention is documented in CONTRIBUTING.md, which also adds a
new "How Your Contribution Lands" section explaining the harvest
model upfront so contributors know what to expect — closing their
PR isn't rejection, and the credit lives in the commit message and
CHANGELOG.
Permissions on the workflow: `pull-requests: write` to close + comment,
`issues: write` for the comment (PR comments are issue comments under
the hood), `contents: read` for the checkout.