Skip to content

Commit f362d6d

Browse files
authored
Simplify the JavaScript release action inputs (#55)
Settles the version-input interface for the shared JS release actions (`release/lang/js/validate`, `release/lang/js/publish`) so it's consistent and minimal. No behavior change for the existing dummy release; this is an interface cleanup ahead of onboarding real consumers (autoevals). ## What changed - **pnpm-only.** Every hand-maintained Braintrust JS package publishes with pnpm, so the actions no longer try to be package-manager-agnostic. Removed the `package_manager` input; setup/build/env-dump now use pnpm directly (`pnpm install --frozen-lockfile`, `pnpm run <build>`, `cache: pnpm`). - **One `node_version` input.** Folded `node_version` + `node_version_file` into a single required `node_version` that accepts **either** an explicit version (`24`) **or** a path to a version file (`.tool-versions` / `.nvmrc` / `.node-version`), routed by a file-existence check. No default, no autodiscovery . Mirrors Ruby's `ruby_version`. - **`pnpm_version` sources from `packageManager`.** Default is now empty: when omitted, `pnpm/action-setup` reads the version from the package's `package.json` `packageManager` field (one source of truth). Pass a value to override. - **npm pin is internal.** Removed the `npm_version` input. Tokenless OIDC trusted publishing needs npm ≥ 11.5.1 (newer than the npm bundled with setup-node), so the publish step pins `npm@11.6.2` internally. This is the publish CLI only so it doesn't belong on the consumer surface. ## Net input-surface change (both JS actions) - Removed: `package_manager`, `node_version_file`, `npm_version` - `node_version`: now required; accepts a version **or** a version-file path - `pnpm_version`: default `'10.33.0'` → `''` (reads `packageManager` when empty)
1 parent 283875d commit f362d6d

10 files changed

Lines changed: 184 additions & 194 deletions

File tree

.github/workflows/release-js.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,7 @@ jobs:
132132
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
133133
dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }}
134134
working_directory: test/release/js
135-
package_manager: pnpm
136-
node_version_file: test/release/js/.tool-versions # exercises node-version-file sourcing
135+
node_version: test/release/js/.tool-versions # exercises version-file sourcing (vs explicit version)
137136
package_name: '@braintrust/bt-publishing-test' # exercises the npm-availability fail-fast check
138137
channel: ${{ inputs.channel || 'latest' }}
139138
allowed_channels: 'latest,rc,next,beta'
@@ -231,8 +230,7 @@ jobs:
231230
sha: ${{ inputs.sha || github.event.pull_request.head.sha }}
232231
checkout: 'false' # bt-publishing-test: skip internal checkout — version patching above must survive into the build
233232
working_directory: test/release/js
234-
package_manager: pnpm
235-
node_version_file: test/release/js/.tool-versions
233+
node_version: test/release/js/.tool-versions
236234
dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }}
237235
release_tag: ${{ needs.validate.outputs.release_tag }}
238236
github_release: 'false' # bt-publishing-test: omit GitHub release to avoid tag/release pollution from repeated test runs

actions/release/lang/js/publish/action.yml

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# GENERATED by scripts/generate.rb — edit templates/, not this file.
22
name: Publish JavaScript Package
33
description: >
4-
Full JavaScript package release: checks out the SHA, sets up Node and the
5-
package manager, builds, publishes to npm (OIDC trusted publishing), creates a
4+
Full JavaScript package release: checks out the SHA, sets up Node and pnpm,
5+
builds, publishes to npm (OIDC trusted publishing), creates a
66
GitHub release, and sends a Slack completion notification. Covers the standard
77
publish sequence for Braintrust npm packages.
88
@@ -18,24 +18,23 @@ inputs:
1818
description: "Path to the package root (where package.json lives)"
1919
required: false
2020
default: '.'
21-
package_manager:
22-
description: "Package manager: pnpm | npm | yarn"
23-
required: false
24-
default: 'pnpm'
2521
node_version:
26-
description: "Node version to use"
27-
required: false
28-
default: ''
29-
node_version_file:
30-
description: "Path to a node version file (.tool-versions, .nvmrc, .node-version), relative to the repo root"
22+
description: >
23+
Node version (e.g. 24), or a path to a version file
24+
(.tool-versions, .nvmrc, .node-version) relative to the repo root.
25+
required: true
26+
pnpm_version:
27+
description: "pnpm version to install. When empty, read from package.json packageManager."
3128
required: false
3229
default: ''
33-
pnpm_version:
34-
description: "pnpm version to install (when package_manager is pnpm)"
30+
build:
31+
description: >
32+
Whether to run the build step. Set to 'false' for packages that publish
33+
their sources directly (no build) — the build step then no-ops.
3534
required: false
36-
default: '10.33.0'
35+
default: 'true'
3736
build_command:
38-
description: "npm script to run for the build"
37+
description: "npm script to run for the build (when build is 'true')"
3938
required: false
4039
default: 'build'
4140
dry_run:
@@ -65,10 +64,6 @@ inputs:
6564
description: "npm registry URL"
6665
required: false
6766
default: 'https://registry.npmjs.org'
68-
npm_version:
69-
description: "npm version to install before publishing (pinned; >= 11.5.1 for tokenless OIDC trusted publishing)"
70-
required: false
71-
default: '11.6.2'
7267
access:
7368
description: "npm publish access: public | restricted (provenance requires public)"
7469
required: false
@@ -141,46 +136,52 @@ runs:
141136
fetch-depth: 0
142137

143138
- name: Set up pnpm
144-
if: ${{ inputs.package_manager == 'pnpm' }}
145139
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
146140
with:
141+
# Empty version → action-setup reads the pnpm version from this package.json's
142+
# "packageManager" field (one source of truth). A non-empty value overrides it.
147143
version: ${{ inputs.pnpm_version }}
144+
package_json_file: ${{ inputs.working_directory }}/package.json
145+
146+
- name: Resolve Node version source
147+
id: node-src
148+
shell: bash
149+
env:
150+
NODE_VERSION: ${{ inputs.node_version }}
151+
run: |
152+
# node_version is either an explicit version (e.g. 24) or a path to a version
153+
# file (.tool-versions / .nvmrc / .node-version). Route by file existence so a
154+
# single input covers both; paths are relative to the repo root (as setup-node expects).
155+
if [ -n "$NODE_VERSION" ] && [ -f "$NODE_VERSION" ]; then
156+
echo "file=$NODE_VERSION" >> "$GITHUB_OUTPUT"
157+
echo "spec=" >> "$GITHUB_OUTPUT"
158+
else
159+
echo "file=" >> "$GITHUB_OUTPUT"
160+
echo "spec=$NODE_VERSION" >> "$GITHUB_OUTPUT"
161+
fi
148162
149163
- name: Set up Node
150164
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
151165
with:
152-
# Explicit node_version wins (setup-node prefers node-version when set); node_version_file
153-
# (.tool-versions / .nvmrc / .node-version) is the fallback. Provide one of the two.
154-
node-version: ${{ inputs.node_version }}
155-
node-version-file: ${{ inputs.node_version_file }}
166+
node-version: ${{ steps.node-src.outputs.spec }}
167+
node-version-file: ${{ steps.node-src.outputs.file }}
156168
registry-url: ${{ inputs.registry }}
157-
cache: ${{ inputs.package_manager }}
158-
cache-dependency-path: |
159-
${{ inputs.working_directory }}/pnpm-lock.yaml
160-
${{ inputs.working_directory }}/package-lock.json
161-
${{ inputs.working_directory }}/yarn.lock
169+
cache: pnpm
170+
cache-dependency-path: ${{ inputs.working_directory }}/pnpm-lock.yaml
162171

163172
- name: Install dependencies
164173
shell: bash
165174
working-directory: ${{ inputs.working_directory }}
166-
env:
167-
PM: ${{ inputs.package_manager }}
168-
run: |
169-
case "$PM" in
170-
pnpm) pnpm install --frozen-lockfile ;;
171-
yarn) yarn install --frozen-lockfile ;;
172-
npm) npm ci ;;
173-
*) echo "Unknown package_manager: $PM"; exit 1 ;;
174-
esac
175+
run: pnpm install --frozen-lockfile
175176

