Skip to content

ci: switch from SLSA provenance to actions/attest with subject-path#19

Merged
kinyoklion merged 7 commits intomainfrom
devin/1774991583-immutable-releases
Apr 1, 2026
Merged

ci: switch from SLSA provenance to actions/attest with subject-path#19
kinyoklion merged 7 commits intomainfrom
devin/1774991583-immutable-releases

Conversation

@keelerm84
Copy link
Copy Markdown
Member

@keelerm84 keelerm84 commented Mar 31, 2026

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

N/A — CI-only changes, no application code or tests modified.

Related issues

Supports the org-wide migration to immutable GitHub releases. Once a release is published, it can no longer be modified, which breaks workflows that upload artifacts after release-please publishes the release.

Describe the solution you've provided

Since this repo only uses attestation (no binary/artifact uploads to the release), draft releases are not needed — actions/attest@v4 stores attestations via GitHub's attestation API rather than as release assets. This PR makes the following changes:

  1. Replace SLSA with actions/attest@v4 using subject-path (both workflows): Removed the separate release-provenance job that used slsa-framework/slsa-github-generator (which uploaded .intoto.jsonl files as release assets via upload-assets: true) and replaced it with inline actions/attest@v4 steps within the build job. Attestation uses subject-path: 'launchdarkly-openfeature-server-sdk-*.gem' to reference the built gem file directly on disk — no hash computation, base64 encoding, or checksums file needed. Added attestations: write permission. Removed gem-hash job output entirely.

  2. Removed hash plumbing from composite action (.github/actions/publish/action.yml): Removed the gem-hash output and "Hash gem for provenance" step. These existed to produce base64-encoded checksums for the old SLSA generator and are no longer needed since subject-path lets actions/attest@v4 read files directly from disk.

  3. Cleaned up orphaned declarations: Removed the unused tag input from manual-publish.yml (was declared but never referenced by any step, with a stale "draft release" description). Removed orphaned release-created and upload-tag-name job outputs from release-please.yml — their sole consumer was the removed release-provenance job.

  4. release-please-config.json: Reformatted extra-files array to multi-line — no functional changes.

Why no draft releases?

The old SLSA generator uploaded provenance files as release assets via upload-assets: true, which would fail under immutable releases. The new actions/attest@v4 stores attestations in GitHub's attestation API instead — it does not modify the GitHub release. Since this repo has no other artifact uploads, release-please can publish directly without a draft→un-draft flow. Repos that upload actual binaries (e.g. ld-relay, cpp-sdks) still use draft releases.

Updates since last revision

  • Removed unused tag input from manual-publish.yml and orphaned release-created / upload-tag-name outputs from release-please.yml. These were dead declarations left behind when the release-provenance job and draft-release machinery were removed. (Addresses Cursor Bugbot findings.)

Describe alternatives you've considered

  • Draft release pattern: An earlier revision used draft releases with a publish-release job to un-draft after completion. This was simplified after determining that attestation-only repos don't need draft releases since actions/attest@v4 doesn't modify the release.
  • subject-checksums: An intermediate revision decoded base64 hashes into a checksums file for actions/attest. This worked but was unnecessarily complex — the gem file is already on disk in the same job, so subject-path references it directly.

Additional context

Key review points:

  • tag input is declared but unused: Now resolved — the tag input was removed entirely.
  • No dry_run guard on attestation in manual-publish.yml: Now resolved — the attest step is gated on !inputs.dry_run.
  • Glob pattern correctness: Verify subject-path: 'launchdarkly-openfeature-server-sdk-*.gem' matches the gem produced by gem build launchdarkly-openfeature-server-sdk.gemspec. The publish action already uses the same pattern for gem push, so this should be consistent — but worth confirming.
  • releases_created vs release_created: In release-please.yml, the attestation step uses steps.release.outputs.releases_created (plural) while the original job-level output used release_created (singular). Both are valid release-please outputs but confirm they behave identically for this single-package repo.
  • contents: read vs contents: write: manual-publish.yml has contents: read while release-please.yml has contents: write. Verify actions/attest@v4 does not require contents: write.
  • Confirm actions/attest@v4 meets compliance requirements: This replaces slsa-framework/slsa-github-generator. Verify the attestation format is acceptable for your supply-chain security needs.

Link to Devin session: https://app.devin.ai/sessions/7d5bda4d9dbe4ae0b950b30a50485e60
Requested by: @keelerm84

@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@devin-ai-integration devin-ai-integration bot added the devin-pr PRs created by Devin label Mar 31, 2026
@kinyoklion kinyoklion marked this pull request as ready for review March 31, 2026 21:45
@kinyoklion kinyoklion requested a review from a team as a code owner March 31, 2026 21:45
Since actions/attest@v4 stores attestations via GitHub's attestation API
(not as release assets), repos that only use attestation don't need draft
releases. Release-please can publish the release directly.

Changes:
- Remove draft:true from release-please-config.json
- Remove create-tag job/steps (force-tag-creation handles this)
- Remove publish-release job (release is published directly)
- Remove publish_release input from manual workflows
@devin-ai-integration devin-ai-integration bot changed the title ci: use draft releases to support immutable GitHub releases ci: switch to actions/attest and add force-tag-creation Mar 31, 2026
force-tag-creation only operates in conjunction with draft releases.
Since this repo does not use draft releases (attestation-only, no
artifact uploads to the release), force-tag-creation is not needed.
@devin-ai-integration devin-ai-integration bot changed the title ci: switch to actions/attest and add force-tag-creation ci: switch from SLSA provenance to actions/attest Mar 31, 2026
Ensures that checksums generation and attestation are skipped during
dry runs, preventing unnecessary attestation of unpublished artifacts.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@devin-ai-integration devin-ai-integration bot changed the title ci: switch from SLSA provenance to actions/attest ci: switch from SLSA provenance to actions/attest with subject-path Mar 31, 2026
@kinyoklion kinyoklion merged commit 59e7fd1 into main Apr 1, 2026
10 checks passed
@kinyoklion kinyoklion deleted the devin/1774991583-immutable-releases branch April 1, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devin-pr PRs created by Devin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants