Skip to content

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

Merged
keelerm84 merged 9 commits into
mainfrom
devin/1774991564-immutable-releases
Apr 2, 2026
Merged

ci: switch from SLSA provenance to actions/attest with subject-path#19
keelerm84 merged 9 commits into
mainfrom
devin/1774991564-immutable-releases

Conversation

@keelerm84

@keelerm84 keelerm84 commented Mar 31, 2026

Copy link
Copy Markdown
Member

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 affected.

Related issues

Supports the org-wide migration to immutable GitHub releases. Reference implementation: launchdarkly/ld-relay.

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, not as release assets. This PR makes the following changes:

  1. Replace SLSA generator with actions/attest@v4 (release-please.yml, manual-publish.yml): The separate release-provenance job using slsa-framework/slsa-github-generator (which uploaded .intoto.jsonl files as release assets via upload-assets: true) is removed in both workflows. Attestation is now done inline via actions/attest@v4 with subject-path, referencing the built gem file directly (launchdarkly-server-sdk-otel-*.gem). The attestations: write permission is added to the build jobs.

  2. Remove base64 hash round-trip (.github/actions/publish/action.yml): The gem-hash output and "Hash gem for provenance" step are removed from the composite action. The old SLSA generator required base64-subjects, which meant the composite action had to sha256sum | base64 -w0 and the workflow had to decode it back. With subject-path, actions/attest@v4 reads the file directly from disk — no hashing or encoding needed.

  3. Remove orphaned job outputs (release-please.yml): The release-created, upload-tag-name, and gem-hash outputs on the release-package job were only consumed by the now-removed release-provenance job. They have been cleaned up.

  4. Update provenance documentation (PROVENANCE.md): Replaced SLSA verifier instructions with gh attestation verify instructions and updated sample output to reflect GitHub artifact attestations. The x-release-please-start-version marker is preserved so release-please keeps the version in sync.

  5. Cosmetic: The extra-files array in release-please-config.json was reformatted from inline to multi-line.

Key points for review:

  • Verify that the glob launchdarkly-server-sdk-otel-*.gem matches the gem built by gem build launchdarkly-server-sdk-otel.gemspec in the composite action (the gem is built in the workspace root, and the attest step runs in the same job).
  • release-please.yml gates the attest step on releases_created (plural) — this is the correct aggregate output for manifest mode. The manual publish workflow gates on format('{0}', inputs.dry_run) == 'false' to handle both boolean and string input types.
  • No way to test actions/attest on a feature branch since it requires a real release context. A dry-run dispatch can confirm the guard prevents attestation from running.

Updates since last revision

  • Switched attestation input from subject-checksums: checksums.txt to subject-path: 'launchdarkly-server-sdk-otel-*.gem', eliminating the base64 encode/decode round-trip entirely.
  • Removed gem-hash output and "Hash gem for provenance" step from .github/actions/publish/action.yml.
  • Removed "Generate checksums file" step from workflows (no longer needed).
  • Removed unused tag input from manual-publish.yml (was added for consistency but never referenced by any step).
  • Removed orphaned release-created and upload-tag-name outputs from release-please.yml (their sole consumer, the release-provenance job, was removed).
  • Reverted the split release-please pattern (two-pass skip-github-pull-request / skip-github-release) that was briefly added. This pattern is only needed for repos that upload artifacts to releases (which require draft releases). Since this repo is attestation-only, the standard single-pass release-please is correct.

Describe alternatives you've considered

  • An earlier revision used subject-checksums with a checksums file generated by decoding base64-encoded hashes from the composite action. subject-path is simpler since the gem file is already on disk in the same job.
  • An earlier revision used draft releases with a publish-release job to un-draft after completion. This was simplified since this repo only uses attestation (not artifact uploads), making draft releases unnecessary.

Additional context

No build/publish logic was changed — only the provenance mechanism (SLSA → actions/attest with subject-path) and release-please config formatting were modified. The format('{0}', inputs.dry_run) pattern stringifies the input regardless of source type, ensuring == 'false' works for both workflow_call (boolean) and workflow_dispatch (string) triggers.

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 PR created by Devin label Mar 31, 2026
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
@kinyoklion kinyoklion marked this pull request as ready for review April 1, 2026 17:55
@kinyoklion kinyoklion requested a review from a team as a code owner April 1, 2026 17:55
@keelerm84 keelerm84 merged commit 567c92f into main Apr 2, 2026
10 checks passed
@keelerm84 keelerm84 deleted the devin/1774991564-immutable-releases branch April 2, 2026 16:40
@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 Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devin-pr PR created by Devin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants