Skip to content
12 changes: 11 additions & 1 deletion .github/workflows/ci-failure-analyst-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,18 @@ jobs:
TMPL

PROMPT=$(envsubst < /tmp/prompt-template.txt)
_analyst_out=$(mktemp)
_analyst_rc=0
claude --print \
--permission-mode bypassPermissions \
--allowedTools Bash \
--fallback-model opus \
-p "$PROMPT"
-p "$PROMPT" 2>&1 | tee "$_analyst_out" || _analyst_rc=${PIPESTATUS[0]}
Comment thread
don-petry marked this conversation as resolved.
Resolved
if [ "$_analyst_rc" -ne 0 ] && \
grep -qiE "hit your.*(session )?limit|rate.?limit|session limit|usage limit|quota exceeded|too many requests" "$_analyst_out"; then
echo "::notice::Claude rate-limited — skipping CI analysis for PR #${PR_NUMBER} (will retry on next CI failure)"
rm -f "$_analyst_out"
exit 0
fi
rm -f "$_analyst_out"
exit "$_analyst_rc"
14 changes: 11 additions & 3 deletions .github/workflows/issue-triage-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ jobs:
persist-credentials: false

- name: Install claude CLI
uses: anthropics/claude-code-action/setup@787c5a0ce96a9a6cfb050ea0c8f4c05f2447c251 # main
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
env:
CLAUDE_CODE_VERSION: ${{ vars.CLAUDE_CODE_VERSION || 'latest' }}
run: |
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.npm-global/bin:$PATH"
if ! command -v claude >/dev/null 2>&1; then
npm install -g "@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}"
fi

- name: Install Python dependencies
run: |
Expand All @@ -35,6 +42,7 @@ jobs:
- name: Run issue-triage (staged)
id: run
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
Expand Down
4 changes: 4 additions & 0 deletions scripts/engine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,10 @@ run_writer_with_fallback() {
echo "::warning::Skipping copilot fallback: classic PAT in COPILOT_GITHUB_TOKEN is unsupported" >&2
continue
fi
if [ "$engine" = "gemini" ] && [ -z "${GEMINI_API_KEY:-}${GOOGLE_API_KEY:-}" ]; then
echo "::warning::Skipping gemini fallback: GEMINI_API_KEY or GOOGLE_API_KEY not configured" >&2
Comment thread
don-petry marked this conversation as resolved.
Resolved
continue
Comment thread
don-petry marked this conversation as resolved.
Resolved
fi
Comment thread
don-petry marked this conversation as resolved.
Resolved

local saved="$REVIEW_ENGINE"
export REVIEW_ENGINE="$engine"
Expand Down
41 changes: 41 additions & 0 deletions tests/dev-lead/unit/test_engine_fallback.bats
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ setup() {
export TEST_PROMPT

export DEV_LEAD_DRY_RUN="false"
export GEMINI_API_KEY="dummy-test-key"
}

teardown() {
Expand Down Expand Up @@ -196,3 +197,43 @@ GHEOF
[ -s "$record_file" ]
rm -f "$record_file"
}

@test "fallback: gemini skipped when no auth env vars set → falls through to copilot" {
# claude exits 2 (rate-limited), no GEMINI_API_KEY/GOOGLE_API_KEY set.
# gemini should be skipped entirely (not called); copilot should succeed.
_make_stub "claude" 2
local gemini_record
gemini_record="$(mktemp)"
_make_recording_stub "gemini" 1 "$gemini_record"
unset GEMINI_API_KEY GOOGLE_API_KEY 2>/dev/null || true
export COPILOT_GITHUB_TOKEN="stub-token"
cat > "$STUB_BIN_DIR/gh" <<'GHEOF'
#!/usr/bin/env bash
case "$*" in
*"copilot"*) echo "success output"; exit 0 ;;
*) echo "{}" ;;
esac
GHEOF
chmod +x "$STUB_BIN_DIR/gh"
_source_engine "claude"

run run_writer_with_fallback "$TEST_PROMPT"

[ "$status" -eq 0 ]
# gemini must NOT have been called (file should be empty)
[ ! -s "$gemini_record" ]
rm -f "$gemini_record"
}

@test "fallback: gemini used normally when GEMINI_API_KEY is set" {
# claude exits 2 (rate-limited), GEMINI_API_KEY is set → gemini should be tried and succeed
_make_stub "claude" 2
_make_stub "gemini" 0
export GEMINI_API_KEY="test-api-key"
_source_engine "claude"

run run_writer_with_fallback "$TEST_PROMPT"

[ "$status" -eq 0 ]
unset GEMINI_API_KEY
}
1 change: 1 addition & 0 deletions tests/dev-lead/unit/test_engine_writer.bats
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ setup() {
echo "test prompt content" > "$TEST_PROMPT"
export TEST_PROMPT
export STUB_BIN_DIR
export GEMINI_API_KEY="dummy-test-key"
}

teardown() {
Expand Down
Loading