Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/pullfrog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# PULLFROG ACTION — DO NOT EDIT EXCEPT WHERE INDICATED
#
# Dispatched by Pullfrog's control plane, never by a pull_request event, and always against
# `main` -- so this file governs a trial run only once it is on the default branch, and a
# pull request changing it is not reviewed by its own copy. The same trap
# claude-pr-review.yml carries, for the same reason.
#
# Every deviation from the console-generated file is below, and each one is deliberate:
#
# env: removed entirely The generated file maps ten provider secrets, ANTHROPIC_API_KEY
# among them, which would hand the org secret that gates the
# production reviewer to a third-party agent and let auto-select
# quietly run this trial on Claude. The rest name secrets that do
# not exist, and a workflow env: value *wins* over a
# Pullfrog-stored key -- so an empty mapping would override the
# console's OPENAI_API_KEY and fail every run with "Missing API
# key". The key lives in the Pullfrog console instead, which also
# keeps rotation and model changes off this file.
# push: disabled The trial reviews and does nothing else. Read-only at the
# action, so it holds even if a console toggle flips.
# shell: restricted Already the default for a public repo; stated so it survives
# the repo going private.
# progress_comments: The reviewer next door reads the PR conversation into its
# disabled prompt, where a live task list is context it pays for.
# timeout: 20m A review is not an hour of work; the reviewer beside it is
# capped at 15 minutes.
# checkout pinned This repository pins every action to an exact patch version.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nit: "This repository pins every action to an exact patch version" isn't quite so — anthropics/claude-code-action@v1 (claude-pr-review.yml:214) floats on a major tag today. That doesn't weaken the case for pinning actions/checkout here, but it does mean pullfrog/pullfrog@v0 isn't the sole exception, and a reader who checks the claim will find it doesn't hold. (not blocking)

# pullfrog/pullfrog stays on @v0 on the vendor's own advice: the
# action is a bootstrap that floats the agent from npm, so a SHA
# pin freezes only the post-run cleanup step and goes stale into
# runs that fail after the agent has finished its work.
name: Pullfrog
run-name: ${{ inputs.name || github.workflow }}
on:
workflow_dispatch:
inputs:
prompt:
type: string
description: Agent prompt
name:
type: string
description: Run name

permissions:
contents: read

jobs:
pullfrog:
runs-on: ubuntu-latest
permissions:
# The only two the action needs: id-token to mint its own short-lived installation
# tokens over OIDC, contents to clone. It never uses this job's GITHUB_TOKEN, so
# nothing here grants it the ability to comment, review, or push.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "nothing here grants it the ability to comment, review, or push" is true of this job's GITHUB_TOKEN and not true of the job overall — id-token: write is precisely what lets the action trade an OIDC token for a Pullfrog App installation token, and that token's scopes live in Pullfrog's App config, not in this file. So the capability the comment says is absent is delegated rather than withheld, and it's unreviewable from here.

That also bounds what push: disabled on line 65 buys: it's an input to the same mutable @v0 tag, so it constrains a cooperating action, not a compromised one. Given that tests.yml:23-25 refuses to take even actionlint as a third-party action because this repo's workflows gate every merge in the org, the honest version of this comment is that the trial accepts a mutable third-party tag with OIDC on the vendor's advice — not that the job holds nothing dangerous. Worth saying plainly, since the next reader will take this block at its word.

(not blocking)

id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6.0.2
with:
fetch-depth: 1
- name: Run agent
uses: pullfrog/pullfrog@v0
with:
prompt: ${{ inputs.prompt }}
push: disabled
shell: restricted
progress_comments: disabled
timeout: 20m

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: timeout: 20m is an input to the third-party action, so the cap is self-enforced — the comparison to the reviewer's 15 minutes isn't apples to apples, since that one is timeout-minutes: 15 on the job (claude-pr-review.yml:44) and GitHub enforces it. If pullfrog/pullfrog hangs anywhere outside the agent's own clock — the npm bootstrap that fetches the agent, or the post-run cleanup step — nothing stops the job before GitHub's 6-hour default. A job-level backstop somewhat above the action's own cap would make the 20m real:

  pullfrog:
    runs-on: ubuntu-latest
    timeout-minutes: 25

(not blocking) (not blocking)