Repository navigation
ci: Publish to crates.io on version bump - #19
Conversation
📝 WalkthroughWalkthroughAdds 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. ChangesCrate release
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
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
.github/workflows/publish.yaml
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 |
There was a problem hiding this comment.
🔒 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
fiRepository: 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"
doneRepository: 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:
- 1: https://github.com/rust-lang/crates-io-auth-action
- 2: https://github.com/marketplace/actions/crates-io-auth-action
- 3: https://github.com/rust-lang/crates-io-auth-action/releases/tag/v1.0.4
- 4: https://github.com/rust-lang/crates-io-auth-action/releases
- 5: rust-lang/crates-io-auth-action@v1.0.4...v1.0.5
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.
| if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then | ||
| echo "Invalid release tag: $tag" | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
🎯 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 || trueRepository: 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 || trueRepository: 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 || trueRepository: 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])
PYRepository: 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:
- 1: https://doc.rust-lang.org/stable/cargo/reference/manifest.html
- 2: https://doc.rust-lang.org/cargo/reference/manifest.html
- 3: https://www.rustprojectprimer.com/releasing/versioning.html
- 4: https://doc.rust-lang.org/1.47.0/cargo/reference/resolver.html
- 5: Cargo doesn't understand build metadata in versions rust-lang/cargo#2939
- 6: https://doc.rust-lang.org/stable/cargo/commands/cargo-metadata.html
- 7: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html
- 8: Add a small note about indexes ignoring SemVer build metadata. rust-lang/cargo#12206
🏁 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)
PYRepository: 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)
PYRepository: 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.
Automatically publishes a new release to crates.io when on version bump when a new tag is pushed.
Summary by CodeRabbit