-
Notifications
You must be signed in to change notification settings - Fork 0
281 lines (266 loc) · 13.4 KB
/
Copy pathrelease-js.yml
File metadata and controls
281 lines (266 loc) · 13.4 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#
# Releases @braintrust/bt-publishing-test — a dummy npm package used to validate Braintrust
# release workflow tooling end-to-end. This does NOT release any real Braintrust
# JavaScript SDK.
#
# This workflow serves two purposes:
# 1. End-to-end testing of the composite actions in actions/release/
# 2. Reference implementation of the v2 JavaScript TURNKEY release shape
# (build-and-ship): configure → prepare → validate → request-approval → [gate] → build-and-ship
#
# Generic steps are provided by composite actions in actions/release/.
# Only the sections marked with inline comments need to change for other packages.
#
# ─────────────────────────────────────────────────────────────────────────────
# SETUP REQUIREMENTS
# ─────────────────────────────────────────────────────────────────────────────
#
# GitHub Environments (repo Settings → Environments):
# publish
# - Required reviewers: sdk-eng team or named maintainers
# - Prevent self-review: enabled
# publish-dry-run
# - Required reviewers: at least yourself (to test the approval gate)
# - Allow administrators to bypass: enabled (for testing flexibility)
#
# Repository Variables (Settings → Secrets and variables → Variables):
# SLACK_SDK_RELEASE_CHANNEL Slack channel ID for release notifications
#
# Repository Secrets (Settings → Secrets and variables → Secrets):
# SLACK_BOT_TOKEN Org-level secret — Brainbot Slack app token
# Must be invited to SLACK_SDK_RELEASE_CHANNEL
#
# npm Trusted Publishing (OIDC — no token needed):
# Configure for your package at npmjs.com → package → Settings → Trusted Publisher
# Organization/User: @braintrust (or your npm scope/owner)
# Repository: braintrustdata/sdk-actions (or your SDK repo)
# Workflow: release-js.yml (or your workflow filename)
# Environment: publish
# Provenance requires a PUBLIC package; the build-and-ship job needs id-token: write.
#
# ─────────────────────────────────────────────────────────────────────────────
name: Release JavaScript (@braintrust/bt-publishing-test)
on:
# Auto dry-run on PRs that touch the generated actions or the workflows, to
# smoke-test the actions end-to-end. (A template edited without regenerating
# is caught separately by the CI check-generated job, which runs on every PR.)
pull_request:
paths:
- 'actions/**'
- '.github/workflows/**'
workflow_dispatch:
inputs:
_instructions:
description: "⚠️ Before starting: Merge a version bump PR. Version is read from the SHA."
type: string
default: "I have merged a version bump PR"
required: false
release_type:
description: "Release type — maps to channel + github_release defaults (overridden by 'channel' below)"
type: choice
default: stable
options:
- stable
- prerelease
channel:
description: "Explicit npm channel / dist-tag override (empty → derived from release_type)"
type: choice
default: latest
options:
- latest
- rc
- next
- beta
sha:
description: "Commit SHA (of the version bump) to release"
required: true
type: string
prev_release:
description: "Anchor for release notes: a tag name or commit SHA. If SHA, notes will be empty."
type: string
required: false
# bt-publishing-test: fixed SHA anchor prevents indefinite changelog accumulation.
# Update this when you want to reset the notes baseline.
default: '58a397193105516446c3042361913655bcece509'
dry_run:
description: "Dry run: Build without tagging or publishing"
type: boolean
default: false
jobs:
bump:
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions: {}
outputs:
version: ${{ steps.bump.outputs.version }}
steps:
# bt-publishing-test: derives next version by querying npm and incrementing the patch.
# Falls back to 0.0.1 on first publish (package not found). Remove this job
# in real SDK workflows; version comes from the version bump PR.
- name: Bump version
id: bump
run: |
# Package may not exist yet (first release / new name); default to 0.0.0
# so the first publish is 0.0.1.
CURRENT=$(npm view @braintrust/bt-publishing-test version 2>/dev/null || echo "0.0.0")
CURRENT=${CURRENT:-0.0.0}
IFS='.' read -r major minor patch <<< "$CURRENT"
echo "version=$major.$minor.$((patch + 1))" >> $GITHUB_OUTPUT
configure:
needs: bump
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
outputs:
version: ${{ steps.configure.outputs.version }}
release_tag: ${{ steps.configure.outputs.release_tag }}
prev_release: ${{ steps.configure.outputs.prev_release }}
branch: ${{ steps.configure.outputs.branch }}
on_release_branch: ${{ steps.configure.outputs.on_release_branch }}
commit_message: ${{ steps.configure.outputs.commit_message }}
channel: ${{ steps.configure.outputs.channel }}
github_release: ${{ steps.configure.outputs.github_release }}
steps:
# bt-publishing-test: checkout required to resolve local ./actions/... references.
# Real SDK workflows use external braintrustdata/sdk-actions/...@sha references.
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Configure release
id: configure
uses: ./actions/release/lang/js/configure
with:
# bt-publishing-test: version passed directly from the bump job.
# In a real JS project, drop `version`; it is read from package.json.
version: ${{ needs.bump.outputs.version }}
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
working_directory: test/release/js
release_type: ${{ inputs.release_type || 'stable' }}
channel: ${{ inputs.channel }} # explicit override; empty → derived from release_type
prepare:
needs: configure
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: write # required for releases/generate-notes API
outputs:
pr_list: ${{ steps.prepare.outputs.pr_list }}
notes: ${{ steps.prepare.outputs.notes }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare release
id: prepare
uses: ./actions/release/prepare
with:
release_tag: ${{ needs.configure.outputs.release_tag }}
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
# On PR auto dry-runs, anchor notes to the head SHA: prepare treats a
# full SHA as "notes unavailable" (no tag range), so the changelog
# doesn't accumulate in the step summary on every PR.
prev_release: ${{ inputs.prev_release || github.event.pull_request.head.sha || needs.configure.outputs.prev_release }}
validate:
needs: [configure, prepare]
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate release
uses: ./actions/release/lang/js/validate
with:
version: ${{ needs.configure.outputs.version }}
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }}
working_directory: test/release/js
node_version: test/release/js/.tool-versions # exercises version-file sourcing
package_name: '@braintrust/bt-publishing-test' # exercises the npm-availability check
release_tag: ${{ needs.configure.outputs.release_tag }}
channel: ${{ needs.configure.outputs.channel }}
allowed_channels: 'latest,rc,next,beta'
on_release_branch: ${{ needs.configure.outputs.on_release_branch }}
notes: ${{ needs.prepare.outputs.notes }}
# Guard the SBOM generator against silent content regressions (subject/purl correctness,
# scope in group+purl, prod-only closure). Reads the sbom.json the dry-run just
# generated; bt-publishing-test-specific — this is test-bed glue, not a consumer step.
- name: Verify SBOM contents
run: ruby scripts/sbom_verify.rb test/release/js/sbom.json --subject bt-publishing-test --purl-prefix "pkg:npm/%40braintrust/bt-publishing-test@"
request-approval:
needs: [configure, prepare, validate]
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions: {}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Request release approval
uses: ./actions/release/request-approval
with:
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
release_tag: ${{ needs.configure.outputs.release_tag }}
prev_release: ${{ needs.configure.outputs.prev_release }}
branch: ${{ needs.configure.outputs.branch }}
on_release_branch: ${{ needs.configure.outputs.on_release_branch }}
commit_message: ${{ needs.configure.outputs.commit_message }}
pr_list: ${{ needs.prepare.outputs.pr_list }}
notes: ${{ needs.prepare.outputs.notes }}
dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }}
# Suppress Slack on PR auto dry-runs (still exercises message-building; just no real post).
slack_token: ${{ github.event_name != 'pull_request' && secrets.SLACK_BOT_TOKEN || '' }}
slack_channel: ${{ github.event_name != 'pull_request' && vars.SLACK_SDK_RELEASE_CHANNEL || '' }}
label: '@braintrust/bt-publishing-test'
emoji: ':javascript:'
build-and-ship:
needs: [configure, prepare, validate, request-approval]
runs-on: ubuntu-24.04
timeout-minutes: 15
# No environment on PR dry-runs (avoids the approval gate AND the accumulating
# deployment records); the gated environments apply only to manual dispatch.
environment: >-
${{ github.event_name != 'pull_request'
&& (inputs.dry_run && 'publish-dry-run' || 'publish')
|| '' }}
permissions:
contents: write
id-token: write # OIDC trusted publishing + provenance
attestations: write # signed SBOM attestation
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.sha || github.event.pull_request.head.sha }}
fetch-depth: 0
# bt-publishing-test: write the resolved version (from configure) into package.json.
# The job checks out fresh, so the file still reflects the committed placeholder version.
# Real SDK workflows omit this — the version is committed in the bump PR.
- name: Apply version to package.json
env:
VERSION: ${{ needs.configure.outputs.version }}
run: |
node -e 'const fs=require("fs");const f="test/release/js/package.json";const p=JSON.parse(fs.readFileSync(f,"utf8"));p.version=process.env.VERSION;fs.writeFileSync(f,JSON.stringify(p,null,2)+"\n")'
- name: Build and ship
uses: ./actions/release/lang/js/build-and-ship
with:
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
checkout: 'false' # bt-publishing-test: skip internal checkout — version patch above must survive
working_directory: test/release/js
node_version: test/release/js/.tool-versions
dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }}
release_tag: ${{ needs.configure.outputs.release_tag }}
# ⚠️ TEST-BED EXCEPTION — do NOT copy this into a real workflow. Creating a GitHub release
# is the intended default for consumers, who should wire the derived value:
# github_release: ${{ needs.configure.outputs.github_release }}
# This workflow auto-runs on every PR and is ephemeral, so it hard-disables releases to
# avoid tag/release pollution on the throwaway bt-publishing-test package.
github_release: 'false'
version: ${{ needs.configure.outputs.version }}
package_name: '@braintrust/bt-publishing-test'
label: '@braintrust/bt-publishing-test'
access: 'public'
provenance: 'true'
channel: ${{ needs.configure.outputs.channel }}
notes: ${{ needs.prepare.outputs.notes }}
prev_release: ${{ needs.configure.outputs.prev_release }}
branch: ${{ needs.configure.outputs.branch }}
on_release_branch: ${{ needs.configure.outputs.on_release_branch }}
pr_list: ${{ needs.prepare.outputs.pr_list }}
slack_token: ${{ github.event_name != 'pull_request' && secrets.SLACK_BOT_TOKEN || '' }}
slack_channel: ${{ github.event_name != 'pull_request' && vars.SLACK_SDK_RELEASE_CHANNEL || '' }}
emoji: ':javascript:'