Repository navigation
ci(pullfrog): pin the action and make the reviewer review-only - #38
Conversation
Three changes to the workflow the Pullfrog console generated, each for a reason that applies to this repository specifically. `push: disabled`. The input defaults to `enabled`, which lets the agent push branches and open pull requests of its own. Every commit and pull request here is authored by its maintainer, so the agent gets no write path at all: it reads the diff and comments. The input is declared in the action's own action.yml and is not mentioned in the getting-started guide, so the generated file leaves it at the permissive default. Pinned to a commit SHA instead of `@v0`. That tag moves — it has already advanced through ninety v0.1.x releases — and this is the one action here that runs an agent with repository access, so a mutable ref is the last place to accept one. Pullfrog's versioning page supports pinning and notes nothing is lost: the action fetches its steps from npm either way, so the agent still tracks patch releases without this file changing. `shell: restricted`, which scrubs *_TOKEN / *_KEY / *_SECRET / *_PASSWORD / *_CREDENTIAL from the environment the agent's shell sees. Already the default for a public repository; stated explicitly so that making this repository private some day cannot silently widen it, since private repos default to `enabled`. The provider `env:` block is left exactly as generated. Unset secrets resolve to empty strings, and the action's sanitizeSecret() leaves the variable untouched in that case rather than treating it as a key, so the block is inert until a key is actually added and it cannot shadow keys held in Pullfrog's own store or the Router. Nothing else is touched: no `run:` steps, so no shell interpolation surface, and no workflow expression reads untrusted event data.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Pinned the agent action to a commit SHA —
pullfrog/pullfrog@v0→@0d318bef…, the commit for tagv0.1.90(confirmed against the upstream tag ref and the currentreleases/latest). Removes the mutable-tag supply-chain surface on the one action that runs with repository access. - Added
push: disabled— the agent runs read-only and cannot create branches or pull requests. - Added
shell: restrictedexplicitly — pins the secret-scrubbing behavior so a future switch to a private repo can't silently widen it toenabled.
Verification. Both push and shell are declared in the action's action.yml at that SHA, and each value used is a documented option. The comment's load-bearing claim — that a SHA pin still tracks ^0.1.x patches because the bootstrap resolves its steps from npm — holds: runCli.ts runs npx --yes pullfrog@^<package.json version> unless the ref is main, so npm resolution keeps advancing within the 0.1 line. No run: steps and no expression consumes untrusted event data, so no injection surface.
Important
Pullfrog covered this run's model usage. DeepSeek Flash is fast and cheap — expect lighter work than a frontier model. This model allowance is temporary and separate from your Pullfrog plan. Connect a model-provider subscription or API key →
DeepSeek Flash (model usage covered by Pullfrog) | 𝕏
actions/checkout defaults to persist-credentials: true, which writes the job's GITHUB_TOKEN into .git/config. That leaves a working push credential inside the very checkout the agent then operates on, so it contradicts the `push: disabled` set alongside it: the input closes the action's own push path and the token reopens it from underneath. Caught by Pinakes' CI policy check — "pullfrog.yml has an actions/checkout step that persists GitHub credentials" — which refuses any checkout that persists credentials. It was right, and the same omission was in all of these repositories, so the fix goes everywhere rather than only where a check happened to be watching. Nothing needs the credential: the agent reaches GitHub through the App's installation token, not the local git remote, and these repositories are public, so an unauthenticated fetch works.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run re-reviewed the single commit added since the prior Pullfrog review (a5ca03d → 9f1f57f).
- Stopped the checkout persisting a push credential —
actions/checkoutnow takespersist-credentials: false, so the job'sGITHUB_TOKENis no longer written into.git/config. This closes the write path thatpush: disabledalone cannot: the input governs the action's own push feature, while the persisted token left an authenticated remote underneath it. - Documented the rationale inline — a nine-line comment explains the default, the contradiction with
push: disabled, and why nothing here needs the credential.
Verification. The load-bearing claims in the comment check out. api.github.com/repos/fabiodalez-dev/Pinakes-Android reports private:false, so the unauthenticated fetch it relies on works. actions/checkout@v6 resolves to a real tag (pre-existing, unchanged by this PR). The Pullfrog agent reaches GitHub through the App installation token via the MCP server rather than the local checkout's credential, and play-bundle.yml:21 already runs a credential-free checkout in this repo — so disabling persistence cannot break PR checkout or fetch.
Important
Pullfrog covered this run's model usage. DeepSeek Flash is fast and cheap — expect lighter work than a frontier model. This model allowance is temporary and separate from your Pullfrog plan. Connect a model-provider subscription or API key →
DeepSeek Flash (model usage covered by Pullfrog) | 𝕏
The reviewer workflow was the only file in .github failing the Workflow, YAML and shell security gate. Four separate problems, all real: - zizmor (pedantic) wants every write permission documented, and it reads a trailing comment on the permission line, not a block above it. id-token: write now says on its own line what it is for: an OIDC identity for Pullfrog token service, which grants nothing on the repository. - The job had no name, so it showed up anonymously in the checks list. - The workflow had no concurrency group. It was left out on purpose, because every run is dispatched against the default branch and one shared group would make two reviews cancel each other. The group is keyed on the dispatched run name instead, so a fresh review of the same pull request supersedes a stale one while different pull requests never collide, and it falls back to the unique run id when no name is passed. - Two lines carried trailing whitespace, inherited from the generated template, which yamllint rejects. The gate had never reached yamllint because zizmor failed first. Also pins actions/checkout by commit SHA where it was still a floating v6 tag. Verified locally with the same three tools the gate runs, over the whole .github tree: zizmor --persona pedantic, actionlint and yamllint all exit 0.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run re-reviewed the single commit added since the prior Pullfrog review (9f1f57f → 4590501).
- Pinned
actions/checkoutto a commit SHA —@v6→@d23441a… # v6, closing the same mutable-ref surface that the earlier commit closed on the agent action. - Added a top-level
concurrencygroup — keyed on the dispatcher-supplied run name, so a fresh review of the same pull request supersedes a stale one while reviews of different pull requests never collide; falls back to the unique run id when no name is passed. - Added a job name and explanatory comments on the top-level and job
permissionsblocks, and stripped trailing whitespace from theenv:block.
Verification. api.github.com/repos/actions/checkout/git/ref/tags/v6 returns commit d23441a48e516b6c34aea4fa41551a30e30af803, so the pin and its # v6 comment match. inputs is an allowed context in a top-level concurrency for workflow_dispatch, and inputs.name || github.run_id falls back to the run id — unique per run — so cancel-in-progress cannot cancel unrelated runs. No run: steps and no expression consumes untrusted event data.
Important
Pullfrog covered this run's model usage. DeepSeek Flash is fast and cheap — expect lighter work than a frontier model. This model allowance is temporary and separate from your Pullfrog plan. Connect a model-provider subscription or API key →
deepseek-v4.1-flash (model usage covered by Pullfrog) | 𝕏

