Commit 59e7fd1
authored
ci: switch from SLSA provenance to actions/attest with subject-path (#19)
**Requirements**
- [x] I have added test coverage for new or changed functionality
- [x] I have followed the repository's [pull request submission
guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests)
- [x] 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:
- [x] ~~**`tag` input is declared but unused**~~: Now resolved — the
`tag` input was removed entirely.
- [x] ~~**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: @keelerm841 parent 84b7aca commit 59e7fd1
4 files changed
Lines changed: 16 additions & 39 deletions
File tree
- .github
- actions/publish
- workflows
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | 7 | | |
12 | 8 | | |
13 | 9 | | |
| |||
16 | 12 | | |
17 | 13 | | |
18 | 14 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | 15 | | |
26 | 16 | | |
27 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
| 17 | + | |
19 | 18 | | |
20 | 19 | | |
21 | 20 | | |
| |||
37 | 36 | | |
38 | 37 | | |
39 | 38 | | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 15 | + | |
19 | 16 | | |
20 | 17 | | |
21 | 18 | | |
| |||
51 | 48 | | |
52 | 49 | | |
53 | 50 | | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
0 commit comments