forked from heavy-duty/ceremony
docs: wire refs guard into ceremony flow
This commit is contained in:
parent
dcf72a9af8
commit
66b136efc0
7 changed files with 59 additions and 5 deletions
3
.github/labeler.yml
vendored
3
.github/labeler.yml
vendored
|
|
@ -32,9 +32,12 @@ scope:guards:
|
|||
- actions/changelog-armed/**
|
||||
- actions/changelog-monotonic/**
|
||||
- actions/drill-recorded/**
|
||||
- actions/refs-not-closing/**
|
||||
- .github/workflows/refs-guard.yml
|
||||
- test/changelog-armed.test.sh
|
||||
- test/changelog-monotonic.test.sh
|
||||
- test/drill-recorded.test.sh
|
||||
- test/refs-not-closing.test.sh
|
||||
scope:labels:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
|
|
|||
|
|
@ -182,6 +182,13 @@ triage bug, and the move is to say so on the issue, not to guess.
|
|||
absent that instruction `Closes #N` remains the default. The exception was
|
||||
bought the hard way: #143 carried `Closes #137` as doctrine then required,
|
||||
and the merge closed #137 with its post-merge criterion unmet (#151).
|
||||
On a `Refs #N` PR, never put a closing keyword (`close`, `closes`,
|
||||
`closed`, `fix`, `fixes`, `fixed`, `resolve`, `resolves`, `resolved`)
|
||||
immediately before `#N` anywhere in the body — including the sentence
|
||||
explaining why the PR does not close it. GitHub reads the whole body by
|
||||
adjacency, not intent. Put the number first (`#N is closed by hand`) or
|
||||
omit it (`triage closes the issue by hand`). A code span does not protect
|
||||
the phrase: a backticked `Closes #199` still closed #199 (#200, #218).
|
||||
Drafts are invisible to the reviewer panel on
|
||||
purpose — the draft phase is yours.
|
||||
- **The issue's acceptance criteria are your definition of done.** Reproduce
|
||||
|
|
|
|||
|
|
@ -34,7 +34,12 @@ In order of authority:
|
|||
not a defect: the issue directs it, triage owns that close, and a
|
||||
request-changes on the "missing" keyword enforces the bug the shape
|
||||
exists to fix — `Closes #137` closed its issue with a post-merge
|
||||
criterion unmet (#151). Check every
|
||||
criterion unmet (#151). For a `Refs #N` body, also verify that no closing
|
||||
keyword immediately precedes `#N` anywhere in the body, even in prose
|
||||
explaining the hand close or inside a code span: GitHub used those exact
|
||||
shapes to close #209, #212 and #199 (#200, #218). The safe forms put the
|
||||
number first (`#N is closed by hand`) or omit it (`triage closes the issue
|
||||
by hand`). Check every
|
||||
criterion; a PR that ships less than the issue says is a request-changes
|
||||
even if the code is beautiful.
|
||||
2. **The repo's load-bearing constraints** — the rules bought with
|
||||
|
|
|
|||
|
|
@ -44,9 +44,11 @@ runs:
|
|||
.data.repository.pullRequest
|
||||
| if . == null then error("pull request was not returned") else .body // "" end
|
||||
' <<<"$facts" >"$body_file"
|
||||
jq -er '
|
||||
jq -r '
|
||||
.data.repository.pullRequest.closingIssuesReferences
|
||||
| if .pageInfo.hasNextPage then
|
||||
| if . == null then
|
||||
error("closing issue references were not returned")
|
||||
elif .pageInfo.hasNextPage then
|
||||
error("more than 100 closing issue references; refusing a partial verdict")
|
||||
else
|
||||
.nodes[].number
|
||||
|
|
|
|||
4
changelog.d/218.md
Normal file
4
changelog.d/218.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
### Added
|
||||
|
||||
- Pull requests that promise `Refs #N` now fail a read-only, body-edit-aware
|
||||
guard if GitHub would close N through a keyword or sidebar link (#218).
|
||||
|
|
@ -124,14 +124,41 @@ the machinery at all:
|
|||
consumer. In particular, `0.1.0` carries `changelog-armed`,
|
||||
`changelog-monotonic` and `drill-recorded` plus `docs-sync`, but not
|
||||
`changelog-assembled` or `runner-isolated`.
|
||||
6. **Labels automation** (optional but recommended): the two callers from
|
||||
6. **`.github/workflows/refs-guard.yml`** — the body-aware guard is its own
|
||||
caller because `edited` is load-bearing: #200 gained its accidental
|
||||
closing keyword after the PR opened, with no push to wake ordinary CI.
|
||||
It costs the consumer one read-only workflow file and no other machinery:
|
||||
|
||||
```yaml
|
||||
name: Refs guard
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
refs-not-closing:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: heavy-duty/ceremony/actions/refs-not-closing@<pinned-tag>
|
||||
```
|
||||
|
||||
`refs-not-closing` is **unreleased** until the first tag carrying #218.
|
||||
Adopt this caller with that ordinary pin bump; never point only this file
|
||||
at a moving or newer ref.
|
||||
7. **Labels automation** (optional but recommended): the two callers from
|
||||
[Labels automation](#labels-automation) — the event-facing labels
|
||||
caller and the sweep caller (#209) — plus `.github/labels.conf`
|
||||
(panel + the repo's `scope:*` rows) and `.github/labeler.yml` (the
|
||||
path→scope globs). Run the sweep caller's `workflow_dispatch` once —
|
||||
**this bootstraps the taxonomy, `release` label included** — and use it
|
||||
again whenever an operator needs a full-board sweep immediately.
|
||||
7. **The artifact hook** (optional): `.github/actions/release-artifact/`
|
||||
8. **The artifact hook** (optional): `.github/actions/release-artifact/`
|
||||
per [The artifact hook](#the-artifact-hook). No hook → the source
|
||||
tarball is the package.
|
||||
|
||||
|
|
@ -156,6 +183,8 @@ precisely so the machinery is safe to work on
|
|||
sibling `push:` silently kills a door (rig's review catch).
|
||||
- [ ] Swap the guard *script* steps in `ci.yml` for the `uses:` steps in
|
||||
the bootstrap list above (with `fetch-depth: 0` on the checkout).
|
||||
- [ ] Add `refs-guard.yml` from the bootstrap list with the same ceremony
|
||||
pin as the release caller and CI guard steps.
|
||||
- [ ] Replace `labels.yml` with the caller from
|
||||
[Labels automation](#labels-automation) and add the sweep caller
|
||||
`labels-sweep.yml` beside it (#209); extract
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ check "#214 incident replays red" 1 "#212" guard incidents-214 212
|
|||
body incidents-200 'Refs #199' 'A later edit added `Closes #199`.'
|
||||
check "#200 incident replays red" 1 "#199" guard incidents-200 199
|
||||
|
||||
body multiple 'Refs #5 and Refs #7.' 'Triage closes #5 and fixes #7 by hand.'
|
||||
check "failure names every intersecting issue" 1 \
|
||||
"scheduled to close: #5 #7" guard multiple 5 7
|
||||
|
||||
for number in 207 191 190 176 165 164; do
|
||||
body "incident-$number" "Refs #$number"
|
||||
check "#$number incident replays green" 0 "no Refs target" \
|
||||
|
|
|
|||
Loading…
Reference in a new issue