ci: use draft releases to support immutable GitHub releases#516
ci: use draft releases to support immutable GitHub releases#516keelerm84 wants to merge 12 commits into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…table-releases # Conflicts: # .github/workflows/manual-sdk-release-artifacts.yml # .github/workflows/release-please.yml
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 247deb4. Configure here.
| "CMakeLists.txt" | ||
| ] | ||
| ], | ||
| "force-tag-creation": true |
There was a problem hiding this comment.
DynamoDB package missing draft
Medium Severity
This change adds "draft": true for other releasable SDK packages but leaves libs/server-sdk-dynamodb-source without it. When release-please cuts that package, GitHub can publish the release immediately while release-please.yml still has no artifact or publish jobs for DynamoDB, so binaries may only arrive via the manual workflow after the release is already immutable.
Reviewed by Cursor Bugbot for commit 247deb4. Configure here.


Summary
Migrates the release workflow to support GitHub's immutable releases feature. Once a release is published it can no longer be modified, so we now create releases in draft state, upload all artifacts, and only then publish.
Changes across three files:
release-please-config.json— Added top-level"draft": trueso release-please creates draft releases for all packages. Added"force-tag-creation": trueto every package (not yet supported by release-please, but included for forward compatibility).release-please.yml— Split release-please pattern — release-please is now invoked twice within the same job:skip-github-pull-request: true— only creates releases (no PRs).skip-github-release: true— only creates/updates PRs, and only runs if no releases were created. This ordering ensures tags exist before release-please checks whether a release PR is still needed.release-client,release-server, etc.) now depend only onrelease-please(the former separatecreate-tagsjob has been removed).googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38(v4.4.0).actions/attest@v4— Removed all 7 SLSA provenance jobs (release-{client,server,server-redis}-provenance,release-{client,server,server-redis}-mac-arm64-provenance, plus 2 in the manual workflow). Replaced with inlineactions/attest@v4steps in each build job that decode the base64 hashes into a checksums file and attest in-place.publish-release-*jobs — Three new jobs (publish-release-client,publish-release-server,publish-release-server-redis) that un-draft their respective release only after all artifact jobs complete.manual-sdk-release-artifacts.yml—publish_releaseinput — Added apublish_releaseboolean input (default:true) and apublish-releasejob gated on it, so operators can optionally keep the release in draft after manual artifact uploads.Review & Testing Checklist for Human
ifcondition on the second call correctly uses!= 'true'with&&across all 4 packages.needsarrays inpublish-release-*jobs: Verify each publish job waits on ALL artifact-uploading jobs for that package before un-drafting. A missing dependency means the release gets published before all artifacts are uploaded — the exact problem we're solving. For example,publish-release-clientneeds bothrelease-client(3-OS matrix) andrelease-client-mac-arm64.release-pleasecreates a tag for server-otel if released, and"draft": truemeans release-please creates a draft release, but there is nopublish-release-server-oteljob to un-draft it. If server-otel has no artifact uploads this is fine — but confirm the draft release won't stay stuck.actions/attest@v4(unpinned): The attest action is referenced by major version tag, not a pinned SHA. Verify this aligns with the repo's policy on action pinning (other actions like checkout are SHA-pinned).publish_release: falseto verify the release stays in draft.Notes
ld-relay(commit 1581de9). The key insight is that release-please depends on the tag existing when determining if a release PR is still needed — so tags must be created between the release step and the PR step.${{ github.repository }}expression appears inrun:blocks (tag creation and publish-release jobs). This value is GitHub-controlled (not user input) so script injection risk is negligible, but worth noting since tag names are deliberately routed through env vars.force-tag-creationhas no effect with the current release-please version — it is a forward-compatibility placeholder that will take effect once release-please supports it, at which point the inline tag creation steps can be removed.manual-sdk-release-artifacts.yml'spublish_releasedefaults totrueforworkflow_dispatch, matching the expectation that manual runs typically want to finalize the release.Link to Devin session: https://app.devin.ai/sessions/7d5bda4d9dbe4ae0b950b30a50485e60
Requested by: @keelerm84
Note
Medium Risk
Changes release publishing order and provenance mechanism; a wrong
needs/ifcould publish before artifacts upload or leave releases stuck in draft.Overview
Supports immutable GitHub releases by creating releases as drafts, uploading artifacts while still editable, then publishing only after builds finish.
release-please-config.jsonsetsdraft: trueon client, server, redis, and otel packages and addsforce-tag-creation: trueacross packages so tags can be created before draft releases (aligned with release-please v5).release-please.ymlbumps to release-please-action v5.0.0, drops separate SLSA provenance jobs and per-job hash outputs, and instead decodes platform hash outputs intochecksums.txtand runsactions/attestin each matrix/arm64 build job (withcontents/attestations/id-tokenpermissions). Newpublish-release-*jobs callgh release edit --draft=falseafter artifact jobs complete (including server-otel with no artifact jobs).manual-sdk-release-artifacts.ymlmirrors inline attestation, adds optionalpublish_release(default true) and a gatedpublish-releasejob after uploads.Reviewed by Cursor Bugbot for commit 247deb4. Bugbot is set up for automated code reviews on this repo. Configure here.