Junie has been reviewing pull requests here since the key was added, and eight of the last eight runs succeeded. What it was not, was configured like the sibling repositories, and three of those differences are worth closing. The action was referenced as `@v1`. It is the only third-party action in this repository and the only one handed a repository secret, so its definition should not be able to change under us. `v1` and `v1.7.5` resolve to the same commit today — the pin is not about which code runs now, it is about who gets to decide that later. There was no timeout. A run that goes wrong hangs rather than stops, and the pull request shows a pending check until Actions gives up on its own six hours later. Forty-five minutes, not the thirty the siblings use: the longest review this repository has actually had ran thirty-five, on the largest diff so far, and a ceiling that cuts a successful review short is worse than none. And a pull request closed and reopened had had no review since it was closed. Left alone deliberately: the absent-key step, which says so in the run summary instead of failing a pull request for a reason that has nothing to do with its code, and the lack of a `branches:` filter — work here stacks feature onto feature, and filtering on main would skip every pull request in a chain but the last. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
85 lines
4.5 KiB
YAML
85 lines
4.5 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:
|
|
# `reopened` because a pull request closed and reopened has had no review since it was
|
|
# closed, and `ready_for_review` because the draft guard below would otherwise skip a pull
|
|
# request opened as a draft forever. No `branches:` filter: work here stacks feature onto
|
|
# feature, so filtering on main would skip every pull request in a chain but the last.
|
|
types: [opened, synchronize, reopened, 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
|
|
# A ceiling, not a target: a run that goes wrong hangs rather than stops, and the pull
|
|
# request shows a pending check until it does. Set above the longest review this repository
|
|
# has actually had — 35 minutes, on the largest diff so far — rather than at the sibling
|
|
# repositories' 30, which would have cut that one short.
|
|
timeout-minutes: 45
|
|
# 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
|
|
|
|
# Pinned to a commit rather than to `v1`: this is the only third-party action here and it
|
|
# is handed a repository secret, so its definition should not be able to change under us.
|
|
# `v1` resolves to this same commit today; the pin is about who gets to move it. The pin
|
|
# covers this definition only — the composite pulls its own dependencies by tag and fetches
|
|
# the Junie CLI over the network. Bump by resolving the new release's commit, never by
|
|
# moving a tag name.
|
|
- uses: JetBrains/junie-github-action@3f6a906f11c6f67c76efaf3d3264bbb615f9ce29 # v1.7.5
|
|
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"
|