Files
star-map/.github/workflows/junie-review.yml
Claude 4d5e3a9914 Let the Junie review skip rather than fail without a key
The workflow as written failed on ddf805e: with no JUNIE_API_KEY secret the
input expands to empty and the action exits on "Missing required input",
marking the pull request failed for a reason that has nothing to do with its
code. I called it inert without the key. It was not inert; it was red, and it
would have been red on every pull request until someone added the secret.

So gate the steps on the key's presence and write the reason into the run
summary instead. `secrets` is not a context a step's `if` can read and neither
`secrets` nor `env` is available to a job-level `if`, so the presence is
resolved once into a job-level env var, which steps can read.

The action step also gets continue-on-error: an outage or a rate limit at
JetBrains' end is worth seeing in the log, but this workflow is meant to be an
opinion beside CI rather than a gate in front of it, and a failure to obtain
that opinion should not hold a pull request whose tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaySiNst4HhDXBHnMy8p5G
2026-08-07 11:33:49 +00:00

70 lines
3.3 KiB
YAML

name: Junie review
# JetBrains' Junie agent reads each pull request and leaves inline review comments. It runs
# alongside CI rather than as part of it: CI answers whether the code works, this answers whether
# it reads well, and a review comment should never be able to turn the build red.
on:
pull_request:
types: [opened, synchronize, ready_for_review]
# A review of the previous push is stale the moment a new one lands, so supersede it rather than
# letting two reviews comment on the same pull request. Keyed by pull request rather than by ref
# so a push to `main` never cancels a review.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
# Read the code, write the review. `issues: write` is what posts the summary comment — GitHub
# treats a pull request's conversation timeline as an issue.
permissions:
contents: read
pull-requests: write
issues: write
jobs:
review:
name: Review the diff
runs-on: ubuntu-latest
# Drafts are work in progress and forks cannot see `JUNIE_API_KEY` — GitHub withholds secrets
# from `pull_request` runs on forked branches, so the job would fail on a missing key rather
# than say anything useful about the code.
if: >-
github.event.pull_request.draft == false &&
github.event.pull_request.head.repo.full_name == github.repository
env:
# Whether the key exists, resolved once here because `secrets` is not one of the contexts a
# step's `if` can read, while `env` is.
HAS_JUNIE_KEY: ${{ secrets.JUNIE_API_KEY != '' }}
steps:
# Without the key the action exits on "Missing required input", which would mark every pull
# request failed for a reason that has nothing to do with its code. Say so in the run
# summary and stop instead — visible to anyone who looks, blocking nobody who doesn't.
- name: Explain the absent key
if: env.HAS_JUNIE_KEY != 'true'
run: |
echo "No \`JUNIE_API_KEY\` secret is set, so this pull request was not reviewed." >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Generate a key at <https://junie.jetbrains.com/cli> and add it under" >> "$GITHUB_STEP_SUMMARY"
echo "Settings → Secrets and variables → Actions." >> "$GITHUB_STEP_SUMMARY"
- uses: actions/checkout@v5
if: env.HAS_JUNIE_KEY == 'true'
with:
# Junie reads the diff through the GitHub API, so the full history it would otherwise
# clone is never used.
fetch-depth: 1
- uses: JetBrains/junie-github-action@v1
if: env.HAS_JUNIE_KEY == 'true'
# An opinion, not a gate. If Junie is down or rate-limited that is worth seeing in the
# log, but it is not a reason to hold a pull request whose tests pass.
continue-on-error: true
with:
junie_api_key: ${{ secrets.JUNIE_API_KEY }}
# The action's built-in review prompt. Replace with a prompt block to review against
# criteria of our own.
prompt: code-review
# Rewrite one comment on each push instead of stacking a new one per revision, so the
# conversation shows the current state of the review rather than its history.
use_single_comment: "true"