Skip to content

fix(ci): recover missing Rust GitHub releases and improve crates.io publish resilience#263

Merged
konard merged 5 commits into
mainfrom
issue-261-72c724284fb2
Apr 14, 2026
Merged

fix(ci): recover missing Rust GitHub releases and improve crates.io publish resilience#263
konard merged 5 commits into
mainfrom
issue-261-72c724284fb2

Conversation

@konard
Copy link
Copy Markdown
Contributor

@konard konard commented Apr 13, 2026

Summary

Fixes #261 - Rust CI/CD was publishing crates to crates.io but failing to create GitHub releases with badges.

Root Cause

A chain of CI/CD failures led to v0.9.2 being published on crates.io but without a GitHub release:

  1. Run 24328743522: CARGO_REGISTRY_TOKEN not set (fixed in PR fix(ci): use CARGO_TOKEN as fallback for CARGO_REGISTRY_TOKEN in Rust CI/CD #258)
  2. Run 24334488286: Crate published successfully, but 5s verification delay was too short. Retries got "already exists" but old code didn't handle it as success
  3. Run 24337999712: Fix merged, but changelog fragments already consumed and tag existed → skipped everything including GitHub release creation

The core problem: no recovery mechanism for partially-completed releases. Once the CI pipeline failed after publishing to crates.io but before creating a GitHub release, there was no way to recover on the next run.

Changes

.github/workflows/rust.yml

  • Add pre-release recovery step: before checking fragments, detect orphaned versions (tag exists + no GitHub release) and create the missing release
  • Use crates.io API as source of truth for publish status (alongside git tags and GitHub release checks)
  • Recovery handles the v0.9.2 case: when this PR merges, the first thing the Rust CI does is create the missing v0.9.2 release

scripts/publish-to-crates.mjs

  • Check crates.io API before each retry attempt (detect if prior attempt actually succeeded despite verification failure)
  • Increase verification delay from 15s to 20s and retries from 3 to 5

docs/case-studies/issue-261/

  • Full case study with timeline, root cause analysis, and learnings

Changelog fragments

  • Rust changelog fragment for CI/CD recovery fix
  • JS changeset for publish script improvements

How to verify

  1. When this PR merges, the Rust CI will run and the recovery step will create the missing rust-v0.9.2 GitHub release with crates.io badge
  2. The new changelog fragment will trigger a v0.9.3 release with its own GitHub release
  3. Both releases should have crates.io badges and proper formatting

Test plan

  • YAML syntax validation passes
  • JS changeset validation passes (validate-changeset.mjs)
  • Rust changelog fragment validation passes (rust-get-bump-type.mjs)
  • File size check passes (check-file-size.mjs)
  • CI checks pass on PR
  • After merge: v0.9.2 GitHub release created by recovery step
  • After merge: v0.9.3 published to crates.io with GitHub release

This PR was created to solve issue #261

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: #261
@konard konard self-assigned this Apr 13, 2026
@konard
Copy link
Copy Markdown
Contributor Author

konard commented Apr 13, 2026

🚨 Solution Draft Failed

The automated solution draft encountered an error:

CLAUDE execution failed

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.6 (claude-opus-4-6)

📎 Failure log uploaded as Gist (1538KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented Apr 13, 2026

🤖 AI Work Session Started

Starting automated work session at 2026-04-13T15:38:22.250Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback.

konard and others added 3 commits April 13, 2026 15:48
…io publish resilience

Root cause: When crates.io publish succeeds but verification fails due to
propagation delay, retries get "already exists" error. While handled in
current code, the GitHub release was never created because the publish step
exited with failure. On the next CI run, changelog fragments were already
consumed and the tag existed, so the release check saw "already released"
and skipped everything — leaving the version published on crates.io but
with no GitHub release.

Changes:
- rust.yml: Check crates.io API + GitHub release existence (not just git
  tags) when deciding whether to release. This enables recovery when a
  version is published on crates.io but the GitHub release is missing.
- publish-to-crates.mjs: Check crates.io API before each retry attempt to
  detect if a prior attempt actually succeeded despite verification failure.
  Increase verification delay to 20s and retries to 5 for better resilience
  against crates.io propagation delays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Case study documenting timeline, root causes, and fixes for the missing
  Rust GitHub release issue
- Rust changelog fragment for the CI/CD recovery mechanism fix
- JS changeset for publish script improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When changelog fragments exist for a new version bump, the previous
version's missing GitHub release would never be created. This adds
a recovery step that runs BEFORE the fragment check to detect and
create any missing GitHub releases for the current Cargo.toml version.

This handles the v0.9.2 case: tag exists, crate on crates.io, but
GitHub release was never created due to prior CI failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard konard changed the title [WIP] Something wrong with CI/CD for Rust (no crates release, no GitHub release) fix(ci): recover missing Rust GitHub releases and improve crates.io publish resilience Apr 13, 2026
@konard konard marked this pull request as ready for review April 13, 2026 15:54
@konard
Copy link
Copy Markdown
Contributor Author

konard commented Apr 13, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $6.031028

📊 Context and tokens usage:

Claude Opus 4.6:

  • Context window: 147.9K / 1M (15%) input tokens, 24.5K / 128K (19%) output tokens

Total: (150.0K + 8.4M cached) input tokens, 24.5K output tokens, $5.768872 cost

Claude Haiku 4.5:

Total: (121.2K + 699.2K cached) input tokens, 8.2K / 64K (13%) output tokens, $0.262156 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Main model: Claude Opus 4.6 (claude-opus-4-6)
  • Additional models:
    • Claude Haiku 4.5 (claude-haiku-4-5-20251001)

📎 Log file uploaded as Gist (3089KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented Apr 13, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard konard merged commit af7bf31 into main Apr 14, 2026
16 checks passed
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.

Something wrong with CI/CD for Rust (no crates release, no GitHub release)

1 participant