Skip to content

publish: runner-run crate to crates.io#8

Open
kjanat wants to merge 8 commits intomasterfrom
claude/setup-crates-publishing-eYir9
Open

publish: runner-run crate to crates.io#8
kjanat wants to merge 8 commits intomasterfrom
claude/setup-crates-publishing-eYir9

Conversation

@kjanat
Copy link
Copy Markdown
Owner

@kjanat kjanat commented May 5, 2026

Summary

This PR adds support for publishing the runner crate to crates.io and renames the package to runner-run to avoid conflicts with existing crates.

Key Changes

  • Renamed package from runner to runner-run in Cargo.toml to comply with crates.io naming requirements
  • Added library target configuration in Cargo.toml to expose the crate as a library while maintaining the binary
  • Added crates-release workflow (.github/workflows/crates-release.yml) that:
    • Publishes to crates.io after successful tag-triggered releases
    • Supports manual dispatch with optional dry-run verification
    • Validates that git tags match Cargo.toml version before publishing
    • Uses trusted trigger metadata (never build-time scripts) for release tag sourcing
    • Mirrors the security and structure of the existing npm-release workflow

Implementation Details

  • The workflow is triggered either by a successful release.yml workflow run on version tags (starting with 'v') or via manual workflow_dispatch
  • Version verification ensures the git tag matches the version in Cargo.toml before any publish attempt
  • Dry-run is always executed for verification; actual publish to crates.io only occurs when not in dry-run mode
  • Uses sparse-checkout pattern with trusted scripts from the default branch for security
  • Requires CARGO_REGISTRY_TOKEN secret for actual crate publication

https://claude.ai/code/session_014R4NQ7rUaJVZ2s36Kxe4WT

Renames the package on crates.io to runner-run (the bare `runner` name is
already taken). Pin [lib] name = "runner" so existing src/{main,bin}.rs
references to the library crate keep working unchanged.

