Skip to content

Commit 0c77208

Browse files
cnolanminichclaude
andcommitted
Document pinned releases: consumer usage and creation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 0a13fc2 commit 0c77208

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

PINNED_RELEASES.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Pinned releases
2+
3+
Pinned releases are variants of regular `dagster-cloud-action` releases in which
4+
every **third-party** GitHub Action reference is pinned to a full commit SHA
5+
instead of a mutable tag:
6+
7+
```yaml
8+
# regular release (v1.13.8)
9+
- uses: actions/checkout@v4
10+
11+
# pinned release (v1.13.8-pinned)
12+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
13+
```
14+
15+
A tag like `actions/checkout@v4` can be re-pointed at any time by whoever
16+
controls that repository; a commit SHA cannot. Pinning closes off the
17+
supply-chain risk of a compromised or hijacked third-party action being pulled
18+
into your deploys.
19+
20+
A pinned release is built from an existing release tag (e.g. `v1.13.8`) and
21+
published as `<base_tag>-pinned` (e.g. `v1.13.8-pinned`). The base tag is never
22+
modified, and the pinned variant reuses the base release's binaries — no
23+
rebuild happens.
24+
25+
## Using a pinned release
26+
27+
### 1. Pick a pinned release and resolve its commit SHA
28+
29+
```bash
30+
# list available pinned tags
31+
git ls-remote --tags https://github.com/dagster-io/dagster-cloud-action 'refs/tags/*-pinned'
32+
33+
# resolve a pinned tag to its commit SHA
34+
gh api repos/dagster-io/dagster-cloud-action/commits/v1.13.8-pinned --jq .sha
35+
```
36+
37+
Note: use the command above (or the commit shown on the release page), not
38+
`git ls-remote`'s tag object SHA — annotated tags have their own SHA distinct
39+
from the commit they point to, and `uses:` needs the **commit** SHA.
40+
41+
### 2. Update your workflow files
42+
43+
In your repository's `.github/workflows/*.yml`, replace each
44+
`dagster-io/dagster-cloud-action` version tag with the commit SHA, keeping the
45+
tag as a comment for readability:
46+
47+
```yaml
48+
# before
49+
- uses: dagster-io/dagster-cloud-action/actions/serverless_prod_deploy@v1.13.8
50+
51+
# after
52+
- uses: dagster-io/dagster-cloud-action/actions/serverless_prod_deploy@83e0bb0323b0a0d136b815d049261bddcbd8963d # v1.13.8-pinned
53+
```
54+
55+
All `actions/...` subpaths use the same SHA — it identifies the whole
56+
repository tree at that release. With `sed`:
57+
58+
```bash
59+
SHA=$(gh api repos/dagster-io/dagster-cloud-action/commits/v1.13.8-pinned --jq .sha)
60+
sed -i '' -E \
61+
"s|(dagster-io/dagster-cloud-action[^@[:space:]]*)@v[0-9][^[:space:]]*|\1@${SHA} # v1.13.8-pinned|" \
62+
.github/workflows/*.yml
63+
```
64+
65+
(On Linux use `sed -i -E ...` without the `''`.)
66+
67+
While you're at it, consider pinning the *other* third-party actions in your
68+
workflows the same way (`actions/checkout`, etc.) —
69+
[`scripts/pin_actions.py`](scripts/pin_actions.py) shows the pattern, and tools
70+
like [zizmor](https://github.com/woodruffw/zizmor) or
71+
[ratchet](https://github.com/sethvargo/ratchet) can do it for arbitrary repos.
72+
73+
### 3. Verify
74+
75+
Trigger a branch deploy (or any workflow run) and confirm it succeeds. The run
76+
logs show each action resolved at the pinned SHA.
77+
78+
## What is and isn't pinned
79+
80+
| Layer | Pinned? |
81+
| --- | --- |
82+
| Your `uses: dagster-io/dagster-cloud-action/...@<SHA>` reference | ✅ immutable commit SHA |
83+
| Third-party actions inside the pinned release | ✅ immutable commit SHAs |
84+
| `dagster-cloud` PEX binaries | ✅ committed files in the pinned tree |
85+
| `ghcr.io/dagster-io/dagster-cloud-action:<version>` Docker image | ⚠️ referenced by version tag, not digest |
86+
87+
The Docker image tag is the one remaining mutable reference; pinning images to
88+
`@sha256:` digests is a possible future extension of the pinning script.
89+
90+
## Creating a pinned release
91+
92+
Maintainers can create a pinned variant of any existing release tag:
93+
94+
- **GitHub UI / CLI** (once the `Create Pinned Release` workflow is on `main`):
95+
96+
```bash
97+
gh workflow run create_pinned_release.yml -f base_tag=v1.13.8
98+
```
99+
100+
Optional `-f new_tag=...` overrides the default `<base_tag>-pinned` name.
101+
102+
- **Locally**:
103+
104+
```bash
105+
scripts/create_pinned_release.sh v1.13.8
106+
```
107+
108+
Both paths run the same sequence: check out the base tag, pin third-party
109+
refs to SHAs (`scripts/pin_actions.py`), rewrite
110+
`dagster-io/dagster-cloud-action` self-references to the new tag, run a
111+
YAML-parse verification gate (`pin_actions.py --check`), then commit and push
112+
only the new tag.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
[GitHub Actions](https://docs.github.com/en/actions) to deploy code locations to Dagster Cloud.
44

5+
## Pinned releases
6+
7+
Releases tagged `<version>-pinned` (e.g. `v1.13.8-pinned`) have all third-party
8+
action references pinned to commit SHAs for supply-chain hardening. See
9+
[PINNED_RELEASES.md](PINNED_RELEASES.md) for how to use them and how to create one.
10+
511
## Quickstart example repositories
612

713
To get started using GitHub Actions-driven CI/CD for Dagster Cloud, take a look at our quickstart example repositories.

0 commit comments

Comments
 (0)