chore: address Copilot review round 18

- board-ops: write board dumps to a temp dir, not the repo root. The boards are
  private, so a snapshot is a full export of item IDs and every card's Status
  and Priority — and the recipe left three such files in the worktree, one
  `git add -A` from being published in a PR. All three now go to `$BOARD_TMP`,
  and the snapshot step prints the path, since recovery needs it.
- release: branch from `origin/v2/main` after fetching, and read the version
  once you are on it. A default clone has only `main` checked out, so the local
  ref may not exist and `package.json` was `main`'s — the released version
  rather than the one being bumped from. Added the one-liner for reading it
  before branching, since the branch name needs it.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-29 05:05:47 -04:00
commit d29bbbb763
2 changed files with 31 additions and 9 deletions

View file

@ -199,7 +199,7 @@ Safe alternatives, in order of preference:
`ProjectV2SingleSelectFieldOptionInput.id` is an optional `String`, so a mixed
list works. Verify afterward that no card lost its value — snapshot
`gh project item-list … --format json` before and after and diff; don't just
spot-check.
spot-check. Send those dumps to `$BOARD_TMP` too, for the reason above.
Both the `Incoming` Status option and the Urgent/High/Medium/Low Priority
options were added this way (#1891), with the before/after diff confirming all
@ -213,8 +213,16 @@ card's value and never touch the field schema.
One command, and it is the difference between a five-minute restore and
reconstructing statuses by inference:
⚠️ **Write it outside the repo.** [The boards are private](../issue-triage/SKILL.md),
so a snapshot is a full dump of item IDs and every card's Status and Priority.
Left in the working tree it is one `git add -A` away from being published in a
PR (Copilot).
```sh
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 > board-snapshot.json
BOARD_TMP=$(mktemp -d)
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \
> "$BOARD_TMP/board-snapshot.json"
echo "snapshot: $BOARD_TMP/board-snapshot.json" # note the path; you need it to recover
```
### Recovering from a deleted option
@ -230,18 +238,24 @@ each single-select field under its lowercased name, so both keys are present),
and pass the Priority field id `PVTSSF_lADOCt2Azc4BJVxtzg5iJE4`.
```sh
# 0. Same temp dir the snapshot went to — keep every dump out of the worktree.
BOARD_TMP=${BOARD_TMP:-$(mktemp -d)}
# 1. Which cards lost their value, and what did they hold?
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 > board-broken.json
jq -r '[.items[]|select(.status==null)|.id]' board-broken.json > lost-ids.json
jq -r --slurpfile L lost-ids.json '($L[0]) as $lost
gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \
> "$BOARD_TMP/board-broken.json"
jq -r '[.items[]|select(.status==null)|.id]' "$BOARD_TMP/board-broken.json" \
> "$BOARD_TMP/lost-ids.json"
jq -r --slurpfile L "$BOARD_TMP/lost-ids.json" '($L[0]) as $lost
| [.items[] | select(.id as $i | $lost|index($i)) | .status // "(none)"]
| group_by(.) | map({s:.[0],c:length}) | .[] | "was \(.s): \(.c)"' board-snapshot.json
| group_by(.) | map({s:.[0],c:length}) | .[] | "was \(.s): \(.c)"' \
"$BOARD_TMP/board-snapshot.json"
# 2. Recreate the option, echoing every surviving option's id (see above).
# NOTE: the recreated option gets a NEW id — the deleted one never comes back.
# 3. Re-apply it to the orphaned cards.
for id in $(jq -r '.[]' lost-ids.json); do
for id in $(jq -r '.[]' "$BOARD_TMP/lost-ids.json"); do
gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$id" \
--field-id PVTSSF_lADOCt2Azc4BJVxtzg5iI8c --single-select-option-id <NEW_OPTION_ID>
sleep 0.4

View file

@ -33,13 +33,21 @@ The bump is part of the milestone's work, so it belongs on the develop branch
and flows into `main` with everything else.
```sh
# The branch name carries the version you are bumping TO, so read it first.
# Branch from the REMOTE ref, and read the version only once you are on it.
# A default clone has just `main` checked out, so a local `v2/main` may not
# exist and `package.json` here is `main`'s — the released version, not the one
# you are bumping from (Copilot).
git fetch origin v2/main
git checkout -b v2/chore/<ISSUE>-bump-<X-Y-Z> origin/v2/main
node -p "require('./package.json').version" # what is on v2/main now
git checkout -b v2/chore/<ISSUE>-bump-<X-Y-Z> v2/main
npm version minor --no-git-tag-version # or major / patch; bump only, no tag
node -p "require('./package.json').version" # confirm, then PR → v2/main
```
The branch name carries the version you are bumping **to**, so it is named after
that second reading. If you want it before branching:
`git show origin/v2/main:package.json | node -p "JSON.parse(require('fs').readFileSync(0)).version"`.
⚠️ **Never copy a version out of this file.** It would be a version that has
already shipped by the time you read it, and following it would cut a release
branch named for the wrong release (Copilot).