From 7db25b8820f3996595406c519ef32de307106c89 Mon Sep 17 00:00:00 2001 From: marcie Date: Fri, 28 Aug 2026 18:31:18 -0500 Subject: [PATCH] framework tools/git: lookup-pipeline pipefail + provider-normalization test arm (codex round on PR #1464) - issue-assign + milestone-create: set -o pipefail; the remove-assignee lookup pipeline now fails loud on provider failure instead of reading an empty result as a silent no-assignees skip (codex blocker). A successful lookup with zero assignees still skips the edit. - test-issue-assign-usage-contract: 6b arm proves provider-exit normalization end to end (gh stub exiting 2 on issue edit -> wrapper exit 1 with the normalized stderr message; codex should-fix). - Battery: 23/23 suites green. --- .../framework/tools/git/issue-assign.sh | 10 ++++++++- .../framework/tools/git/milestone-create.sh | 1 + .../git/test-issue-assign-usage-contract.sh | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/mosaic/framework/tools/git/issue-assign.sh b/packages/mosaic/framework/tools/git/issue-assign.sh index b7192005..1dad6987 100755 --- a/packages/mosaic/framework/tools/git/issue-assign.sh +++ b/packages/mosaic/framework/tools/git/issue-assign.sh @@ -3,6 +3,7 @@ # Usage: issue-assign.sh -i ISSUE_NUMBER [-a assignee] [-l labels] [-m milestone] set -e +set -o pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/detect-platform.sh" @@ -96,7 +97,14 @@ case "$PLATFORM" in fi if [[ "$REMOVE_ASSIGNEE" == true ]]; then # Get current assignees and remove them - CURRENT=$(gh issue view "$ISSUE" --json assignees -q '.assignees[].login' 2>/dev/null | tr '\n' ',') + # pipefail preserves the provider status through the pipeline; + # a FAILED lookup exits here instead of reading as a silent + # no-assignees skip (codex PR #1464). A successful lookup with + # zero assignees still skips the edit below. + CURRENT=$(gh issue view "$ISSUE" --json assignees -q '.assignees[].login' 2>/dev/null | tr '\n' ',') || { + echo "Error: could not read current assignees (provider lookup failed)" >&2 + exit 1 + } if [[ -n "$CURRENT" ]]; then prov_rc=0 gh issue edit "$ISSUE" --remove-assignee "${CURRENT%,}" || prov_rc=$? diff --git a/packages/mosaic/framework/tools/git/milestone-create.sh b/packages/mosaic/framework/tools/git/milestone-create.sh index 67202fb2..c21acfce 100755 --- a/packages/mosaic/framework/tools/git/milestone-create.sh +++ b/packages/mosaic/framework/tools/git/milestone-create.sh @@ -3,6 +3,7 @@ # Usage: milestone-create.sh -t "Title" [-d "Description"] [--due "YYYY-MM-DD"] set -e +set -o pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/detect-platform.sh" diff --git a/packages/mosaic/framework/tools/git/test-issue-assign-usage-contract.sh b/packages/mosaic/framework/tools/git/test-issue-assign-usage-contract.sh index 8eb35e0a..5c73537c 100755 --- a/packages/mosaic/framework/tools/git/test-issue-assign-usage-contract.sh +++ b/packages/mosaic/framework/tools/git/test-issue-assign-usage-contract.sh @@ -129,4 +129,26 @@ done # the arm above proves only parse acceptance and non-usage classification. # Parser-failure arms (1-4) remain zero-contact (asserted at 4b). +# 6b. Provider-exit normalization (codex PR #1464): a provider stub exiting +# 2 (its own usage-error status) must surface as wrapper exit 1, never 2. +GH_REPO="$WORK_DIR/repo-gh" +mkdir -p "$GH_REPO" +git -C "$GH_REPO" init -q +git -C "$GH_REPO" remote add origin https://github.com/acme/widgets.git +cat > "$BIN_DIR/gh" <> "$PROBE_LOG" +if [[ "\$1 \$2" == "issue edit" ]]; then exit 2; fi +exit 0 +GHSTUB +chmod +x "$BIN_DIR/gh" +rc=0 +( + cd "$GH_REPO" + PATH="$BIN_DIR:$PATH" MOSAIC_GIT_IDENTITY="" MOSAIC_BRAIN_HOME="" \ + "$SCRIPT_DIR/issue-assign.sh" -i 5 -a someone >"$OUT_FILE" 2>"$ERR_FILE" +) || rc=$? +[[ "$rc" -eq 1 ]] || fail "GitHub path: gh exit 2 must normalize to wrapper exit 1 (got $rc)" +grep -q "provider" "$ERR_FILE" || fail "GitHub path: normalized provider error missing from stderr" + echo "issue-assign.sh usage-contract regression passed (R1/R4)"