The Pullfrog console generated this workflow when I enabled the repository. It works, but it leaves three things at defaults that are wrong for this project, so this tightens them before the reviewer starts running.
push: disabled. This is the one that matters. The input defaults toenabled, which lets the agent push branches and open pull requests of its own. Every commit and pull request in my repositories is authored by me, so the agent gets no write path at all: it reads the diff and comments. The input is declared in the action's ownaction.ymland is not mentioned in the getting-started guide, which is why the generated file leaves it permissive.Pinned to a commit SHA instead of
@v0. That tag moves — it has already advanced through ninetyv0.1.xreleases — and this is the only action here that runs an agent with access to the repository, so a mutable ref is the last place I want one. Pullfrog's own versioning page supports pinning and says nothing is lost: the action fetches its steps from npm either way, so the agent keeps tracking patch releases without this file changing. Bump the SHA to update.shell: restricted, which scrubs*_TOKEN/*_KEY/*_SECRET/*_PASSWORD/*_CREDENTIALout of the environment the agent's shell sees. It is already the default for a public repository; I set it explicitly so that making this repository private some day cannot widen it silently, since private repos default toenabled.I left the provider
env:block exactly as generated. I checked what an unset secret does: it resolves to an empty string, and the action'ssanitizeSecret()leaves the variable untouched in that case rather than treating it as a key, so the block is inert until a key is actually added and it cannot shadow keys held in Pullfrog's own store or in the Router.Nothing else changes. There are no
run:steps, so there is no shell interpolation surface, and no workflow expression reads untrusted event data.One caveat worth recording: the file carries Pullfrog's own
DO NOT EDIT EXCEPT WHERE INDICATEDheader, so if the console regenerates it these three changes are lost. The durable place for the push tier is the console's own repository setting; this file is the belt to that braces.