Skip to content

fix(ci): skip Claude workflows cleanly when ANTHROPIC_API_KEY is unset#7

Merged
scotthavird merged 1 commit into
mainfrom
fix/workflows-graceful-skip-without-secret
Apr 25, 2026
Merged

fix(ci): skip Claude workflows cleanly when ANTHROPIC_API_KEY is unset#7
scotthavird merged 1 commit into
mainfrom
fix/workflows-graceful-skip-without-secret

Conversation

@scotthavird
Copy link
Copy Markdown
Owner

Summary

Hardens both shipped GitHub Actions workflows (claude.yml and claude-review.yml) so that they skip cleanly when ANTHROPIC_API_KEY is not configured, rather than failing with an opaque environment-validation error. Fresh forks of this template now get green/skipped CI on PRs until the maintainer adds the secret — no red checks before any code is even written.

Closes #6

Changes

.github/workflows/claude-review.yml and claude.yml

  • Add a check-secret gate job that runs first and exposes a boolean output has_key. (Job-level if: ${{ secrets.X != '' }} isn't allowed by GitHub Actions, hence the gate-job pattern.)
  • Gate the existing responder / review job on needs.check-secret.outputs.has_key == 'true'.
  • Emit a ::notice:: annotation with actionable wording when the secret is missing: where to add it (Settings → Secrets and variables → Actions) and what name (ANTHROPIC_API_KEY).

docs/integrations.md

  • Note the graceful-skip behavior so users understand why a fresh fork shows skipped jobs.

Architecture

flowchart LR
  PR[pull_request opened/sync] --> CS[check-secret job]
  CS -->|secret set| RV[review job runs]
  CS -->|secret absent| SK[review job skipped]
  CS -.->|::notice::| MAINT[maintainer sees actionable hint]
Loading

Code Walkthrough

Why a separate gate job?

jobs:
  check-secret:
    runs-on: ubuntu-latest
    outputs:
      has_key: ${{ steps.check.outputs.has_key }}
    steps:
      - id: check
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          if [ -n "$ANTHROPIC_API_KEY" ]; then
            echo "has_key=true" >> "$GITHUB_OUTPUT"
          else
            echo "has_key=false" >> "$GITHUB_OUTPUT"
            echo "::notice::ANTHROPIC_API_KEY is not set..."
          fi

GitHub Actions intentionally restricts secrets.* evaluation in job-level if conditions to prevent secret oracling. The supported pattern is to expose the secret to a step via env:, evaluate at runtime, and propagate the result through outputs. The cost is one extra short-lived job; the benefit is that downstream jobs are skipped (which counts as success at the workflow level), not failed.

Testing

  • YAML validation: python -c "import yaml; yaml.safe_load(open('...'))" for both files.
  • End-to-end test: this PR is itself the first run of the updated workflow against a repo that doesn't (currently) have ANTHROPIC_API_KEY set. If check-secret succeeds and review is skipped on this PR, the fix is confirmed.
  • Edge case considered: claude.yml's existing @claude-mention conditional is preserved — it now ANDs with the secret-present check.

Agent Review Context

  • change-type: fix
  • risk-level: low
  • key-files: .github/workflows/claude-review.yml, .github/workflows/claude.yml
  • testing-confidence: high (YAML valid; the PR run itself is the proof)

Checklist

  • YAML syntactically valid
  • Behavior unchanged when secret IS set
  • No breaking changes
  • Docs updated (docs/integrations.md)

🤖 Generated with Claude Code

Both claude.yml (@claude mention responder) and claude-review.yml
(auto-PR review) invoke anthropics/claude-code-action@v1, which fails
with an opaque environment-validation error when the secret is missing.
A fresh fork of this template would then see red CI on every PR until
the maintainer added the secret.

Refactor both workflows into a two-job pattern:
- A check-secret gate job exposes whether ANTHROPIC_API_KEY is set
  via a job output (since `if: ${{ secrets.X != '' }}` is not allowed
  at job level).
- The downstream responder/review job is gated on that output, so it
  is skipped (not failed) when the secret is absent.
- A ::notice:: annotation tells the maintainer exactly which secret to
  add and where.

Behavior is unchanged when the secret IS set.

Refs #6
AI-Tool: claude-code
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scotthavird scotthavird merged commit d58ecbb into main Apr 25, 2026
2 checks passed
@scotthavird scotthavird deleted the fix/workflows-graceful-skip-without-secret branch April 25, 2026 00:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Workflows fail on forks without ANTHROPIC_API_KEY — should skip cleanly

1 participant