What the agent does
In a repository like tauri-apps/tauri there are 24 workflow files under .github/workflows, from test-core.yml and test-android.yml to publish-cli-rs.yml, docker.yml and covector-version-or-publish.yml. Almost every uses: line points at a moving tag: actions/checkout@v7 appears 37 times, actions/setup-node@v7 19 times, Swatinem/rust-cache@v2 9 times and taiki-e/install-action@v2 6 times. Only three lines already carry a commit: softprops/action-gh-release in publish-cli-rs.yml, peter-evans/repository-dispatch in covector-version-or-publish.yml (with a # 3.0.0 comment) and peter-evans/create-pull-request@v8.1.1 by exact tag. The agent lists each line with its file and line number before it changes anything.
It then finds the drift the tags hide. bench.yml and deploy-schema-worker.yml still use actions/checkout@v6 while the rest use v7, and supply-chain.yml uses actions/checkout@master. publish-cli-rs.yml and docker.yml upload with actions/upload-artifact@v4 and download with actions/download-artifact@v4.1.7, while other jobs are on upload v7 and download v8. docker.yml builds the .docker/cross images with docker/setup-qemu-action@v2, setup-buildx-action@v2, login-action@v2 and build-push-action@v3, several majors behind the docker/setup-qemu-action@v4 in publish-cli-js.yml. For each action the agent resolves the latest release to its 40-character commit and rewrites the line as owner/repo@
Two kinds of reference need care. dtolnay/rust-toolchain selects the toolchain by its ref (@stable, @1.90, @nightly, @master), so pinning it to a commit means moving the choice into a toolchain: input, the way test-core.yml already passes toolchain: ${{ matrix.platform.toolchain }} to @master. jbolda/covector/packages/action@covector-v0 is a tag on a monorepo, so the agent resolves that exact tag rather than the newest release of any package in it. Local reusable workflows such as uses: ./.github/workflows/test-api-e2e.yml are left alone.
For every major jump (upload and download artifact v4 to current, the docker actions v2 to current) it reads the action's release notes for removed or renamed inputs and adjusts the with: blocks. The upload and download pair must move together, because artifacts written by one major cannot always be read by another. It then runs actionlint on the changed files and opens the pull request against dev, the branch renovate.json targets.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Pin every third-party action in .github/workflows to the full commit SHA of its latest release, written as owner/repo@<sha> # vX.Y.Z. Leave local uses: ./ workflows alone. For dtolnay/rust-toolchain, pin the commit and move the toolchain from the ref into a toolchain: input. Move actions/upload-artifact and actions/download-artifact together. Read the release notes of every action that crosses a major version and fix any removed or renamed input. Run actionlint on every changed file. Open a pull request against dev with a table of each action, its old ref, new version and SHA, and make sure its checks pass.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
The pull request touches only files under .github/workflows. Its description has one row per action: the old ref (v7, v4.1.7, master, stable), the release it now names, and the SHA it is pinned to, then a short section for each major jump with the input changes the release notes asked for. The workflows that run on pull requests (fmt.yml, lint-rust.yml, lint-js.yml, test-core.yml and the others whose paths: filters match .github/workflows) run on the pinned versions, so a bad SHA or a broken input fails there.
Workflows that only run on push to dev, on release or on a schedule, such as publish-cli-rs.yml, docker.yml and the covector publish job, are not exercised by the pull request. The description lists them separately so a reviewer knows which pins were checked by actionlint alone. A reviewer compares each SHA with the release it names and reads the docker.yml diff closely, since four of its actions move by more than one major.
Run it on every Monday morning
renovate.json here enables only the cargo and npm managers, so nothing proposes new action releases. A scheduled job can send this request each Monday; when every pin is already current, the agent reports that and opens nothing.
Set a webhook URL on the API key and Rush posts run.completed when the turn ends. Your handler reads the session from session_url and posts the pull request link to the channel that owns CI.
The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.
Why run it on Rush?
Twenty-four workflows with a desktop, mobile and Docker matrix are slow to check by hand, and the risky part is not the edit but knowing what each major release removed. In a Rush sandbox the agent clones the repository, uses gh to resolve each tag to a commit, reads the release notes and runs actionlint, and every command with its output stays in the session transcript for the reviewer.
The result is one pull request whose own checks have run on the new pins, not 30 separate bump pull requests. If you maintain several Tauri apps or plugins, each repository can get its own run at the same time, within the key's concurrency limit.
Frequently asked questions
Why not just keep the @v7 tags?
A tag can be moved to point at different code after you reviewed it; a commit SHA cannot. Pinning with the version in a comment keeps the workflow readable while making what runs fixed.
What happens to dtolnay/rust-toolchain@stable and @1.90?
That action reads the toolchain from its ref. To pin it, the agent points every use at the same commit and passes stable, 1.90 or nightly through the toolchain: input, which the action supports.
Will it touch Cargo.toml or package.json?
No. The request is limited to .github/workflows. Rust and npm dependencies stay with Renovate, which this repository already configures for cargo and npm.
How are the workflows that do not run on pull requests checked?
actionlint validates their syntax and inputs, and the description lists them as not exercised. A reviewer can trigger the ones with workflow_dispatch after merge, or check them on the next push to dev.