From 46a8423ce37d6fa8c8ed710c736b72961621ed0e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 22 Sep 2026 06:52:18 +0000 Subject: [PATCH] ci: fail closed when e2e ref lookup is not a missing branch git ls-remote --exit-code returns 2 only when the ref is absent. DNS, auth, and other transport errors were taking the missing-branch path, so a blip could silently run CI against main. Re-resolve inside migration-wallet-setup immediately before checkout so a failed-job rerun does not reuse a stale companion ref. Co-authored-by: piotr-iohk --- .github/actions/resolve-e2e-ref/action.yml | 45 +++++++++++++++----- .github/workflows/determine-e2e-branch.yml | 31 +++++++++++++- .github/workflows/migration-wallet-setup.yml | 20 ++++++++- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/.github/actions/resolve-e2e-ref/action.yml b/.github/actions/resolve-e2e-ref/action.yml index e4e04a75..f57030f2 100644 --- a/.github/actions/resolve-e2e-ref/action.yml +++ b/.github/actions/resolve-e2e-ref/action.yml @@ -6,6 +6,11 @@ description: "Re-validate the determined e2e branch immediately before checkout" # the companion may be deleted later, or "Re-run failed jobs" may reuse the # old determine output. Shard jobs (including macos) should call this right # before checking out synonymdev/bitkit-e2e-tests. +# +# git ls-remote --exit-code returns 2 when no ref matches. DNS, auth, and +# other transport failures return a different status (typically 128) and must +# fail this step. Treating them as "branch missing" would silently test the +# fallback branch. inputs: selected: @@ -51,18 +56,36 @@ runs: # 1. Empty or already the fallback — nothing to re-validate. if [[ -z "$SELECTED" || "$SELECTED" == "$FALLBACK" ]]; then REF="$FALLBACK" - # 2. Companion still exists — use it. - elif git ls-remote --exit-code https://github.com/$TEST_REPO.git "refs/heads/$SELECTED" >/dev/null 2>&1; then - REF="$SELECTED" - echo "✅ Found selected branch: $REF" - # 3. Explicit custom branch is gone — fail hard (do not silently switch). - elif [[ -n "$E2E_BRANCH_INPUT" && "$E2E_BRANCH_INPUT" != "main" && "$E2E_BRANCH_INPUT" != "default-feature-branch" ]]; then - echo "::error title=Invalid e2e_branch::Branch '$SELECTED' not found in $TEST_REPO" - exit 1 - # 4. Default companion path — soft-fallback (deleted after determine, or stale re-run). else - echo "::warning title=Missing e2e companion::Branch '$SELECTED' not found in $TEST_REPO, using '$FALLBACK'." - REF="$FALLBACK" + # stdout is the matching SHA; keep stderr for the failure reason. + # --exit-code: 0 = ref exists, 2 = no matching ref. Anything else + # (DNS, auth, missing repo) must not take the missing-branch path. + err_file="$(mktemp)" + ls_status=0 + git ls-remote --exit-code "https://github.com/${TEST_REPO}.git" "refs/heads/${SELECTED}" >/dev/null 2>"$err_file" || ls_status=$? + + if [[ "$ls_status" -eq 0 ]]; then + REF="$SELECTED" + echo "✅ Found selected branch: $REF" + elif [[ "$ls_status" -ne 2 ]]; then + if [[ -s "$err_file" ]]; then + echo "git ls-remote stderr:" + cat "$err_file" + fi + echo "::error title=E2E ref lookup failed::git ls-remote exited ${ls_status} looking up '${SELECTED}' in ${TEST_REPO}. Refusing to fall back to '${FALLBACK}'." + rm -f "$err_file" + exit 1 + # Explicit custom branch is gone — fail hard (do not silently switch). + elif [[ -n "$E2E_BRANCH_INPUT" && "$E2E_BRANCH_INPUT" != "main" && "$E2E_BRANCH_INPUT" != "default-feature-branch" ]]; then + echo "::error title=Invalid e2e_branch::Branch '$SELECTED' not found in $TEST_REPO" + rm -f "$err_file" + exit 1 + # Default companion path — soft-fallback (deleted after determine, or stale re-run). + else + echo "::warning title=Missing e2e companion::Branch '$SELECTED' not found in $TEST_REPO, using '$FALLBACK'." + REF="$FALLBACK" + fi + rm -f "$err_file" fi echo "🧭 Effective ref: $REF" diff --git a/.github/workflows/determine-e2e-branch.yml b/.github/workflows/determine-e2e-branch.yml index 26f2702f..86ccbb5b 100644 --- a/.github/workflows/determine-e2e-branch.yml +++ b/.github/workflows/determine-e2e-branch.yml @@ -54,10 +54,35 @@ jobs: echo "🧭 Base branch: $BASE_BRANCH" echo "🧭 Checking repo: $TEST_REPO" + # --exit-code: 0 = ref exists, 2 = no matching ref. Any other status + # is a transport/auth failure. resolve-e2e-ref treats "main" as + # already settled, so a swallowed lookup error here would check out + # the base branch for the rest of the run. + ref_lookup_status() { + local ref="$1" + local err_file + local status=0 + err_file="$(mktemp)" + git ls-remote --exit-code "https://github.com/${TEST_REPO}.git" "refs/heads/${ref}" >/dev/null 2>"$err_file" || status=$? + if [[ "$status" -ne 0 && "$status" -ne 2 ]]; then + if [[ -s "$err_file" ]]; then + echo "git ls-remote stderr:" + cat "$err_file" + fi + echo "::error title=E2E ref lookup failed::git ls-remote exited ${status} looking up '${ref}' in ${TEST_REPO}. Not treating this as a missing branch." + rm -f "$err_file" + exit 1 + fi + rm -f "$err_file" + return "$status" + } + if [[ "$INPUT_BRANCH" == "main" ]]; then BRANCH="main" elif [[ "$INPUT_BRANCH" == "default-feature-branch" ]]; then - if git ls-remote --exit-code https://github.com/$TEST_REPO.git "refs/heads/$APP_BRANCH" >/dev/null 2>&1; then + lookup_status=0 + ref_lookup_status "$APP_BRANCH" || lookup_status=$? + if [[ "$lookup_status" -eq 0 ]]; then BRANCH="$APP_BRANCH" echo "✅ Found matching branch: $BRANCH" else @@ -65,7 +90,9 @@ jobs: echo "⚠️ No '$APP_BRANCH' branch in $TEST_REPO, using '$BASE_BRANCH'." fi else - if git ls-remote --exit-code https://github.com/$TEST_REPO.git "refs/heads/$INPUT_BRANCH" >/dev/null 2>&1; then + lookup_status=0 + ref_lookup_status "$INPUT_BRANCH" || lookup_status=$? + if [[ "$lookup_status" -eq 0 ]]; then BRANCH="$INPUT_BRANCH" else echo "::error title=Invalid e2e_branch::Branch '$INPUT_BRANCH' not found in $TEST_REPO" diff --git a/.github/workflows/migration-wallet-setup.yml b/.github/workflows/migration-wallet-setup.yml index e1711f3a..a1223640 100644 --- a/.github/workflows/migration-wallet-setup.yml +++ b/.github/workflows/migration-wallet-setup.yml @@ -1,12 +1,21 @@ name: Migration Wallet Setup +# Checkout re-validates e2e_branch in this job. A caller-side resolve that +# already succeeded is skipped on "Re-run failed jobs", so a companion deleted +# after that resolve would otherwise be reused until checkout fails again. + on: workflow_call: inputs: e2e_branch: - description: "Branch of synonymdev/bitkit-e2e-tests to use" + description: "Candidate bitkit-e2e-tests branch to re-validate immediately before checkout. Pass determine-e2e-branch's output, or a previously resolved ref." required: true type: string + e2e_branch_input: + description: "How the candidate was chosen (main | default-feature-branch | custom branch name). A missing companion soft-falls back to main. An explicit custom name hard-fails. Defaults to default-feature-branch so callers that only pass e2e_branch keep that soft-fallback. Pass the same dispatch value when it is a custom branch." + required: false + type: string + default: "default-feature-branch" rn_version: description: "Legacy RN app version to use for setup (e.g., v1.1.6)" required: false @@ -30,12 +39,19 @@ jobs: runs-on: ubuntu-latest steps: + - name: Resolve E2E tests ref + id: e2e-ref + uses: synonymdev/bitkit-e2e-tests/.github/actions/resolve-e2e-ref@main + with: + selected: ${{ inputs.e2e_branch }} + e2e_branch_input: ${{ inputs.e2e_branch_input }} + - name: Clone E2E tests uses: actions/checkout@v4 with: repository: synonymdev/bitkit-e2e-tests path: bitkit-e2e-tests - ref: ${{ inputs.e2e_branch }} + ref: ${{ steps.e2e-ref.outputs.ref }} - name: Enable KVM run: |