Adds .github/workflows/crates-release.yml mirroring npm-release.yml: runs
on successful tag-triggered release.yml or manual dispatch, verifies the
tag matches Cargo.toml version, dry-runs publish, then uploads with
CARGO_REGISTRY_TOKEN under the crates-io environment.
Comment thread .github/workflows/crates-release.yml Fixed
Comment thread .github/workflows/crates-release.yml Fixed
Comment thread .github/workflows/crates-release.yml Fixed
CodeQL flagged the previous workflow_run + checkout-of-tag pattern as
"untrusted code in a privileged context" (security/code-scanning #7-9):
workflow_run runs with secrets, and `cargo publish` executes build.rs
from the tag-controlled checkout, which would let a malicious tag
exfiltrate CARGO_REGISTRY_TOKEN.

Switch the trigger to `release: types: [published]`. release.yml still
creates the release as a draft — a maintainer must review and click
publish, which becomes the human gate. The `crates-io` environment's
required reviewers are the second gate. workflow_dispatch is preserved
for manual republishes.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Review Change Stack

📝 Walkthrough
  • Rename package in Cargo.toml from runnerrunner-run to avoid crates.io name conflicts while keeping the library crate name runner ([lib] name = "runner") so existing runner::... imports remain valid.
  • Bump package version 0.6.0 → 0.7.0 in Cargo.toml.
  • Add an explicit library target ([lib] path = "src/lib.rs") alongside the existing binary so the crate can be consumed as a library while retaining the CLI binary.
  • Add GitHub Actions workflow .github/workflows/crates-release.yml to publish the crate to crates.io:
    • Triggered by published GitHub releases (version tags, e.g. v*) and by manual workflow_dispatch with tag and optional dry-run.
    • Reads RELEASE_TAG from trusted trigger metadata (inputs.tag for manual runs, otherwise the release tag) and pins checkout to refs/tags/<tag> to avoid ambiguous tag/branch resolution.
    • Uses sparse-checkout and trusted trigger metadata to avoid executing build-time scripts from untrusted checkouts; mirrors security/structure of the existing npm-release workflow while avoiding workflow_run anti-patterns.
    • Verifies the release tag (stripping a leading v) matches the runner-run version in Cargo.toml using cargo metadata + jq.
    • Always runs cargo publish --locked --dry-run as verification; only performs cargo publish --locked when not in dry-run mode and when CARGO_REGISTRY_TOKEN is present.
    • Fails fast with a job-level HAS_CARGO_REGISTRY_TOKEN check and clear error when the registry token is missing to prevent obscure publish failures.
  • Update CHANGELOG.md: add Unreleased post-release checklist and record 0.7.0 entry documenting the crates-release workflow and package rename.

Preserves existing library import stability, enables secure tag-driven and manual publishes to crates.io, and improves CI safety and publish error messaging.

Walkthrough

Package renamed from runnerrunner-run and [lib] added with name = "runner". A new GitHub Actions workflow .github/workflows/crates-release.yml verifies tag vs Cargo.toml, runs cargo publish --locked --dry-run, then conditionally publishes to crates.io with CARGO_REGISTRY_TOKEN.

Changes

Crate Publication and Release Automation

Layer / File(s) Summary
Data Shape / Package Manifest
Cargo.toml
Package name changed to runner-run; version bumped to 0.7.0; new [lib] target added with name = "runner" and path = "src/lib.rs".
Workflow Run-name & Triggers
.github/workflows/crates-release.yml
Workflow run-name set from release vs manual dispatch; triggers on release.published and workflow_dispatch with required tag and optional dry-run.
Job Env / Checkout / Toolchain
.github/workflows/crates-release.yml
Job env computes RELEASE_TAG, normalizes INPUT_DRY_RUN, computes HAS_CARGO_REGISTRY_TOKEN; checks out refs/tags/${RELEASE_TAG}, installs stable Rust, enables Cargo caching.
Verification Step
.github/workflows/crates-release.yml
Strips leading v from the tag and compares to the runner-run version via cargo metadata + jq; workflow fails on mismatch.
Publish Steps
.github/workflows/crates-release.yml
Always runs cargo publish --locked --dry-run; when INPUT_DRY_RUN != 'true' verifies CARGO_REGISTRY_TOKEN presence then runs cargo publish --locked with token scoped to publish step only.
Changelog / Docs
CHANGELOG.md
Adds Unreleased checklist and documents 0.7.0 entries describing the new crates-release workflow and the package rename while preserving the library crate name runner.
sequenceDiagram
    autonumber
    participant Release as GitHub Release
    participant GH as GitHub Actions Runner
    participant Repo as Repository (git)
    participant Cargo as Cargo / Rust toolchain
    participant Crates as crates.io

    Release->>GH: release.published or workflow_dispatch
    GH->>Repo: checkout tag RELEASE_TAG
    GH->>Cargo: install stable toolchain & enable cache
    GH->>Cargo: cargo metadata + jq -> read `runner-run` version
    Cargo-->>GH: package version
    GH->>GH: compare tag vs Cargo.toml version
    alt versions match
        GH->>Cargo: cargo publish --locked --dry-run
        Cargo-->>GH: dry-run result
        alt INPUT_DRY_RUN != 'true'
            GH->>Crates: cargo publish --locked (with CARGO_REGISTRY_TOKEN)
            Crates-->>GH: publish result
        end
    else mismatch
        GH-->>Release: fail workflow (version mismatch)
    end
Loading

"Arrr, the package be renamed and the rig be set,
Tags be checked afore we send it to the net,
Dry-run first, then hoist the token with care,
crates.io gets feed only when the versions pair,
Ship it proper, or I'll make ye swab the lair!"

🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Changelog Update ⚠️ Warning CHANGELOG v0.7.0 section present with date and descriptions, but [Unreleased] compare link still points to v0.6.0 instead of v0.7.0. Update CHANGELOG footer line 460: change [Unreleased] compare link from v0.6.0 to v0.7.0
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed Title uses lowercase verb 'publish' following conventional commit guidelines and clearly describes the main change: publishing the runner-run crate to crates.io.
Description check ✅ Passed Description is comprehensive and directly related to the changeset, covering package rename, library target configuration, and workflow implementation with clear implementation details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Semver Version Bump Validation ✅ Passed No actual source code (.rs) files were modified. Only Cargo.toml config, CI workflow, and docs changed. Custom check requires version bump only if source code is modified—condition not met.
Agents.Md Documentation Updated ✅ Passed No AGENTS.md file exists in the repository. The custom check's condition does not apply—the check only requires AGENTS.md updates IF such a file exists. No file, no violation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/setup-crates-publishing-eYir9

Comment @coderabbitai help to get the list of available commands and usage tips.

@kjanat kjanat changed the title Publish runner crate to crates.io feat: publish runner-run crate to crates.io May 5, 2026
@kjanat kjanat changed the title feat: publish runner-run crate to crates.io publish: runner-run crate to crates.io May 5, 2026
@kjanat kjanat self-assigned this May 5, 2026
coderabbitai[bot]

This comment was marked as resolved.

claude and others added 2 commits May 5, 2026 08:43
Two CodeRabbit findings on the crates-release workflow:

- actions/checkout resolves bare refs to a branch first, then a tag, so
  a branch sharing a tag's name would silently checkout the wrong commit
  on workflow_dispatch input. Pin the ref to refs/tags/<tag> explicitly.

- cargo publish would die with an opaque auth error if CARGO_REGISTRY_TOKEN
  isn't wired up. Compute HAS_CARGO_REGISTRY_TOKEN at job-level (so the
  secret value never lands in a step env) and fail fast with a clear
  message before the publish step runs.
@gitguardian
Copy link
Copy Markdown

gitguardian Bot commented May 5, 2026

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 5, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
runner 8a785e0 Commit Preview URL

Branch Preview URL
May 08 2026, 11:58 PM

@kjanat kjanat added the enhancement New feature or request label May 5, 2026
@kjanat kjanat marked this pull request as ready for review May 8, 2026 02:34
coderabbitai[bot]

This comment was marked as low quality.

The package rename to runner-run isn't strictly breaking — runner-run
has never been published to crates.io and the bare `runner` name on
the registry belongs to someone else, so there's no prior consumer to
break. But a lot of work has accumulated under [Unreleased] since
v0.6.0 (composite action, cargo-aliases task source, landing page,
templated site build, npm publish hardening, BSD packaging fixes,
and now crates.io publishing), so cut a 0.7.0 section dated today
and let this PR's tag carry all of it.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
Cargo.toml (1)

2-3: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Arrr — bump this to a MAJOR release for the crate rename.

Line 2 changes the published crate identity (runnerrunner-run), which is a breaking change for consumers; Line 3 at 0.7.0 under-signals that break.

Suggested patch
-version      = "0.7.0"
+version      = "1.0.0"

As per coding guidelines, “If the PR introduces breaking changes (removal or renaming of public APIs, changes to function signatures, deleted exported symbols, or incompatible config changes), MAJOR must increment.”

🤖 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 `@Cargo.toml` around lines 2 - 3, The crate rename in Cargo.toml changes the
published package identity (name = "runner-run") which is a breaking change, so
update the version string from "0.7.0" to a new MAJOR release (e.g., "1.0.0" or
appropriate next major) to signal the breaking change; modify the version field
in Cargo.toml to the new MAJOR version and ensure any related CI/release
metadata that reads the version is updated to match.
🤖 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 `@CHANGELOG.md`:
- Around line 13-14: Update the `[Unreleased]` compare-link in the CHANGELOG
footer so it no longer points to `v0.6.0...HEAD`; replace the old tag portion
with the new release tag (e.g., `vX.Y.Z...HEAD`) so the `[Unreleased]` link
correctly compares the new tag to HEAD. Locate the `[Unreleased]` link in the
footer (the compare URL currently containing `v0.6.0...HEAD`) and update it to
`vX.Y.Z...HEAD`, ensuring the bracketed `[Unreleased]` text remains unchanged.

---

Duplicate comments:
In `@Cargo.toml`:
- Around line 2-3: The crate rename in Cargo.toml changes the published package
identity (name = "runner-run") which is a breaking change, so update the version
string from "0.7.0" to a new MAJOR release (e.g., "1.0.0" or appropriate next
major) to signal the breaking change; modify the version field in Cargo.toml to
the new MAJOR version and ensure any related CI/release metadata that reads the
version is updated to match.
🪄 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: efcc71f0-539e-4ddb-a3e2-ff1c0099a799

📥 Commits

Reviewing files that changed from the base of the PR and between 72ebf53 and 8a785e0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • CHANGELOG.md
  • Cargo.toml
📜 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). (5)
  • GitHub Check: verify
  • GitHub Check: Workers Builds: runner
  • GitHub Check: Analyze (actions)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (rust)
🧰 Additional context used
📓 Path-based instructions (2)
@(package.json|pyproject.toml|setup.py|Cargo.toml|go.mod|pom.xml|build.gradle|VERSION)

📄 CodeRabbit inference engine (Custom checks)

@(package.json|pyproject.toml|setup.py|Cargo.toml|go.mod|pom.xml|build.gradle|VERSION): If any source code files (excluding tests, docs, CI, markdown, or comments-only changes) are modified, then a version field MUST be updated in one of the following files if present in the repo: package.json, pyproject.toml, setup.py, Cargo.toml, go.mod, pom.xml, build.gradle, or a VERSION file.
The new version MUST follow SemVer (MAJOR.MINOR.PATCH). If the PR introduces breaking changes (removal or renaming of public APIs, changes to function signatures, deleted exported symbols, or incompatible config changes), MAJOR must increment. If it adds backward-compatible functionality, MINOR must increment. If it only fixes bugs without changing public APIs, PATCH must increment.

Files:

  • Cargo.toml
**/CHANGELOG.md

📄 CodeRabbit inference engine (Custom checks)

**/CHANGELOG.md: If any source code files (excluding tests, docs, CI, markdown, or comments-only changes) are modified, CHANGELOG.md MUST also be modified in the same PR.
If a version bump is detected, CHANGELOG.md MUST contain a new section header matching the exact new version number in the format: '## [X.Y.Z] - YYYY-MM-DD'.
If NO version bump is detected, the changes in the PR MUST be added under the existing '## [Unreleased]' section in CHANGELOG.md. The entry MUST describe the changes (e.g., Added, Changed, Fixed, Removed).

Files:

  • CHANGELOG.md
🧠 Learnings (1)
📚 Learning: 2026-03-26T16:14:15.754Z
Learnt from: kjanat
Repo: kjanat/runner PR: 1
File: src/tool/go_task.rs:64-81
Timestamp: 2026-03-26T16:14:15.754Z
Learning: If code uses let-chains (e.g., `if let Some(x) = foo && ... && let Some(y) = bar`), ensure the crate’s `Cargo.toml` sets `package.edition = "2024"`. Rust 2021/earlier should not be used with let-chains; require 2024 specifically for compilation.

Applied to files:

  • Cargo.toml
🔇 Additional comments (1)
Cargo.toml (1)

28-30: Good call: [lib] name = "runner" preserves import compatibility.

Nice move — this keeps existing runner::... paths stable while publishing under runner-run.

Comment thread CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants