Commit b48abc4
ci(board-snapshot): sync the snapshot directory so the R2 mirror matches the documented prefix (#18136)
Fixes #18049
## What this changes
One line in the R2 sync step of `.github/workflows/board-snapshot.yml`,
plus the comment in that step that described the old source.
The step synced the archive worktree ROOT (`aws s3 sync archive/
"$mirror"`) while the snapshot is written to `archive/board`
(`SNAPSHOT_ARGS: --out=archive/board`, near line 237). With
`mirror="s3://${R2_BUCKET}/objectstack/board/"`, that maps
`archive/board/X` onto `objectstack/board/` + `board/X`, so the whole
mirror sat one segment deeper than the `mirror` prefix on the line above
it documents — the `objectstack/board/board/...` layout the card
measured from the bucket side (10912 of 10913 objects, run 34765639736).
Syncing `archive/board/` maps `archive/board/X` to
`objectstack/board/X`.
## Migration: `--delete` does it, and the target is deliberately not
widened
`--delete` is kept, and it is what migrates the bucket: the stale
`objectstack/board/board/` tree is inside the new sync target and has no
local counterpart, so the first scheduled run after this merges removes
it. No cleanup step is needed.
The target is NOT widened to `objectstack/` to reach the same mapping —
that spelling would put `objectstack/snapshots/` inside a `--delete`
target and eat the daily tarballs, which is the failure the step's own
comment already warns about. The daily tarball step is untouched: it
writes its own key from `-C archive .` and still carries `./board/...`,
self-describing.
No secret name or value is touched, no secret is added, and the
workflow's `permissions:` block is unchanged.
## The two `.git` excludes are dropped, and why
They are dead after this change, not merely redundant. `archive/` is a
linked worktree, so its `.git` is a FILE at `archive/.git`; aws-cli
filter patterns are matched against each path relative to the SOURCE
directory, and with the source now `archive/board/` that file is outside
the source entirely. Nothing under `archive/board/` is or can be named
`.git` — the snapshot script writes the board tree there.
Dropping them is behaviour-neutral. Keeping them would have left a
live-looking guard whose accompanying comment describes a path this step
no longer reads, inside the very step whose comment/code disagreement is
what this card is about. The tarball step's own `--exclude=.git` still
applies to `-C archive .` and is left as it is.
## Acceptance, both directions
Measured in the worktree at `9dfcfb46a`:
| reading | before | after |
|---|---|---|
| `grep -n 'aws s3 sync archive/board/'
.github/workflows/board-snapshot.yml` | 0 hits (exit 1) | 1 hit, line
364 |
| `grep -c 'aws s3 sync archive/ ' .github/workflows/board-snapshot.yml`
| 1 | 0 |
| literal control, `grep -n 'mirror=' ...` | line 340 | line 340,
byte-unchanged |
| `git diff --stat origin/main` | — | 1 file changed, 21 insertions, 4
deletions |
A `yaml.safe_load` of the file parses; the job still has 9 steps and
every `if:` guard is byte-unchanged. The `set +e` / `code=$?` / `set -e`
shape around the sync is byte-identical, so the step's exit-code capture
is untouched.
## Verification the maintainer can run, once
The bucket cannot be re-measured from this container (no R2
credentials), so the post-change layout is NOT MEASURED here. After the
next scheduled run (`7 2,8,14,20 * * *`), one `ListObjectsV2` against
prefix `objectstack/board/` should show `manifest.json`, `comments/`,
`issues/` and `reviews/` at the top level of that prefix and no `board/`
subtree under it, while `objectstack/snapshots/` still holds the daily
tarballs. That first run's `deleted` count in the step summary should be
roughly the object count of the old tree.
## Not reachable at PR time
The R2 step is guarded by `if: github.event_name != 'pull_request'`, as
are the archive checkout and the commit/push steps. A `pull_request` run
therefore exercises the snapshot on a real runner (`--out=board
--dry-run --limit=5 --max-requests=25`) and never touches the bucket.
The changed line cannot be proven green by this PR's own CI; it is
covered by the greps above and by the one-run verification described
above.
## Gates
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths — it takes its own change set from
the merge base) and run in the foreground, each exit code captured
before any pipe: 36 derived families, 35 exit 0, reconciled with
`--ran`.
`pnpm check:pm-dispatch-gates` is NOT MEASURED here: its self-test suite
streamed thousands of passing assertions and zero failures, but did not
terminate inside a 520 s budget in this shared container. It runs in
CI's required `Lint & Repo Gates` job.
## Changeset
`skip-changeset`: no package's `files[]` ships `.github/**`, so this
diff publishes nothing from any released package.
## Acceptance notes
- Noted, not filed: the prose block above the step still reads "this
step mirrors the archive CHECKOUT". It stays accurate in substance,
because `board/` is the only entry the archive branch tree holds, but
after this change the sync mirrors that subtree rather than the tree
root. Left as written — rewriting it is prose polish, not a defect, and
this card's surface is the sync step itself.
_Generated by [Claude
Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 739ab52 commit b48abc4
1 file changed
Lines changed: 21 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
339 | 339 | | |
340 | 340 | | |
341 | 341 | | |
342 | | - | |
343 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
344 | 362 | | |
345 | 363 | | |
346 | | - | |
| 364 | + | |
347 | 365 | | |
348 | 366 | | |
349 | | - | |
350 | 367 | | |
351 | 368 | | |
352 | 369 | | |
| |||
0 commit comments