-
Notifications
You must be signed in to change notification settings - Fork 0
169 lines (159 loc) · 6.7 KB
/
Copy pathrelease.yml
File metadata and controls
169 lines (159 loc) · 6.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Release — atomic six-package npm publish with isolated SLSA Build L3
# provenance + SBOM generation + signed GitHub release.
#
# Trigger: tag v*.*.* on main. The release is atomic — any step
# failure aborts before any `npm publish`. There is NO long-lived
# NPM_TOKEN; npm trusted publishing via OIDC is the only auth path.
#
# Build, pack, and SBOM generation happen without `id-token: write`.
# `.github/workflows/sign-and-publish.yml` is the reusable signing lane
# that receives OIDC + attestation permissions.
#
# The six-package set is asserted by
# packages/k8s-baseline/tests/release-readiness.test.ts:
# - @hulumi/baseline
# - @hulumi/policies
# - @hulumi/drift
# - @hulumi/k8s-baseline (added in runbook hulumi-operations-k8s-security M1)
# - @hulumi/cloudflare-baseline
# - @hulumi/platform-patterns
name: release
on:
push:
tags:
- "v*.*.*"
permissions:
contents: read
jobs:
preflight:
name: pre-flight (build + test + lint)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6
with:
version: 9.12.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 20
cache: pnpm
registry-url: https://registry.npmjs.org
- run: pnpm install --frozen-lockfile
- run: pnpm run lint:exact-pin-guard
- run: pnpm -r build
- run: pnpm -r typecheck
- run: pnpm -r test
- run: pnpm -r lint
- run: pnpm run lint:license-boundary
- run: pnpm run format:check
build-release-artifacts:
name: build release artifacts (no OIDC signing)
needs: preflight
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6
with:
version: 9.12.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 22.14.0
cache: pnpm
registry-url: https://registry.npmjs.org
- name: Use npm CLI pinned for release tooling
run: |
npm install -g npm@11.5.1
node --version
npm --version
- run: pnpm install --frozen-lockfile
- run: pnpm -r build
- name: Generate tarballs
run: |
mkdir -p .release-artifacts
ABS_DEST="$(pwd)/.release-artifacts"
for pkg in baseline policies drift k8s-baseline cloudflare-baseline platform-patterns; do
(cd "packages/$pkg" && pnpm pack --pack-destination "$ABS_DEST")
done
ls -la .release-artifacts/
- name: Generate tarball digest manifest
run: |
set -euo pipefail
sha256sum .release-artifacts/*.tgz > .release-artifacts/tarballs-sha256.txt
cat .release-artifacts/tarballs-sha256.txt
- name: Generate SBOMs (CycloneDX, via cdxgen)
# cdxgen is the multi-package-manager CycloneDX generator. It reads
# `pnpm-lock.yaml` natively, so no transient `package-lock.json`
# round-trip is needed. The previous fix (`npm install
# --package-lock-only`) was intercepted by Corepack — when the
# workspace's `package.json#packageManager` is `pnpm@9.12.0`,
# Corepack rejects or rewrites direct npm calls, so the lockfile
# never got created and `@cyclonedx/cyclonedx-npm` errored with
# "No evidence: no package lock file nor `node_modules` dir".
# Switching to cdxgen sidesteps the Corepack interaction
# entirely.
env:
# cdxgen reads `pnpm-lock.yaml` from the workspace root and
# the package.json from the per-package directory. Run from
# the repo root so pnpm-lock.yaml is discoverable.
FETCH_LICENSE: "true"
run: |
set -euo pipefail
for pkg in baseline policies drift k8s-baseline cloudflare-baseline platform-patterns; do
npx --yes @cyclonedx/cdxgen@11.10.0 \
--type js \
--no-recurse \
--spec-version 1.5 \
--output ".release-artifacts/sbom-${pkg}.cdx.json" \
"packages/$pkg"
done
- name: Verify release-artifact directory before upload (diagnostic)
# The v1.4.0 release run regressed at this point — upload-artifact
# said "No files were found" even though the previous `Generate
# tarballs` step had ls-ed six .tgz files in this directory. This
# diagnostic step captures the directory contents immediately
# before the upload, fails the job loudly if the dir is empty, and
# records the file count + total size in the run log. See PR #186
# post-mortem.
run: |
set -euo pipefail
test -d .release-artifacts || { echo "::error::.release-artifacts/ does not exist"; exit 1; }
ls -la .release-artifacts/
count=$(find .release-artifacts -mindepth 1 -maxdepth 1 -type f | wc -l)
echo "file count: $count"
if [ "$count" -eq 0 ]; then
echo "::error::.release-artifacts/ is empty immediately before upload"
exit 1
fi
- name: Upload release artifacts for isolated signing
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: hulumi-release-artifacts
# v5+ default `include-hidden-files: false` skips any directory
# or file whose name starts with `.`. Because `.release-artifacts/`
# is itself dot-prefixed, every path under it counts as hidden
# and the action emits "No files were found" even when the
# directory contains the .tgz + SBOM files (see PR #187
# post-mortem and the diagnostic step's `ls -la` output).
# Setting include-hidden-files: true uploads the contents of the
# dot-prefixed staging directory without changing repo-level
# hidden-file handling (this glob is scoped to .release-artifacts).
include-hidden-files: true
path: .release-artifacts/**
if-no-files-found: error
retention-days: 7
sign-and-publish:
name: SLSA attest + npm publish (reusable)
needs: build-release-artifacts
uses: ./.github/workflows/sign-and-publish.yml
permissions:
actions: read
contents: write
id-token: write
attestations: write
with:
artifact-name: hulumi-release-artifacts
package-list: baseline policies drift k8s-baseline cloudflare-baseline platform-patterns