From 040782cad09763d2e93d4a09fbe37f4f91431e8e Mon Sep 17 00:00:00 2001 From: Brian Majewski Date: Mon, 8 Jun 2026 10:44:34 -0700 Subject: [PATCH] feat: secrets migrate --status surfaces v2-only externals (coverage, EGB-712) --- secrets | 15 ++++++++++++--- test/migrate.bats | 11 +++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/secrets b/secrets index ed6e1f4..68e7112 100755 --- a/secrets +++ b/secrets @@ -2242,12 +2242,21 @@ _migrate_status() { new="${f%.gradle-properties.age}.properties.age" [ -f "$new" ] || untwinned=$((untwinned + 1)) done < <(find "$dir" -type f -name '*.gradle-properties.age' 2>/dev/null) + # v2-only externals: a .properties.age with no .gradle-properties.age twin — + # old (v1) clients cannot read these (the additive-v2 forcing function). + local v2only=0 pf + while IFS= read -r pf; do + [ -f "$pf" ] || continue + [ -f "${pf%.properties.age}.gradle-properties.age" ] || v2only=$((v2only + 1)) + done < <(find "$dir" -type f -name '*.properties.age' 2>/dev/null) + local v2note="" + [ "$v2only" -gt 0 ] && v2note=" [$v2only v2-only — old clients not served]" if [ "$v1" -eq 0 ]; then - echo " $project: v2-ready (no v1 properties blobs)" + echo " $project: v2-ready (no v1 properties blobs)$v2note" elif [ "$untwinned" -eq 0 ]; then - echo " $project: migrated ($v1 v1 blob(s), all twinned)" + echo " $project: migrated ($v1 v1 blob(s), all twinned)$v2note" else - echo " $project: NEEDS MIGRATE ($untwinned of $v1 v1 blob(s) un-twinned) — cd into the project and run 'secrets migrate'" + echo " $project: NEEDS MIGRATE ($untwinned of $v1 v1 blob(s) un-twinned) — cd into the project and run 'secrets migrate'$v2note" any_untwinned=1 fi done diff --git a/test/migrate.bats b/test/migrate.bats index 281a281..4ef2084 100644 --- a/test/migrate.bats +++ b/test/migrate.bats @@ -437,6 +437,17 @@ m_file_src() { mkdir -p "$HOME/keystores"; printf 'KS\x00\x01\x02\xffDATA\n' > [[ "$output" == *"Finalize-ready"* ]] || false } +@test "migrate --status counts v2-only externals (old clients not served)" { + make_v1_store + m_gradle_src $'beaconClerkPkTest=pk_test_abc\n' + create_project_dir v2onlyext + printf 'gradle-properties ~/.gradle/gradle.properties beaconClerkPkTest\n' > .secrets-files + "$SECRETS_BIN" push v2onlyext >/dev/null 2>&1 # v2-only (fresh, no v1 twin) + run "$SECRETS_BIN" migrate --status + [ "$status" -eq 0 ] # no v1 blobs -> finalize-ready + [[ "$output" == *"v2-only"* ]] || false # surfaced as v2-only coverage +} + @test "migrate --status on an already-v2 store says nothing to do" { init_with_remote create_project_dir v2status