feat(aur): publish runner-run + runner-run-bin with shell completions#35
Conversation
Add an `aur-release` workflow that publishes two AUR packages on every `release: published` (and via `workflow_dispatch` with a `tag`): - `runner-run` — builds `runner`+`run` from the source tarball via cargo. - `runner-run-bin` — installs prebuilt release binaries (x86_64, aarch64, armv7h); `provides`/`conflicts` `runner-run` as a drop-in replacement. `aur-prepare.sh` rewrites `pkgver`/`pkgrel` and, for `-bin`, injects per-arch `sha256sums_*` read from the release's published `.sha256` companion assets — sidestepping `updpkgsums`' host-$CARCH-only fetch. The source pkg has one arch-independent source, so the deploy action runs `updpkgsums` for it. Pushes gate behind the `aur` GitHub Environment for the SSH key, mirroring crates-release.yml; `dry-run` prepares + prints the PKGBUILDs without touching the AUR. Also pin every third-party action in the release/crates/npm workflows to a full commit SHA (with `# vN` comment) and collapse the touched YAML to flow style. No behavior change to those pipelines.
Both AUR packages now ship bash/zsh/fish completions into the system
autoload dirs instead of telling users to `eval` the dynamic script in
an rc file. `runner completions <shell>` emits one combined stream for
both binaries with the invoking binary's path baked in via
`current_exe()`, so: sed-rewrite the `$srcdir`/`target/release` paths to
`/usr/bin/{runner,run}`, then awk-split bash and zsh on their per-command
start-of-line boundaries into separate autoload files (fish stays one
file). Completions remain clap-dynamic — tab-completion shells out to the
binary, picking up the live task list per project.
PowerShell on Linux has no system autoload dir, so the file is installed for users to dot-source from $PROFILE.
So commits to the AUR repo attribute to the AUR account in the web UI instead of the project-author subaddress from Cargo.toml.
📝 WalkthroughAdd AUR release channel with two packages, automated publishing, shell completions and CI hardening. Introduce two AUR packages under aur/ and end-to-end automation to publish them from GitHub Releases:
This change delivers a documented AUR release pipeline for source and binary packages, installs comprehensive shell completions, and secures CI/release workflows by pinning third-party action references. WalkthroughThis PR adds AUR publishing automation and pins Actions in release pipelines. It introduces .github/scripts/publish/aur-prepare.sh (updates PKGBUILD pkgver/pkgrel and injects per-architecture sha256sums for runner-run-bin), a new .github/workflows/aur-release.yml (matrixed publish of runner-run and runner-run-bin with dry-run support and conditional deploy), two PKGBUILD recipes under aur/ for source and binary packaging (build/install/completions), updates aur/ README, and pins multiple Actions to specific commit SHAs across crates-release, npm-release and the main release workflow. sequenceDiagram
participant Release as GitHub Release
participant Workflow as .github/workflows/aur-release.yml
participant Prep as .github/scripts/publish/aur-prepare.sh
participant Assets as GitHub Release Assets
participant Deploy as KSXGitHub/github-actions-deploy-aur
participant AUR as AUR git repo
Release->>Workflow: published release / manual dispatch
Workflow->>Prep: run for pkgname, version (strip leading v)
Prep->>Assets: download per-arch .sha256 assets (runner-run-bin)
Prep->>Prep: extract & validate digest, inject into PKGBUILD
Workflow->>Deploy: conditional deploy (unless dry-run)
Deploy->>AUR: push updated aur/<pkgname>/PKGBUILD
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labelsenhancement, documentation
🚥 Pre-merge checks | ✅ 8✅ Passed checks (8 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
Comment |
Fish autoloads by command basename. Without run.fish the run binary gets no completions in a fresh shell (only after runner<TAB> sourced runner.fish first as a side effect — fragile session ordering).
- aur-prepare.sh: reject non-semver version strings before sed touches any file (blocks &/\\/// /newline injection from a hypothetical bad tag). - aur-release.yml: per-pkg concurrency group; serializes dispatch + release-published for the same pkg without blocking the other matrix leg. - release.yml: persist-credentials:false on the two checkouts that were missing it, matching the other secure checkouts in the file.
Drop restatements of what the code does. Keep only non-obvious why-notes (`release:published-skip` on token releases, `target:.rust` schema lock, toolchain ordering, drafts need contents:write).
3ef39f4 to
b7c817e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Line 140: The env mapping currently written as env: {
CARGO_UNSTABLE_BUILD_STD: std, panic_abort } splits into two keys (making
panic_abort null) so cargo-build-std does not get "std,panic_abort"; update the
release.yml env for CARGO_UNSTABLE_BUILD_STD (the env mapping that mentions
CARGO_UNSTABLE_BUILD_STD and cargo-build-std) to provide a single string value
containing the comma-separated targets, e.g. set CARGO_UNSTABLE_BUILD_STD to
"std,panic_abort" (or use a proper YAML block mapping with
CARGO_UNSTABLE_BUILD_STD: "std,panic_abort") so the action receives the intended
value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e0796c54-2914-4a85-b89a-5ed6f866a57b
📒 Files selected for processing (6)
.github/scripts/publish/aur-prepare.sh.github/workflows/aur-release.yml.github/workflows/npm-release.yml.github/workflows/release.ymlaur/runner-run-bin/PKGBUILDaur/runner-run/PKGBUILD
📜 Review details
⏰ Context from checks skipped due to timeout of 18000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (actions)
- GitHub Check: verify
🧰 Additional context used
📓 Path-based instructions (1)
.github/**/*.{yml,yaml}
⚙️ CodeRabbit configuration file
Do not ever warn about stylistic yamllint shit. Do warn about security related shit. Insecure shell handling of user supplied / defined strings: think of branch names, inputs, pr content, anything needs to be string interpolation and permission safe.
Files:
.github/workflows/aur-release.yml.github/workflows/npm-release.yml.github/workflows/release.yml
🧠 Learnings (1)
📚 Learning: 2026-05-04T15:23:38.296Z
Learnt from: kjanat
Repo: kjanat/runner PR: 5
File: .github/workflows/release.yml:73-73
Timestamp: 2026-05-04T15:23:38.296Z
Learning: For GitHub Actions workflows in this repository (kjanat/runner), maintain the maintainer’s preference for “floating” action tags (e.g., `v6`, `v7`) instead of pinned full commit SHAs. During code review, do not flag action usages in `.github/workflows/**/*.yml` for not being pinned to full commit SHAs or suggest switching to SHA pinning.
Applied to files:
.github/workflows/aur-release.yml.github/workflows/npm-release.yml.github/workflows/release.yml
🔇 Additional comments (12)
.github/scripts/publish/aur-prepare.sh (2)
20-28: Aye, the version validation be shipshape now! 🏴☠️LGTM! The semver regex properly rejects malicious characters (
&,/,\, newlines) before they can keelhaul thesedsubstitution. This addresses the previous concern about injection throughworkflow_dispatch.
30-37: LGTM!Also applies to: 39-58, 61-62
.github/workflows/aur-release.yml (3)
27-28: Arr, the concurrency guard be properly hoisted! 🏴☠️LGTM! The per-package concurrency group prevents dispatch and release-triggered runs from racing each other to the AUR push.
1-21: LGTM!Also applies to: 29-42
44-62: LGTM!aur/runner-run-bin/PKGBUILD (2)
62-67: Shiver me timbers, the fish be properly rigged now! 🐟🏴☠️LGTM! Installing
fish.combinedunder bothrunner.fishandrun.fishensures each command's tab-completion works in a fresh shell without depending on session order. This addresses the previous concern about fish's basename-based autoloading.
1-28: LGTM!Also applies to: 30-61, 68-71
aur/runner-run/PKGBUILD (2)
76-81: Arr, same fix as the -bin package, properly doubling up the fish files! 🐟🏴☠️LGTM! Both
runner.fishandrun.fishare now installed, ensuring tab-completion works regardless of which command the user invokes first.
1-40: LGTM!Also applies to: 42-75, 82-85
.github/workflows/npm-release.yml (1)
82-105: LGTM!.github/workflows/release.yml (2)
34-34:persist-credentials: falseon these checkouts — splendid bit o' hardening, that.Keeps the auto-injected token off disk where it isn't needed. No quarrel from me.
LGTM!
Also applies to: 98-98
45-59: Shell handling o' the release tag be done right —RELEASE_TAG/GITHUB_REPOSITORYpassed viaenvand quoted, no raw${{ }}injection into the script.
github.ref_nameflows through an env var and is quoted in the shell body, so no command-injection plank to walk here.LGTM!
Also applies to: 200-209
| if: matrix.build-tool == 'cargo-build-std' | ||
| env: | ||
| CARGO_UNSTABLE_BUILD_STD: std,panic_abort | ||
| env: { CARGO_UNSTABLE_BUILD_STD: std, panic_abort } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
python3 - <<'EOF'
import yaml
print(yaml.safe_load("{ CARGO_UNSTABLE_BUILD_STD: std, panic_abort }"))
print(yaml.safe_load('{ CARGO_UNSTABLE_BUILD_STD: "std,panic_abort" }'))
EOFRepository: kjanat/runner
Length of output: 162
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '120,160p' .github/workflows/release.yml | cat -nRepository: kjanat/runner
Length of output: 2085
Fix broken YAML env for cargo-build-std (line 140)
That flow-mapping env: { CARGO_UNSTABLE_BUILD_STD: std, panic_abort } gets parsed as:
CARGO_UNSTABLE_BUILD_STD: 'std'panic_abort: null
So cargo-build-std won’t receive std,panic_abort like it’s meant to.
🐛 Proposed fix
- env: { CARGO_UNSTABLE_BUILD_STD: std, panic_abort }
+ env: { CARGO_UNSTABLE_BUILD_STD: "std,panic_abort" }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| env: { CARGO_UNSTABLE_BUILD_STD: std, panic_abort } | |
| env: { CARGO_UNSTABLE_BUILD_STD: "std,panic_abort" } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml at line 140, The env mapping currently written
as env: { CARGO_UNSTABLE_BUILD_STD: std, panic_abort } splits into two keys
(making panic_abort null) so cargo-build-std does not get "std,panic_abort";
update the release.yml env for CARGO_UNSTABLE_BUILD_STD (the env mapping that
mentions CARGO_UNSTABLE_BUILD_STD and cargo-build-std) to provide a single
string value containing the comma-separated targets, e.g. set
CARGO_UNSTABLE_BUILD_STD to "std,panic_abort" (or use a proper YAML block
mapping with CARGO_UNSTABLE_BUILD_STD: "std,panic_abort") so the action receives
the intended value.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/npm-release.yml (1)
40-45:⚠️ Potential issue | 🟠 Major | ⚡ Quick winValidate
workflow_dispatchinputs before trusting 'em.Ahoy:
inputs.tagandinputs.run-idbe operator-supplied, but this path only provesrun-idis numeric. That still lets a mismatchedrun-id/tagpair fetch and publish the wrongnpm-distartefact, and the “Trusted trigger metadata only” note papers over that trust boundary. Please verify that the supplied run actually belongs to a successfulrelease.ymlrun forRELEASE_TAGbefore writing it toGITHUB_OUTPUT. As per coding guidelines,.github/**/*.{yml,yaml}should warn about insecure handling of user supplied / defined strings and keep interpolation permission-safe.Also applies to: 75-105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/npm-release.yml around lines 40 - 45, The workflow currently trusts operator-supplied inputs.tag and inputs.run-id when setting RELEASE_TAG and writing to GITHUB_OUTPUT; update the workflow_dispatch handling to first validate that the provided run-id corresponds to a completed successful run of the release workflow that produced the same tag: fetch the workflow run metadata (using the GitHub API) for the given run-id, verify its workflow name/file is release.yml (or expected workflow id), confirm its conclusion is success and its associated tag/release equals RELEASE_TAG, and only then set RELEASE_TAG / write outputs (GITHUB_OUTPUT); reject or fail the job if any check fails to avoid mismatched run-id/tag pairs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/npm-release.yml:
- Around line 40-45: The workflow currently trusts operator-supplied inputs.tag
and inputs.run-id when setting RELEASE_TAG and writing to GITHUB_OUTPUT; update
the workflow_dispatch handling to first validate that the provided run-id
corresponds to a completed successful run of the release workflow that produced
the same tag: fetch the workflow run metadata (using the GitHub API) for the
given run-id, verify its workflow name/file is release.yml (or expected workflow
id), confirm its conclusion is success and its associated tag/release equals
RELEASE_TAG, and only then set RELEASE_TAG / write outputs (GITHUB_OUTPUT);
reject or fail the job if any check fails to avoid mismatched run-id/tag pairs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbd1b2c1-85bb-4821-b99d-c0c15db4ef32
📒 Files selected for processing (2)
.github/workflows/aur-release.yml.github/workflows/npm-release.yml
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
.github/**/*.{yml,yaml}
⚙️ CodeRabbit configuration file
Do not ever warn about stylistic yamllint shit. Do warn about security related shit. Insecure shell handling of user supplied / defined strings: think of branch names, inputs, pr content, anything needs to be string interpolation and permission safe.
Files:
.github/workflows/npm-release.yml.github/workflows/aur-release.yml
🧠 Learnings (1)
📚 Learning: 2026-05-04T15:23:38.296Z
Learnt from: kjanat
Repo: kjanat/runner PR: 5
File: .github/workflows/release.yml:73-73
Timestamp: 2026-05-04T15:23:38.296Z
Learning: For GitHub Actions workflows in this repository (kjanat/runner), maintain the maintainer’s preference for “floating” action tags (e.g., `v6`, `v7`) instead of pinned full commit SHAs. During code review, do not flag action usages in `.github/workflows/**/*.yml` for not being pinned to full commit SHAs or suggest switching to SHA pinning.
Applied to files:
.github/workflows/npm-release.yml.github/workflows/aur-release.yml
🔇 Additional comments (2)
.github/workflows/aur-release.yml (1)
28-29: LGTM!Also applies to: 32-32
.github/workflows/npm-release.yml (1)
60-68: LGTM!
Closes the gap left by #35 — the AUR packages are live but neither the README, the landing site, nor the changelog mentioned them. - **README.md** `## Install`: `yay -S runner-run-bin` added to the top-tier list (alongside `npm` and `cargo binstall`). Source variant `yay -S runner-run` slotted into the collapsed *Other install methods* block, next to the `cargo install` entries. - **site/src/index.html**: new `arch · aur · primary` copy-button between `cargo · binstall · primary` and `cargo · build from source`; same markup pattern as the existing buttons. - **CHANGELOG.md** `[Unreleased]`: `### Added` describes the two AUR packages, the four-shell completion install paths, the workflow, and the prepare script. `### Security` documents the action-SHA pinning sweep and the persist-credentials hardening from #35.
Summary
runner-run— builds from source via cargo (x86_64,aarch64)runner-run-bin— installs prebuilt release binaries (x86_64,aarch64,armv7h);provides/conflictsrunner-run/usr/share/runner/runner.ps1for$PROFILEdot-sourcing..github/workflows/aur-release.ymlfires onrelease: published; gated behind theaurGitHub Environment so the SSH key is only readable from that job. Matrix runs both pkgs in parallel withfail-fast: false. Manualworkflow_dispatchwithdry-runtoggle for validation..github/scripts/publish/aur-prepare.shrewritespkgver/pkgreland — for the-binpkg — injects per-archsha256sums_*read directly from the release's published.sha256companion assets (updpkgsumson x86_64 CI can't compute aarch64/armv7h sums).uses:references in the existing release workflows to commit SHAs.Implementation notes
runner completions <shell>is the only completion generator and emits a single stream covering bothrunnerANDrun, with the path of the invoking binary baked in viacurrent_exe(). The PKGBUILDs handle both wrinkles insidepackage():sed-rewrite the baked$srcdirpath to/usr/bin/{runner,run}. Longer match first —…/runis a prefix of…/runner.awk-split bash + zsh on their start-of-line boundaries (_clap_complete_run\(\) \{for bash,#compdef runfor zsh) so each command lands in its own autoload file. Fish and pwsh stay as one file.Final installed surface per package:
/usr/share/bash-completion/completions/{runner,run}/usr/share/zsh/site-functions/{_runner,_run}/usr/share/fish/vendor_completions.d/runner.fish/usr/share/runner/runner.ps1. /usr/share/runner/runner.ps1Test plan
aur-prepare.shexercised against livev0.12.0release; injected sha256 sums byte-equal to published.sha256assets for all three arches.runner-run-binbuilt locally withmakepkg --nodeps --noconfirm→ 6 completion files present at canonical paths, all baked paths rewritten to/usr/bin/{runner,run}, zero$srcdirresidue.runner-run'spackage()block simulated against the working-tree binaries — identical outcome.bash -n,zsh -n,fish -npass on their respective installed files.[Parser]::ParseFile(pwsh's reflected parser) passes onrunner.ps1.namcapon the built-binpackage: zero errors (residual warnings are the known false-positive Rust libgcc/glibc-stub linkage notes).actionlintclean onaur-release.yml; YAML parses;case()usage matches the convention of the three existing release workflows.aur-release→ Run workflow withdry-run: true.