176177
- name: Build
178+
if: ${{ inputs.build == 'true' }}
177179
shell: bash
178180
working-directory: ${{ inputs.working_directory }}
179181
env:
180-
PM: ${{ inputs.package_manager }}
181182
BUILD_COMMAND: ${{ inputs.build_command }}
182183
run: |
183-
"$PM" run "$BUILD_COMMAND"
184+
pnpm run "$BUILD_COMMAND"
184185
185186
- name: Publish to npm
186187
shell: bash
@@ -192,24 +193,24 @@ runs:
192193
ACCESS: ${{ inputs.access }}
193194
PROVENANCE: ${{ inputs.provenance }}
194195
REGISTRY: ${{ inputs.registry }}
195-
NPM_VERSION: ${{ inputs.npm_version }}
196-
# Force OIDC trusted publishing: clear any inherited token so npm can't fall
197-
# back to token auth.
196+
# Force OIDC: clear any inherited token so the publish can't fall back to token auth.
198197
NODE_AUTH_TOKEN: ''
199198
NPM_TOKEN: ''
200199
run: |
201200
if [ "$NPM_ENABLED" != "true" ]; then
202-
echo "npm publishing disabled; skipping."
201+
echo "npm registry publishing disabled; skipping."
203202
exit 0
204203
fi
205-
npm install -g "npm@$NPM_VERSION"
206-
ARGS=(--tag "$CHANNEL" --access "$ACCESS" --registry "$REGISTRY")
204+
# pnpm delegates the upload to this npm CLI; pin >= 11.5.1 for OIDC (newer than setup-node's).
205+
npm install -g "npm@11.6.2"
206+
# --no-git-checks: the publish tree may be patched/detached (e.g. an rc version in package.json).
207+
ARGS=(--tag "$CHANNEL" --access "$ACCESS" --registry "$REGISTRY" --no-git-checks)
207208
[ "$PROVENANCE" = "true" ] && ARGS+=(--provenance)
208209
if [ "$DRY_RUN" = "true" ]; then
209-
echo "DRY RUN: npm publish ${ARGS[*]} --dry-run"
210-
npm publish "${ARGS[@]}" --dry-run
210+
echo "DRY RUN: pnpm publish ${ARGS[*]} --dry-run"
211+
pnpm publish "${ARGS[@]}" --dry-run
211212
else
212-
npm publish "${ARGS[@]}"
213+
pnpm publish "${ARGS[@]}"
213214
fi
214215
215216
- name: Create GitHub release
@@ -413,14 +414,12 @@ runs:
413414
if: ${{ failure() }}
414415
shell: bash
415416
working-directory: ${{ inputs.working_directory }}
416-
env:
417-
PM: ${{ inputs.package_manager }}
418417
run: |
419418
echo "=== Node environment ==="
420419
node --version
421420
npm --version
422-
echo "=== Package manager ($PM) ==="
423-
"$PM" --version || echo "(unavailable)"
421+
echo "=== pnpm ==="
422+
pnpm --version || echo "(unavailable)"
424423
echo "=== Registry ==="
425424
npm config get registry
426425
echo "=== package.json version ==="

actions/release/lang/js/validate/action.yml

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# GENERATED by scripts/generate.rb — edit templates/, not this file.
22
name: Validate JavaScript Release
33
description: >
4-
Checks out the release SHA, sets up Node and the package manager, reads the
4+
Checks out the release SHA, sets up Node and pnpm, reads the
55
package version, validates the release channel and metadata (tag existence,
66
branch, commit metadata), and builds to confirm the package is publishable
77
before the approval gate.
@@ -25,22 +25,15 @@ inputs:
2525
description: "Path to the package root (where package.json lives)"
2626
required: false
2727
default: '.'
28-
package_manager:
29-
description: "Package manager: pnpm | npm | yarn"
30-
required: false
31-
default: 'pnpm'
3228
node_version:
33-
description: "Node version to use"
34-
required: false
35-
default: ''
36-
node_version_file:
37-
description: "Path to a node version file (.tool-versions, .nvmrc, .node-version), relative to the repo root"
38-
required: false
39-
default: ''
29+
description: >
30+
Node version (e.g. 24), or a path to a version file
31+
(.tool-versions, .nvmrc, .node-version) relative to the repo root.
32+
required: true
4033
pnpm_version:
41-
description: "pnpm version to install (when package_manager is pnpm)"
34+
description: "pnpm version to install. When empty, read from package.json packageManager."
4235
required: false
43-
default: '10.33.0'
36+
default: ''
4437
registry:
4538
description: "npm registry URL"
4639
required: false
@@ -64,8 +57,14 @@ inputs:
6457
description: "Comma-separated allowlist of accepted release channels"
6558
required: false
6659
default: 'latest'
60+
build:
61+
description: >
62+
Whether to run the build step. Set to 'false' for packages that publish
63+
their sources directly (no build) — the build step then no-ops.
64+
required: false
65+
default: 'true'
6766
build_command:
68-
description: "npm script to run for the build"
67+
description: "npm script to run for the build (when build is 'true')"
6968
required: false
7069
default: 'build'
7170
outputs:
@@ -97,37 +96,43 @@ runs:
9796
fetch-depth: 0
9897

9998
- name: Set up pnpm
100-
if: ${{ inputs.package_manager == 'pnpm' }}
10199
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
102100
with:
101+
# Empty version → action-setup reads the pnpm version from this package.json's
102+
# "packageManager" field (one source of truth). A non-empty value overrides it.
103103
version: ${{ inputs.pnpm_version }}
104+
package_json_file: ${{ inputs.working_directory }}/package.json
105+
106+
- name: Resolve Node version source
107+
id: node-src
108+
shell: bash
109+
env:
110+
NODE_VERSION: ${{ inputs.node_version }}
111+
run: |
112+
# node_version is either an explicit version (e.g. 24) or a path to a version
113+
# file (.tool-versions / .nvmrc / .node-version). Route by file existence so a
114+
# single input covers both; paths are relative to the repo root (as setup-node expects).
115+
if [ -n "$NODE_VERSION" ] && [ -f "$NODE_VERSION" ]; then
116+
echo "file=$NODE_VERSION" >> "$GITHUB_OUTPUT"
117+
echo "spec=" >> "$GITHUB_OUTPUT"
118+
else
119+
echo "file=" >> "$GITHUB_OUTPUT"
120+
echo "spec=$NODE_VERSION" >> "$GITHUB_OUTPUT"
121+
fi
104122
105123
- name: Set up Node
106124
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
107125
with:
108-
# Explicit node_version wins (setup-node prefers node-version when set); node_version_file
109-
# (.tool-versions / .nvmrc / .node-version) is the fallback. Provide one of the two.
110-
node-version: ${{ inputs.node_version }}
111-
node-version-file: ${{ inputs.node_version_file }}
126+
node-version: ${{ steps.node-src.outputs.spec }}
127+
node-version-file: ${{ steps.node-src.outputs.file }}
112128
registry-url: ${{ inputs.registry }}
113-
cache: ${{ inputs.package_manager }}
114-
cache-dependency-path: |
115-
${{ inputs.working_directory }}/pnpm-lock.yaml
116-
${{ inputs.working_directory }}/package-lock.json
117-
${{ inputs.working_directory }}/yarn.lock
129+
cache: pnpm
130+
cache-dependency-path: ${{ inputs.working_directory }}/pnpm-lock.yaml
118131

119132
- name: Install dependencies
120133
shell: bash
121134
working-directory: ${{ inputs.working_directory }}
122-
env:
123-
PM: ${{ inputs.package_manager }}
124-
run: |
125-
case "$PM" in
126-
pnpm) pnpm install --frozen-lockfile ;;
127-
yarn) yarn install --frozen-lockfile ;;
128-
npm) npm ci ;;
129-
*) echo "Unknown package_manager: $PM"; exit 1 ;;
130-
esac
135+
run: pnpm install --frozen-lockfile
131136

132137
- name: Read version
133138
id: read-version
@@ -227,26 +232,24 @@ runs:
227232
echo "Validated $TAG @ $SHA ($COMMIT_MSG)"
228233
229234
- name: Build
235+
if: ${{ inputs.build == 'true' }}
230236
shell: bash
231237
working-directory: ${{ inputs.working_directory }}
232238
env:
233-
PM: ${{ inputs.package_manager }}
234239
BUILD_COMMAND: ${{ inputs.build_command }}
235240
run: |
236-
"$PM" run "$BUILD_COMMAND"
241+
pnpm run "$BUILD_COMMAND"
237242
238243
- name: Dump JavaScript environment
239244
if: ${{ failure() }}
240245
shell: bash
241246
working-directory: ${{ inputs.working_directory }}
242-
env:
243-
PM: ${{ inputs.package_manager }}
244247
run: |
245248
echo "=== Node environment ==="
246249
node --version
247250
npm --version
248-
echo "=== Package manager ($PM) ==="
249-
"$PM" --version || echo "(unavailable)"
251+
echo "=== pnpm ==="
252+
pnpm --version || echo "(unavailable)"
250253
echo "=== Registry ==="
251254
npm config get registry
252255
echo "=== package.json version ==="

0 commit comments

Comments
 (0)