From bf32f29acd3ae1c0c461bdfb1fa85a24291ee8e2 Mon Sep 17 00:00:00 2001 From: mos-dt-0 Date: Mon, 10 Aug 2026 20:54:09 +0000 Subject: [PATCH] fix(ci): make queue guard purpose-sensitive (#1148) --- .../2026-08-10-ci-queue-purpose-design.md | 33 +++ ...6-08-10-ci-queue-purpose-implementation.md | 208 ++++++++++++++++++ docs/scratchpads/1146-ci-queue-purpose.md | 65 ++++++ .../framework/tools/git/ci-queue-wait.sh | 18 +- .../mosaic/framework/tools/git/pr-merge.sh | 4 +- .../git/test-ci-queue-wait-github-checks.sh | 18 +- .../tools/git/test-ci-queue-wait-tristate.sh | 28 ++- .../tools/git/test-pr-merge-head-pin.sh | 7 +- 8 files changed, 356 insertions(+), 25 deletions(-) create mode 100644 docs/plans/2026-08-10-ci-queue-purpose-design.md create mode 100644 docs/plans/2026-08-10-ci-queue-purpose-implementation.md create mode 100644 docs/scratchpads/1146-ci-queue-purpose.md diff --git a/docs/plans/2026-08-10-ci-queue-purpose-design.md b/docs/plans/2026-08-10-ci-queue-purpose-design.md new file mode 100644 index 00000000..ce56c668 --- /dev/null +++ b/docs/plans/2026-08-10-ci-queue-purpose-design.md @@ -0,0 +1,33 @@ +# CI Queue Guard Purpose Semantics + +- **Issue:** #1146 +- **Target branch:** `next` + +## Problem + +`ci-queue-wait.sh` treats any result other than terminal success as asserted non-readiness. That is correct for merge readiness, but incorrect for the pre-push queue guard: a terminal failure or an empty status set means no pipeline is queued or running, so the queue is clear. + +## Design + +Make final-state handling purpose-sensitive while preserving the existing provider and payload safeguards: + +- `--purpose push` + - wait while state is `pending`; + - return success for `terminal-success`, `terminal-failure`, and `no-status`; + - continue rejecting `malformed`, `unknown`, and unrecognized states. +- `--purpose merge` + - return success only for `terminal-success`; + - continue rejecting `terminal-failure`, `no-status`, malformed, unknown, and unrecognized states. +- `--require-status` remains authoritative: `no-status` fails for either purpose when it is supplied. + +Diagnostics will explicitly distinguish a queue-clear push result from successful CI so callers cannot mistake an old failure for a green pipeline. + +## Testing + +Extend the process-level tri-state regression harness with separate push and merge assertions: + +1. Push passes for terminal success, terminal failure, and no status. +2. Push still fails for pending, malformed, and unknown states. +3. `--require-status` makes push/no-status fail. +4. Merge behavior remains fail-closed except for terminal success. +5. Existing provider-unavailable audit behavior remains unchanged. diff --git a/docs/plans/2026-08-10-ci-queue-purpose-implementation.md b/docs/plans/2026-08-10-ci-queue-purpose-implementation.md new file mode 100644 index 00000000..b46d0671 --- /dev/null +++ b/docs/plans/2026-08-10-ci-queue-purpose-implementation.md @@ -0,0 +1,208 @@ +# CI Queue Guard Purpose Semantics Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Make the pre-push CI queue guard pass when no pipeline is queued or running while preserving fail-closed merge readiness. + +**Architecture:** Keep provider lookup and tri-state classification unchanged. Make only the final state dispatch purpose-sensitive: push treats valid non-pending states as queue-clear, while merge continues to require terminal success. Preserve `--require-status`, malformed-payload rejection, unknown-state rejection, and audited provider-unavailable behavior. + +**Tech Stack:** Bash, process-level shell regression harnesses, Gitea/GitHub status APIs. + +--- + +### Task 1: Freeze Purpose-Specific State Semantics + +**Files:** + +- Modify: `packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh` +- Test: `packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh` + +**Step 1: Add failing push assertions** + +Change push expectations so `terminal-failure` and `no-status` require exit 0 plus an explicit `queue-clear` diagnostic. Add a `--require-status` assertion that keeps push/no-status non-zero. + +**Step 2: Add failing merge assertions** + +Invoke the same harness with `MOSAIC_TEST_PURPOSE=merge` and assert terminal failure and no status remain non-zero while terminal success remains zero. + +**Step 3: Add unknown-state coverage** + +Add a stub payload with a syntactically valid but unsupported status value and assert both purposes reject it. + +**Step 4: Run the focused test and verify RED** + +Run: + +```bash +bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +``` + +Expected: failures showing push terminal-failure and no-status returned exit 3 instead of exit 0 or lacked `queue-clear` diagnostics. + +**Step 5: Commit the failing tests** + +```bash +git add packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +git commit -m "test(ci): define purpose-aware queue readiness" +``` + +### Task 2: Implement Purpose-Sensitive Final-State Dispatch + +**Files:** + +- Modify: `packages/mosaic/framework/tools/git/ci-queue-wait.sh:458-481` +- Test: `packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh` +- Test: `packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh` + +**Step 1: Implement push queue-clear behavior** + +For `no-status`, retain the existing `--require-status` failure. Otherwise, return success for push with an explicit diagnostic such as: + +```text +[ci-queue-wait] queue-clear state=no-status purpose=push branch=; no queued or running CI. +``` + +For `terminal-failure`, return success only for push with the same queue-clear wording. Merge must continue returning asserted non-readiness. + +**Step 2: Preserve malformed and unknown rejection** + +Keep `malformed`, `unknown`, and unrecognized states non-zero for both purposes. + +**Step 3: Run focused tests and verify GREEN** + +Run: + +```bash +bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +bash packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh +``` + +Expected: both scripts exit 0 and report their regression suites passed. + +**Step 4: Commit implementation** + +```bash +git add packages/mosaic/framework/tools/git/ci-queue-wait.sh +git commit -m "fix(ci): separate push queue clearance from merge readiness" +``` + +### Task 3: Verify, Review, and Document Evidence + +**Files:** + +- Modify: `docs/scratchpads/1146-ci-queue-purpose.md` + +**Step 1: Run shell syntax and focused regressions** + +```bash +bash -n packages/mosaic/framework/tools/git/ci-queue-wait.sh +bash -n packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +bash packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh +``` + +**Step 2: Run repository quality gates** + +```bash +pnpm preflight +pnpm typecheck +pnpm lint +pnpm test +pnpm format:check +``` + +Expected: every command exits 0. + +**Step 3: Obtain independent review** + +Request review of the exact branch head. Remediate all blocking findings and rerun focused and baseline gates. + +**Step 4: Record evidence and commit** + +Update the scratchpad with test output, review result, and residual risk, then commit it: + +```bash +git add docs/scratchpads/1146-ci-queue-purpose.md +git commit -m "docs(ci): record queue guard verification" +``` + +### Task 4: Keep the Merge Wrapper Aligned with the `next` Lane + +**Files:** + +- Modify: `packages/mosaic/framework/tools/git/pr-merge.sh:97-101` +- Test: `packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh` + +**Step 1: Write the failing regression** + +Run the exact-head merge regression with its Gitea fixture targeting `next` and confirm the current wrapper rejects it because it only permits `main`. + +**Step 2: Allow only documented integration targets** + +Permit `main` and `next`; reject every other target. Do not alter exact-head pinning, queue-guard invocation, provider selection, or merge method enforcement. + +**Step 3: Run focused merge regressions** + +```bash +bash packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh +bash packages/mosaic/framework/tools/git/test-pr-merge-queue-branch.sh +bash packages/mosaic/framework/tools/git/test-pr-merge-gitea-empty-uid.sh +``` + +Expected: all pass, including a Gitea merge fixture targeting `next`. + +**Step 4: Commit** + +```bash +git add packages/mosaic/framework/tools/git/pr-merge.sh packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh +git commit -m "fix(ci): allow reviewed merges into next" +``` + +### Task 5: Activate and Deliver Through `next` + +**Files:** + +- Installed output: `~/.config/mosaic/tools/git/ci-queue-wait.sh` + +**Step 1: Activate through the canonical installer** + +From the reviewed worktree, run the framework installer in sync-only keep mode so operator files remain protected: + +```bash +MOSAIC_SYNC_ONLY=1 MOSAIC_INSTALL_MODE=keep MOSAIC_SKIP_SKILLS_SYNC=1 \ + bash packages/mosaic/framework/install.sh +``` + +**Step 2: Verify installed/source parity** + +```bash +cmp -s \ + packages/mosaic/framework/tools/git/ci-queue-wait.sh \ + ~/.config/mosaic/tools/git/ci-queue-wait.sh +``` + +Expected: exit 0. + +**Step 3: Run mandatory pre-push queue guard** + +```bash +~/.config/mosaic/tools/git/ci-queue-wait.sh --purpose push -B fix/1146-ci-queue-purpose +``` + +Expected: branch-absent or queue-clear success. + +**Step 4: Push and open a PR against `next`** + +```bash +git push -u origin fix/1146-ci-queue-purpose +~/.config/mosaic/tools/git/pr-create.sh \ + -t "fix(ci): make queue guard purpose-sensitive" \ + -b "Closes #1146" \ + -B next \ + -H fix/1146-ci-queue-purpose \ + -i 1146 +``` + +**Step 5: Complete reviewed integration** + +Wait for exact-head terminal-green CI, obtain the required review, merge via the Mosaic wrapper, verify merged CI, and close #1146. Do not bypass any gate. diff --git a/docs/scratchpads/1146-ci-queue-purpose.md b/docs/scratchpads/1146-ci-queue-purpose.md new file mode 100644 index 00000000..e9402d6f --- /dev/null +++ b/docs/scratchpads/1146-ci-queue-purpose.md @@ -0,0 +1,65 @@ +# #1146 — CI Queue Guard Purpose Semantics + +## Objective + +Make the pre-push queue guard wait for queued/running CI without requiring the previous remote head to have successful CI. Preserve fail-closed merge readiness. + +## Scope + +- `packages/mosaic/framework/tools/git/ci-queue-wait.sh` +- focused queue-guard regression tests +- design and scratchpad documentation +- local framework activation required before the fixed guard can authorize this branch's push + +## Plan + +1. Freeze purpose-specific behavior in failing process-level tests. +2. Implement the smallest state-dispatch change. +3. Run focused shell tests and repository quality gates. +4. Obtain independent review and remediate findings. +5. Install the reviewed framework source locally, run the mandatory pre-push queue guard, and push. +6. Open a PR against `next`, verify terminal-green CI, and close #1146 after merge. + +## Budget + +- ASSUMPTION: no explicit token cap was provided. +- Working estimate: 12K tokens. +- Scope reduction: change only final-state dispatch and focused tests; do not redesign provider adapters. + +## Progress + +- Confirmed source and installed guards are byte-identical. +- Reproduced `terminal-failure` blocking `--purpose push`. +- Root cause: final-state dispatch requires terminal success for both push and merge. +- Design approved: push is queue-clear on valid non-pending states; merge remains fail-closed. + +## Tests + +- RED confirmed before implementation: the focused tri-state harness reported push `terminal-failure` and `no-status` as `ASSERTED_NOT_READY`. +- GREEN: `bash packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh` — all outcome classes passed. +- GREEN: `bash packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh` — 6/6 purpose-aware cases passed. +- GREEN: `bash -n` passed for the changed guard and both focused harnesses. +- GREEN: `pnpm preflight`, `pnpm typecheck`, and `pnpm lint` passed. +- `pnpm test` ran 45/46 workspace test tasks successfully, but the pre-existing Gateway `cross-user-isolation.test.ts` failed during cleanup with PostgreSQL error `28P01` (local `mosaic` password authentication failure). The changed Mosaic framework test task passed within that run. +- GREEN: focused queue and merge shell regressions passed after the wrapper change. +- GREEN: isolated Mosaic Vitest run passed (81 files, 1,514 tests). +- The normal parallel Mosaic Vitest run has an environment-sensitive pre-existing failure in `install-ordering-guard.spec.ts`: the real activation probe changes between two calls while other suites run concurrently. Running the same spec alone and the complete Vitest suite with one fork passes. +- The framework shell suite's pre-existing `version_coupling_unittest.py` also fails locally because the newly installed `mosaic` is now on PATH despite the test injecting a nonexistent PATH; CI's clean image does not have this global CLI. All changed queue/merge harnesses pass. +- GREEN: `pnpm format:check` passed. +- Note: an additional ad hoc Prettier command was not applicable to shell files because Prettier has no shell parser; the repository-wide format check passed using its configured file globs. + +## Review + +- Independent Codex review of the six-file diff: approved, confidence 0.84, zero blockers/should-fix/suggestions. +- Review confirmed push queue-clear behavior, merge fail-closed behavior, and `--require-status` coverage. + +## Risks and Blockers + +- Canonical framework activation completed with `MOSAIC_SYNC_ONLY=1 MOSAIC_INSTALL_MODE=keep MOSAIC_SKIP_SKILLS_SYNC=1 bash packages/mosaic/framework/install.sh`. +- Source and installed queue guards are byte-identical (`cmp` and SHA-256 parity passed). +- The installed pre-push guard now passes for the not-yet-remote feature branch with `queue clear`. +- The required merge wrapper then exposed a second bootstrap defect: `pr-merge.sh` hardcoded `main`, contradicting the documented PR-based `next` integration lane. Tracked as #1149 and fixed in the same delivery branch with a regression fixture targeting `next`. +- Activation emitted the existing manifest-safety warning that six `fleet/run/*.hb*` operator files were touched then restored; no data loss was observed, but this remains a pre-existing framework-manifest defect to report separately. +- The first activation attempt timed out after 600 seconds while copying the 113K-file operator snapshot; the bounded 1,800-second retry completed successfully. It left a partial durable snapshot from the interrupted attempt in the normal backup directory; the completed snapshot is the newer `pre-update-20260810T195317Z` entry. +- Full baseline test completion is blocked by the unrelated local PostgreSQL authentication/cleanup failure described above; CI has its own disposable PostgreSQL service. +- Existing `.mosaic/orchestrator/*` working-tree changes are unrelated and must remain unstaged. diff --git a/packages/mosaic/framework/tools/git/ci-queue-wait.sh b/packages/mosaic/framework/tools/git/ci-queue-wait.sh index d4f49b87..f38be51e 100755 --- a/packages/mosaic/framework/tools/git/ci-queue-wait.sh +++ b/packages/mosaic/framework/tools/git/ci-queue-wait.sh @@ -465,12 +465,24 @@ while true; do no-status) if [[ "$REQUIRE_STATUS" -eq 1 ]]; then echo "Error: ASSERTED_NOT_READY state=no-status; --require-status was set for ${BRANCH}." >&2 - else - echo "Error: ASSERTED_NOT_READY state=no-status purpose=${PURPOSE} branch=${BRANCH}." >&2 + exit 3 fi + if [[ "$PURPOSE" == "push" ]]; then + echo "[ci-queue-wait] queue-clear state=no-status purpose=push branch=${BRANCH}; no queued or running CI." + exit 0 + fi + echo "Error: ASSERTED_NOT_READY state=no-status purpose=${PURPOSE} branch=${BRANCH}." >&2 exit 3 ;; - terminal-failure|malformed|unknown) + terminal-failure) + if [[ "$PURPOSE" == "push" ]]; then + echo "[ci-queue-wait] queue-clear state=terminal-failure purpose=push branch=${BRANCH}; no queued or running CI." + exit 0 + fi + echo "Error: ASSERTED_NOT_READY state=terminal-failure purpose=${PURPOSE} branch=${BRANCH}." >&2 + exit 3 + ;; + malformed|unknown) echo "Error: ASSERTED_NOT_READY state=${STATE} purpose=${PURPOSE} branch=${BRANCH}." >&2 exit 3 ;; diff --git a/packages/mosaic/framework/tools/git/pr-merge.sh b/packages/mosaic/framework/tools/git/pr-merge.sh index 403ac056..1898d5dd 100755 --- a/packages/mosaic/framework/tools/git/pr-merge.sh +++ b/packages/mosaic/framework/tools/git/pr-merge.sh @@ -94,8 +94,8 @@ BASE_BRANCH="$(printf '%s' "$PR_METADATA" | python3 -c 'import json, sys; print( HEAD_BRANCH="$(printf '%s' "$PR_METADATA" | python3 -c 'import json, sys; print((json.load(sys.stdin).get("headRefName") or "").strip())')" HEAD_SHA="$(printf '%s' "$PR_METADATA" | python3 -c 'import json, sys; print((json.load(sys.stdin).get("headRefOid") or "").strip())')" HEAD_REPO="$(printf '%s' "$PR_METADATA" | python3 -c 'import json, sys; value=json.load(sys.stdin).get("headRepository") or ""; print((value.get("nameWithOwner") or value.get("full_name") or "") if isinstance(value, dict) else str(value).strip())')" -if [[ "$BASE_BRANCH" != "main" ]]; then - echo "Error: Mosaic policy allows merges only for PRs targeting 'main' (found '$BASE_BRANCH')." >&2 +if [[ "$BASE_BRANCH" != "main" && "$BASE_BRANCH" != "next" ]]; then + echo "Error: Mosaic policy allows merges only for PRs targeting 'main' or 'next' (found '$BASE_BRANCH')." >&2 exit 1 fi diff --git a/packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh b/packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh index d063f12b..84173fd7 100644 --- a/packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh +++ b/packages/mosaic/framework/tools/git/test-ci-queue-wait-github-checks.sh @@ -43,22 +43,22 @@ SH chmod +x "$STUB_DIR/gh" run_guard() { - local mode="$1" + local mode="$1" purpose="${2:-push}" ( cd "$REPO_DIR" || exit export PATH="$STUB_DIR:$PATH" export MOSAIC_GH_CHECK_MODE="$mode" export MOSAIC_GH_CALL_LOG="$WORK_DIR/gh-calls.log" export MOSAIC_CI_QUEUE_AUDIT_LOG="$WORK_DIR/audit.jsonl" - "$SCRIPT_DIR/ci-queue-wait.sh" --purpose push -t 0 -i 0 + "$SCRIPT_DIR/ci-queue-wait.sh" --purpose "$purpose" -t 0 -i 0 ) } failures=0 assert_case() { - local mode="$1" expected_rc="$2" expected_state="$3" output rc + local mode="$1" expected_rc="$2" expected_state="$3" purpose="${4:-push}" output rc set +e - output=$(run_guard "$mode" 2>&1) + output=$(run_guard "$mode" "$purpose" 2>&1) rc=$? set -e if [[ "$expected_rc" == zero && "$rc" -ne 0 ]]; then @@ -79,10 +79,12 @@ set -e : > "$WORK_DIR/gh-calls.log" assert_case success zero terminal-success assert_case pending nonzero pending -assert_case failure nonzero terminal-failure -assert_case late-failure nonzero terminal-failure +assert_case failure zero terminal-failure +assert_case late-failure zero terminal-failure +assert_case failure nonzero terminal-failure merge +assert_case late-failure nonzero terminal-failure merge -if [[ $(grep -c 'check-runs?per_page=100&filter=latest' "$WORK_DIR/gh-calls.log") -lt 4 ]]; then +if [[ $(grep -c 'check-runs?per_page=100&filter=latest' "$WORK_DIR/gh-calls.log") -lt 6 ]]; then echo "FAIL: expected every case to query all Checks API pages" >&2 failures=$((failures + 1)) fi @@ -92,4 +94,4 @@ if [[ "$failures" -ne 0 ]]; then exit 1 fi -echo "GitHub check-runs regression passed (4/4 cases, including later-page failure)" +echo "GitHub check-runs regression passed (6/6 purpose-aware cases, including later-page failure)" diff --git a/packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh b/packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh index 35ea0aee..2ff0465b 100644 --- a/packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh +++ b/packages/mosaic/framework/tools/git/test-ci-queue-wait-tristate.sh @@ -53,6 +53,7 @@ case "$url" in malformed) printf '%s' 'not-json' ;; malformed-statuses-type) printf '%s' '{"state":"success","statuses":"corrupt"}' ;; malformed-status-entry) printf '%s' '{"state":"success","statuses":[null]}' ;; + unknown) printf '%s' '{"state":"success","statuses":[{"status":"cancelled"}]}' ;; large-success) python3 -c 'import json; print(json.dumps({"state":"success", "statuses":[{"status":"success"}], "padding":"x" * (160 * 1024)}), end="")' ;; @@ -128,18 +129,27 @@ run_assertion() { set -e : > "$WORK_DIR/urls.log" -run_assertion success zero success 'state=terminal-success' -run_assertion pending nonzero pending 'ASSERTED_NOT_READY' -run_assertion failure nonzero failure 'ASSERTED_NOT_READY' -run_assertion no-status nonzero no-status 'ASSERTED_NOT_READY' -run_assertion aggregate-success-no-status nonzero aggregate-success-no-status 'ASSERTED_NOT_READY' -run_assertion malformed nonzero malformed 'ASSERTED_NOT_READY' -run_assertion malformed-statuses-type nonzero malformed-statuses-type 'ASSERTED_NOT_READY' -run_assertion malformed-status-entry nonzero malformed-status-entry 'ASSERTED_NOT_READY' -run_assertion large-payload not126 large-success 'state=terminal-success' +# Push readiness is queue clearance, not proof that prior CI succeeded. +run_assertion push-success zero success 'state=terminal-success' +run_assertion push-pending nonzero pending 'ASSERTED_NOT_READY' +run_assertion push-failure zero failure 'queue-clear state=terminal-failure purpose=push' +run_assertion push-no-status zero no-status 'queue-clear state=no-status purpose=push' +run_assertion push-aggregate-success-no-status zero aggregate-success-no-status 'queue-clear state=no-status purpose=push' +run_assertion push-require-status nonzero no-status 'ASSERTED_NOT_READY state=no-status' --require-status +run_assertion push-malformed nonzero malformed 'ASSERTED_NOT_READY' +run_assertion push-malformed-statuses-type nonzero malformed-statuses-type 'ASSERTED_NOT_READY' +run_assertion push-malformed-status-entry nonzero malformed-status-entry 'ASSERTED_NOT_READY' +run_assertion push-unknown nonzero unknown 'ASSERTED_NOT_READY' +run_assertion push-large-payload not126 large-success 'state=terminal-success' run_assertion credential-unresolvable zero credential-unresolvable 'CANNOT_ASSERT' run_assertion provider-unreachable zero unreachable 'CANNOT_ASSERT' +# Merge readiness remains fail-closed and requires exact-head terminal success. +MOSAIC_TEST_PURPOSE=merge run_assertion merge-success zero success 'state=terminal-success' +MOSAIC_TEST_PURPOSE=merge run_assertion merge-failure nonzero failure 'ASSERTED_NOT_READY state=terminal-failure' +MOSAIC_TEST_PURPOSE=merge run_assertion merge-no-status nonzero no-status 'ASSERTED_NOT_READY state=no-status' +MOSAIC_TEST_PURPOSE=merge run_assertion merge-unknown nonzero unknown 'ASSERTED_NOT_READY state=unknown' + if [[ ! -s "$AUDIT_LOG" ]] || ! grep -q '"outcome":"CANNOT_ASSERT"' "$AUDIT_LOG"; then echo "FAIL provider-unreachable-audit: expected durable CANNOT_ASSERT JSONL record" >&2 failures=$((failures + 1)) diff --git a/packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh b/packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh index 0eec10f0..3d023619 100644 --- a/packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh +++ b/packages/mosaic/framework/tools/git/test-pr-merge-head-pin.sh @@ -17,9 +17,10 @@ make_fixture() { cp "$SCRIPT_DIR/detect-platform.sh" "$tools/detect-platform.sh" git -C "$root/repo" init -q git -C "$root/repo" remote add origin "$remote" + local base_branch="${3:-main}" cat > "$tools/pr-metadata.sh" < "$tools/ci-queue-wait.sh" <<'SH' #!/usr/bin/env bash @@ -29,8 +30,8 @@ SH } rm -rf "$WORK_DIR" -make_fixture gitea https://git.example.test/acme/widgets.git -make_fixture github https://github.com/acme/widgets.git +make_fixture gitea https://git.example.test/acme/widgets.git next +make_fixture github https://github.com/acme/widgets.git main cat > "$WORK_DIR/gitea/curl" <<'SH' #!/usr/bin/env bash