Skip to content

ci: gate crate publishing on unpublished versions#690

Open
MicaiahReid wants to merge 1 commit into
mainfrom
ci-gate-crate-publishing
Open

ci: gate crate publishing on unpublished versions#690
MicaiahReid wants to merge 1 commit into
mainfrom
ci-gate-crate-publishing

Conversation

@MicaiahReid

Copy link
Copy Markdown
Collaborator

Add an unprotected release preparation job that checks the configured crate versions before entering the protected release environment. Skip the publish job when every crate version is already on crates.io so ordinary main merges do not create deployment approval requests.

Add an unprotected release preparation job that checks the configured
crate versions before entering the protected release environment. Skip
the publish job when every crate version is already on crates.io so
ordinary main merges do not create deployment approval requests.
@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR gates the protected publish job on a new unprotected prepare_release job that checks each configured crate version against the crates.io API before requesting the release environment approval. Ordinary main merges where all crate versions are already published will now exit cleanly without triggering a deployment approval request.

  • New prepare_release job: runs on every trigger without the release environment, queries crates.io for each crate, and writes should_publish and crates outputs; the job exits with an error if crates.io returns an unexpected response after three retries.
  • Gated publish job: now depends on prepare_release and runs only when should_publish == 'true'; it preserves its own crates.io re-check so crates published by a concurrent run between the two jobs are safely skipped.
  • Code duplication: the check_crates_io bash function is defined identically in both jobs because each runs on a separate runner; any future changes to retry logic or headers need to be applied in two places.

Confidence Score: 4/5

Safe to merge — the core gating logic is correct and the publish job retains its own crates.io re-check as a safety net against race conditions between jobs.

The two-job design works as intended: ordinary main merges skip the approval gate, and only genuine new versions trigger the release environment. The two findings are non-blocking: the check_crates_io function duplication is a maintenance concern, and the HTTP-200-without-.version edge case is an unlikely crates.io API quirk that would surface as a clear build failure rather than a silent mispublish.

.github/workflows/release_crates.yaml — the check_crates_io function defined in both jobs should be kept in sync if retry or header logic changes.

Important Files Changed

Filename Overview
.github/workflows/release_crates.yaml Adds a new unprotected prepare_release job that queries crates.io to determine whether any crates need publishing before entering the protected release environment. The publish job is now gated on should_publish == 'true', preventing spurious approval requests on plain main merges. Logic is sound; two P2 style concerns: the check_crates_io function is duplicated verbatim between both jobs, and a HTTP 200 response without a .version key will trigger the error exit path rather than a more descriptive fallback.

Sequence Diagram

sequenceDiagram
    participant GH as GitHub Actions
    participant PR as prepare_release job
    participant CIO as crates.io API
    participant PUB as publish job (release env)

    GH->>PR: trigger (push to main / workflow_dispatch)
    PR->>PR: resolve crate list (input or default)
    loop for each crate
        PR->>CIO: "GET /api/v1/crates/{crate}/{version}"
        CIO-->>PR: 200 (already published) or 404 (new version)
        Note over PR: retries up to 3x on transient errors
    end
    PR->>PR: write should_publish and crates to GITHUB_OUTPUT

    alt "should_publish == 'true'"
        GH->>PUB: trigger (requires release environment approval)
        loop for each crate
            PUB->>CIO: "GET /api/v1/crates/{crate}/{version}"
            CIO-->>PUB: 200 (skip) or 404 (publish)
            PUB->>PUB: "cargo publish --package {crate}"
        end
    else "should_publish == 'false'"
        Note over GH: publish job skipped — no approval request
    end
Loading

Reviews (1): Last reviewed commit: "ci: gate crate publishing on unpublished..." | Re-trigger Greptile

Comment thread .github/workflows/release_crates.yaml
Comment thread .github/workflows/release_crates.yaml

@lgalabru lgalabru left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

❤️

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.

2 participants