Skip to content

board-snapshot: the R2 mirror lands at objectstack/board/board/…, one segment deeper than the workflow documents #18049

Description

@hotlong

The R2 secrets were configured on this repository on 2026-09-13 and the first
configured run is green: run 34765639736
reports R2: synced 10912 object(s), deleted 0; daily tarball written for 2026-09-13.

The mirror works. Its prefix is one segment deeper than this workflow's own
comment says it is
, and that gap is only visible from the bucket side.

What the comment promises vs. what is in the bucket

.github/workflows/board-snapshot.yml documents the mirror as objectstack/board/….
An independent S3 ListObjectsV2 against the bucket (not the run log) returns:

objectstack/board/board/manifest.json
objectstack/board/board/comments/…
objectstack/board/board/issues/…
objectstack/board/board/reviews/…
objectstack/snapshots/2026-09-13.tar.gz

board/board/. 10912 of the 10913 objects sit under it.

Cause

Two lines that are each correct alone:

  • the snapshot writes into archive/board (SNAPSHOT_ARGS: --out=archive/board)
  • the sync source is the worktree ROOT (aws s3 sync archive/ "$mirror", with
    mirror="s3://${R2_BUCKET}/objectstack/board/")

So archive/board/X maps to objectstack/board/ + board/X.

Why it is worth fixing even though nothing reads the archive

Nothing does read it — that invariant is stated in the file and still holds. The
cost is paid exactly once, in the situation the whole workflow exists for: a
restore driven from the documented path looks in objectstack/board/ and finds
one directory instead of a manifest. The daily tarball is unaffected (it is
written to its own key from -C archive ., so it carries ./board/… and is
self-describing).

Fix

Either spelling works; the first keeps the documented layout:

aws s3 sync archive/board/ "$mirror" …

Note that the migration needs no cleanup step: with --delete, the stale
objectstack/board/board/ tree is inside the new sync target and has no local
counterpart, so the first run after the change removes it. That is also the
reason not to fix it by widening the target to objectstack/ instead — that
spelling puts objectstack/snapshots/ inside a --delete target and would
eat the daily tarballs, which is the failure the existing comment already
warns about.

Found while configuring the four R2 secrets; no code change made.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions