From 20c08063250d9723e2936be4df699fa3d108d7aa Mon Sep 17 00:00:00 2001 From: Myasnikov Daniil Date: Thu, 25 Jun 2026 16:42:56 +0500 Subject: [PATCH] test(release): port promote-retag bats to the cozytest harness hack/promote-retag_test.bats was written for upstream bats (run, $status, $output, setup(), skip), but CI runs hack/*.bats through hack/cozytest.sh, a pure-shell runner that has none of those. The first 'run' therefore died with 'cozytest.sh: run: not found', failing the Unit & controller tests job. Rewrite both cases in the cozytest idiom already used by select-e2e_test.bats and check-host-runtime.bats: redirect to temp files, capture the exit code with '|| rc=$?' so the harness's set -e does not abort the expected-failure case, and assert with plain shell. The selector logic under test is unchanged. Assisted-By: Claude Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Myasnikov Daniil --- hack/promote-retag_test.bats | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/hack/promote-retag_test.bats b/hack/promote-retag_test.bats index b89b45611..e898c0363 100644 --- a/hack/promote-retag_test.bats +++ b/hack/promote-retag_test.bats @@ -7,30 +7,49 @@ # "--migrate-image=..." arg string — so the first skopeo copy to a registry CI # cannot push to aborted the whole promotion. The selector must emit only # cozystack-owned ($REGISTRY/...) refs. - -setup() { - command -v yq >/dev/null 2>&1 || skip "yq (mikefarah) not installed" - yq --version 2>&1 | grep -q mikefarah || skip "yq is not mikefarah" -} +# +# Harness note: the CI path is hack/cozytest.sh, NOT real bats. cozytest.sh's +# awk parser recognizes only @test blocks and a bare `}` on its own line; there +# is no `run`, `$status`, `$output`, `skip`, or setup()/teardown(). Each test +# runs as a shell function under `set -eu -x`, so a non-zero exit aborts the +# test (that is the exit-0 assertion) and other expectations are direct shell +# tests. A test that expects a non-zero exit must capture it with `|| rc=$?` +# so the harness's `set -e` does not abort first. mikefarah yq is assumed +# present (provided by the test toolchain, like the other yq-using bats here). +# +# Run with: hack/cozytest.sh hack/promote-retag_test.bats +# (or `bats hack/promote-retag_test.bats` if the bats binary is +# installed; cozytest.sh is the CI path.) @test "dry-run over the real tree retags only cozystack-owned refs" { - run hack/promote-retag.sh v9.9.9 --dry-run - [ "$status" -eq 0 ] + tmp=$(mktemp -d) + trap 'rm -rf "$tmp"' EXIT + + # Under set -e a non-zero exit aborts the test — that is the exit-0 assertion. + hack/promote-retag.sh v9.9.9 --dry-run >"$tmp/out" 2>"$tmp/err" # At least one cozystack-owned image is selected. - echo "$output" | grep -q 'docker://ghcr.io/cozystack/cozystack/' + grep -q 'docker://ghcr.io/cozystack/cozystack/' "$tmp/out" # Every docker:// ref in the copy plan is under the cozystack registry — no # third-party repos and no malformed arg-string refs leak through. - bad=$(echo "$output" | grep -oE 'docker://[^ ]+' | sed 's|docker://||' \ + bad=$(grep -oE 'docker://[^ ]+' "$tmp/out" | sed 's|docker://||' \ | grep -vE '^ghcr\.io/cozystack/cozystack/' || true) [ -z "$bad" ] } @test "REGISTRY override scopes the selection" { - REGISTRY="example.com/nope" run hack/promote-retag.sh v9.9.9 --dry-run + tmp=$(mktemp -d) + trap 'rm -rf "$tmp"' EXIT + # No cozystack images live under example.com/nope, so the selector finds # nothing and exits non-zero rather than silently promoting the wrong set. - [ "$status" -ne 0 ] - echo "$output" | grep -q 'No cozystack-owned digest-pinned image refs found' + # Capture the exit status without tripping the harness's `set -e`. + rc=0 + REGISTRY="example.com/nope" hack/promote-retag.sh v9.9.9 --dry-run \ + >"$tmp/out" 2>"$tmp/err" || rc=$? + + [ "$rc" -ne 0 ] + # The diagnostic is written to stderr. + grep -q 'No cozystack-owned digest-pinned image refs found' "$tmp/err" }