fix: pre-landing review for store-format-v2 (verify-window orphan, copy-forward push, --force, comment)
Pre-landing review (1 critical, 4 informational): - CRITICAL: per-project `secrets verify` during the migration window flagged the freshly-written v2 twin as a spurious orphan and exited 1 (store still reads v1, so verify's expected set only held the .gradle-properties.age name). Breaks the documented migrate->verify->finalize workflow and CI. Fix: verify's orphan set now accounts for BOTH suffix forms of a properties external, so the twin is never a false orphan mid-migration. Regression test added. - Copy-forward now pushes the twins (mirrors push/rekey) so a --finalize on another machine sees them; previously twins were local-only until finalize, a multi-machine footgun. - Dropped the undocumented `--force` alias (keep `--yes`). - Clarified the EGB-700 comment (which-format line, folded into EGB-703). Deferred to EGB-701: the two finalize find-walks over *.gradle-properties.age could collapse to one pass. Full suite 236/236.
This commit is contained in:
parent
5521d978a3
commit
c10e89fb51
2 changed files with 27 additions and 4 deletions
16
secrets
16
secrets
|
|
@ -1908,8 +1908,8 @@ cmd_which() {
|
|||
resolve_store
|
||||
echo "store: $SECRETS_DIR"
|
||||
echo "source: $STORE_SOURCE"
|
||||
# EGB-700: surface the store format so users can tell v1 from v2 during the
|
||||
# migration window. A v1 store is a legacy store with no format marker.
|
||||
# EGB-700 (folded into EGB-703): surface the store format so users can tell
|
||||
# v1 from v2 during the migration window. v1 = legacy store, no format marker.
|
||||
echo "format: v$(_store_format)"
|
||||
|
||||
# v2 manifest (.secrets.json): validate and summarize. Validation here
|
||||
|
|
@ -2051,7 +2051,12 @@ _verify_project() {
|
|||
[ -n "$etype" ] || continue
|
||||
slug=$(_secrets_files_slug "$epath")
|
||||
erel="external/$slug.$(_external_blob_suffix "$etype").age"
|
||||
expected="$expected$erel"$'\n'
|
||||
# Account for BOTH the v1 and v2 suffix forms in the orphan set. During the
|
||||
# migration window (after copy-forward, before --finalize) the v2 twin
|
||||
# coexists with the v1 blob; neither should read as an orphan whichever
|
||||
# format the store currently reports. (file's two forms are identical.)
|
||||
expected="${expected}external/$slug.$etype.age"$'\n'
|
||||
[ "$etype" = "gradle-properties" ] && expected="${expected}external/$slug.properties.age"$'\n'
|
||||
eblob="$pdir/$erel"
|
||||
if [ ! -f "$eblob" ]; then
|
||||
echo "FINDING: external '$epath' ($etype) is declared but has no blob in the store ($project/$erel missing). Run 'secrets push'." >&2
|
||||
|
|
@ -2176,6 +2181,9 @@ _migrate_project() {
|
|||
ensure_store_protections
|
||||
git -C "$SECRETS_DIR" add -A
|
||||
git -C "$SECRETS_DIR" commit -m "migrate: copy-forward v2 twins for $project" >/dev/null 2>&1 || true
|
||||
# Push the twins so a --finalize on another machine sees them (finalize
|
||||
# refuses any v1 blob without a twin). Mirrors push/rekey's push behavior.
|
||||
git -C "$SECRETS_DIR" remote get-url origin >/dev/null 2>&1 && git -C "$SECRETS_DIR" push >/dev/null 2>&1 || true
|
||||
info "Copy-forward for '$project': $moved new v2 twin(s), $already already present. v1 blobs kept (non-destructive). Run 'secrets migrate --finalize' once every project is migrated and every machine is upgraded."
|
||||
}
|
||||
|
||||
|
|
@ -2261,7 +2269,7 @@ cmd_migrate() {
|
|||
case "$1" in
|
||||
--dry-run) dry_run=true; shift ;;
|
||||
--finalize) finalize=true; shift ;;
|
||||
--yes|--force) force=true; shift ;;
|
||||
--yes) force=true; shift ;;
|
||||
-*) die "Unknown migrate flag: $1. Usage: secrets migrate [--dry-run | --finalize] [--yes]" ;;
|
||||
*) die "migrate takes no project argument. Run it from inside a project (copy-forward) or use --finalize (store-wide)." ;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue