Skip to content

ci: Publish to crates.io on version bump - #19

Merged
EthanPlant merged 1 commit into
mainfrom
auto-release
Aug 2, 2026
Merged

EthanPlant merged 1 commit into
mainfrom
auto-release

Conversation

@EthanPlant

@EthanPlant EthanPlant commented Aug 2, 2026 •

Copy link
Copy Markdown
Owner

Automatically publishes a new release to crates.io when on version bump when a new tag is pushed.

Summary by CodeRabbit

  • Chores
    • Added an automated release workflow triggered by version tags.
    • Releases now validate package versions, run tests, verify packaging, and publish to the package registry.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a GitHub Actions workflow that runs on version tags. It validates the tag and Cargo package version, runs tests and packaging checks, authenticates with crates.io through OIDC, and publishes the crate.

Changes

Crate release

Layer / File(s) Summary
Workflow trigger and runtime setup
.github/workflows/publish.yaml
The workflow runs for pushed v* tags, sets read-only repository access and OIDC permissions, checks out the repository, and reports Rust and Cargo versions.
Release validation and publication
.github/workflows/publish.yaml
The workflow validates the semantic release tag against the elsewhere package version, runs locked tests and package verification, authenticates with crates.io, and publishes the crate.

Estimated code review effort: 3 (Moderate) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant Cargo
  participant CratesIO
  GitHubActions->>GitHubActions: Trigger on a pushed version tag
  GitHubActions->>Cargo: Validate tag and package version
  GitHubActions->>Cargo: Run locked tests and package verification
  GitHubActions->>CratesIO: Authenticate with OIDC
  GitHubActions->>CratesIO: Publish the crate with registry token
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the added CI workflow that publishes versioned releases to crates.io.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch auto-release

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/publish.yaml:
- Line 24: Update the actions/checkout and rust-lang/crates-io-auth-action
references in the publish workflow to reviewed full commit SHAs instead of
floating version tags, and retain each current version tag as an inline comment
for traceability.
- Around line 40-43: Replace the independent regex validation in the release-tag
workflow with a direct comparison between GITHUB_REF_NAME and
"v${cargo_version}" after cargo metadata succeeds. Use the Cargo-derived version
as the sole validity check, while retaining the existing invalid-tag message and
exit behavior.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c66694e1-69b8-4457-8388-5d83f0138cb7

📥 Commits

Reviewing files that changed from the base of the PR and between 05b9d52 and cab6ab4.

📒 Files selected for processing (1)
  • .github/workflows/publish.yaml


steps:
- name: Checkout repository
uses: actions/checkout@v6

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/publish.yaml
printf '%s\n' '--- action references ---'
rg -n 'uses:|permissions:|on:|tags:|publish' .github/workflows/publish.yaml
printf '%s\n' '--- repository metadata ---'
if [ -f Cargo.toml ]; then
  rg -n '^(name|version)\s*=' Cargo.toml
fi

Repository: EthanPlant/Elsewhere

Length of output: 2927


🏁 Script executed:

#!/bin/bash
set -eu
for spec in \
  "actions/checkout refs/tags/v6 refs/tags/v6^{}" \
  "rust-lang/crates-io-auth-action refs/tags/v1 refs/tags/v1^{}"
do
  set -- $spec
  printf '%s\n' "--- $1 ---"
  git ls-remote "https://github.com/$1.git" "$2" "$3"
done

Repository: EthanPlant/Elsewhere

Length of output: 277


🏁 Script executed:

#!/bin/bash
set -eu
repo='rust-lang/crates-io-auth-action'
printf '%s\n' '--- repository metadata ---'
curl -fsSL "https://api.github.com/repos/$repo" |
  jq '{full_name, archived, default_branch, html_url}'
printf '%s\n' '--- matching tags ---'
curl -fsSL "https://api.github.com/repos/$repo/tags?per_page=100" |
  jq -r '.[].name' | grep -E '^(v1|v1\.)' || true
printf '%s\n' '--- matching refs ---'
curl -fsSL "https://api.github.com/repos/$repo/git/matching-refs/tags/v1" |
  jq -r '.[] | [.ref, .object.type, .object.sha] | `@tsv`'

Repository: EthanPlant/Elsewhere

Length of output: 377


🌐 Web query:

rust-lang/crates-io-auth-action v1 GitHub tag

💡 Result:

The GitHub repository rust-lang/crates-io-auth-action supports using @v1 as a floating tag for its GitHub Action [1][2]. This tag automatically tracks the latest minor and patch releases within the v1 release series. As of August 2, 2026, the project has released multiple versions within the v1 series, such as v1.0.4 [3][2] and v1.0.5 [4][5]. In GitHub Actions, pointing to @v1 ensures that your workflow utilizes the most recent stable release associated with that major version [1].

Citations:


Pin both release actions to full commit SHAs.

actions/checkout@v6 and rust-lang/crates-io-auth-action@v1 are floating tags. A tag update can change the code that checks out release source or exchanges the OIDC token. Use reviewed full commit SHAs and retain the version tags in comments.

🤖 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/publish.yaml at line 24, Update the actions/checkout and
rust-lang/crates-io-auth-action references in the publish workflow to reviewed
full commit SHAs instead of floating version tags, and retain each current
version tag as an inline comment for traceability.

Comment on lines +40 to +43
if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid release tag: $tag"
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/publish.yaml | sed -n '1,90p'
printf '%s\n' '--- manifests ---'
git ls-files '*Cargo.toml' | while IFS= read -r f; do
  echo "### $f"
  rg -n '^(name|version)\s*=' "$f" || true
done
printf '%s\n' '--- version/tag handling ---'
rg -n -S 'GITHUB_REF_NAME|cargo metadata|release tag|version|semver' .github Cargo.toml '**/Cargo.toml' 2>/dev/null || true
printf '%s\n' '--- available tools ---'
command -v cargo || true

Repository: EthanPlant/Elsewhere

Length of output: 150


🏁 Script executed:

#!/bin/bash
printf '%s\n' '--- workflow ---'
sed -n '1,90p' .github/workflows/publish.yaml
printf '%s\n' '--- Cargo manifests ---'
fd -HI -t f 'Cargo\.toml$' . --exclude node_modules --exclude target | head -50
printf '%s\n' '--- version declarations ---'
rg -n --glob 'Cargo.toml' '^(name|version)\s*=' . || true
printf '%s\n' '--- tool availability ---'
command -v cargo || true

Repository: EthanPlant/Elsewhere

Length of output: 150


🏁 Script executed:

#!/bin/bash
timeout 10s sed -n '1,90p' .github/workflows/publish.yaml
printf '%s\n' '--- root entries ---'
timeout 10s find . -maxdepth 2 -name Cargo.toml -print
printf '%s\n' '--- manifest versions ---'
timeout 10s grep -R -n --include='Cargo.toml' -E '^(name|version)[[:space:]]*=' . | head -50 || true

Repository: EthanPlant/Elsewhere

Length of output: 328


🏁 Script executed:

#!/bin/bash
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/publish.yaml")
print(p.stat())
print(p.read_text()[:6000])
PY

Repository: EthanPlant/Elsewhere

Length of output: 2196


🌐 Web query:

Cargo manifest package version build metadata cargo metadata version output SemVer plus build metadata

💡 Result:

In Cargo, the version field within the Cargo.toml manifest adheres to the Semantic Versioning (SemVer) specification, which allows for an optional build metadata suffix denoted by a plus sign (e.g., 1.0.0+21AF26D3) [1][2][3]. However, Cargo's treatment of this metadata is strictly informational: - Cargo ignores build metadata when performing dependency resolution and version comparison [4][3]. Versions that differ only by their build metadata are considered identical by Cargo [3]. - You should not rely on build metadata in version requirements; using it in such a context is generally not supported or effectively unusable for dependency selection [4][5]. - When you run the cargo metadata command, the version information provided in the resulting JSON output will include the build metadata if it is defined in the manifest, but it remains irrelevant to Cargo's internal logic for graph resolution and build planning [6][7]. Because Cargo ignores this part of the version string, it is intended solely for external purposes, such as embedding information about the build environment (e.g., git commit hashes, CI job IDs, or downstream library versions) [3]. Note that because Cargo and registry indexes often treat this metadata as negligible or redundant, publishing multiple versions of the same crate that differ only by build metadata is discouraged and may be restricted by registries like crates.io to maintain version uniqueness [4][8][3].

Citations:


🏁 Script executed:

#!/bin/bash
python3 - <<'PY'
import json
import re
from pathlib import Path

workflow = Path(".github/workflows/publish.yaml").read_text()
pattern = re.compile(r"^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$")
for tag in ("v1.2.3", "v1.2.3-alpha.1", "v1.2.3+build.1"):
    print(tag, bool(pattern.fullmatch(tag)))

for path in (Path("Cargo.toml"),):
    if path.exists():
        print(f"--- {path} ---")
        for line_no, line in enumerate(path.read_text().splitlines(), 1):
            if re.match(r"^\s*(name|version)\s*=", line):
                print(f"{line_no}: {line}")

print("--- workflow ordering ---")
print("regex_before_metadata:", workflow.index("if [[ !") < workflow.index("cargo metadata"))
print("direct_tag_comparison_present:", 'tag_version" != "$cargo_version"' in workflow)
PY

Repository: EthanPlant/Elsewhere

Length of output: 150


🏁 Script executed:

#!/bin/bash
python3 - <<'PY'
import re
from pathlib import Path

workflow = Path(".github/workflows/publish.yaml").read_text()
pattern = re.compile(r"^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$")
for tag in ("v1.2.3", "v1.2.3-alpha.1", "v1.2.3+build.1"):
    print(tag, bool(pattern.fullmatch(tag)))

for path in (Path("Cargo.toml"),):
    if path.exists():
        print(f"--- {path} ---")
        for line_no, line in enumerate(path.read_text().splitlines(), 1):
            if re.match(r"^\s*(name|version)\s*=", line):
                print(f"{line_no}: {line}")

print("--- workflow ordering ---")
print("regex_before_metadata:", workflow.index("if [[ !") < workflow.index("cargo metadata"))
print("direct_tag_comparison_present:", 'tag_version" != "$cargo_version"' in workflow)
PY

Repository: EthanPlant/Elsewhere

Length of output: 150


Derive tag validity from the Cargo version.

The regex rejects valid Cargo versions with SemVer build metadata, such as v1.2.3+build.1. Remove the independent regex check and compare GITHUB_REF_NAME directly with "v${cargo_version}" after cargo metadata succeeds.

🤖 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/publish.yaml around lines 40 - 43, Replace the independent
regex validation in the release-tag workflow with a direct comparison between
GITHUB_REF_NAME and "v${cargo_version}" after cargo metadata succeeds. Use the
Cargo-derived version as the sole validity check, while retaining the existing
invalid-tag message and exit behavior.

@EthanPlant
EthanPlant merged commit 19f0b46 into main Aug 2, 2026
7 checks passed
@EthanPlant
EthanPlant deleted the auto-release branch August 3, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant