File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -133,6 +133,7 @@ jobs:
133133 dry_run : ${{ inputs.dry_run || github.event_name == 'pull_request' }}
134134 working_directory : test/release/js
135135 package_manager : pnpm
136+ package_name : ' @braintrust/bt-publishing-test' # exercises the npm-availability fail-fast check
136137 channel : ${{ inputs.channel || 'latest' }}
137138 allowed_channels : ' latest,rc,next,beta'
138139
Original file line number Diff line number Diff line change @@ -49,6 +49,10 @@ inputs:
4949 description : " Whether to create a GitHub release"
5050 required : false
5151 default : ' true'
52+ release_title :
53+ description : " GitHub release name/title. Defaults to the release tag when empty."
54+ required : false
55+ default : ' '
5256 npm :
5357 description : " Whether to publish to the npm registry"
5458 required : false
@@ -208,21 +212,24 @@ runs:
208212 ENABLED : ${{ inputs.github_release }}
209213 DRY_RUN : ${{ inputs.dry_run }}
210214 TAG : ${{ inputs.release_tag }}
215+ RELEASE_TITLE : ${{ inputs.release_title }}
211216 NOTES_B64 : ${{ inputs.notes }}
212217 SHA : ${{ inputs.sha }}
213218 run : |
214219 if [ "$ENABLED" != "true" ]; then
215220 echo "GitHub release disabled; skipping."
216221 exit 0
217222 fi
223+ # Release name defaults to the tag when no explicit title is provided.
224+ TITLE="${RELEASE_TITLE:-$TAG}"
218225 if [ "$DRY_RUN" = "true" ]; then
219- echo "DRY RUN: would create GitHub release $TAG"
226+ echo "DRY RUN: would create GitHub release $TAG (title: $TITLE) "
220227 echo "--- Release notes preview ---"
221228 echo "$NOTES_B64" | base64 -d 2>/dev/null || echo "(unavailable)"
222229 else
223230 echo "$NOTES_B64" | base64 -d 2>/dev/null > /tmp/release-notes.md
224231 gh release create "$TAG" \
225- --title "$TAG " \
232+ --title "$TITLE " \
226233 --notes-file /tmp/release-notes.md \
227234 --target "$SHA"
228235 fi
Original file line number Diff line number Diff line change @@ -41,6 +41,13 @@ inputs:
4141 description : " npm registry URL"
4242 required : false
4343 default : ' https://registry.npmjs.org'
44+ package_name :
45+ description : >
46+ npm package name (matches the publish action's input). When set, validate fails
47+ fast if this version is already published (covers prereleases, which aren't
48+ git-tagged). Leave empty to skip.
49+ required : false
50+ default : ' '
4451 tag_format :
4552 description : " Git tag format, with a {version} placeholder (e.g. js-{version})"
4653 required : false
@@ -129,6 +136,23 @@ runs:
129136 echo "version=$VERSION" >> $GITHUB_OUTPUT
130137 fi
131138
139+ - name : Check npm version availability
140+ shell : bash
141+ env :
142+ PACKAGE_NAME : ${{ inputs.package_name }}
143+ VERSION : ${{ steps.read-version.outputs.version }}
144+ REGISTRY : ${{ inputs.registry }}
145+ run : |
146+ if [ -z "$PACKAGE_NAME" ]; then
147+ echo "No package_name provided; skipping npm availability check."
148+ exit 0
149+ fi
150+ if npm view "$PACKAGE_NAME@$VERSION" version --registry "$REGISTRY" >/dev/null 2>&1; then
151+ echo "Error: $PACKAGE_NAME@$VERSION already exists on npm — has the version been bumped?"
152+ exit 1
153+ fi
154+ echo "$PACKAGE_NAME@$VERSION is available on npm."
155+
132156 - name : Validate release channel
133157 shell : bash
134158 env :
Original file line number Diff line number Diff line change @@ -32,6 +32,10 @@ inputs:
3232 description : " Whether to create a GitHub release"
3333 required : false
3434 default : ' true'
35+ release_title :
36+ description : " GitHub release name/title. Defaults to the release tag when empty."
37+ required : false
38+ default : ' '
3539 notes :
3640 description : " Base64-encoded release notes from the prepare action"
3741 required : false
@@ -116,21 +120,24 @@ runs:
116120 ENABLED : ${{ inputs.github_release }}
117121 DRY_RUN : ${{ inputs.dry_run }}
118122 TAG : ${{ inputs.release_tag }}
123+ RELEASE_TITLE : ${{ inputs.release_title }}
119124 NOTES_B64 : ${{ inputs.notes }}
120125 SHA : ${{ inputs.sha }}
121126 run : |
122127 if [ "$ENABLED" != "true" ]; then
123128 echo "GitHub release disabled; skipping."
124129 exit 0
125130 fi
131+ # Release name defaults to the tag when no explicit title is provided.
132+ TITLE="${RELEASE_TITLE:-$TAG}"
126133 if [ "$DRY_RUN" = "true" ]; then
127- echo "DRY RUN: would create GitHub release $TAG"
134+ echo "DRY RUN: would create GitHub release $TAG (title: $TITLE) "
128135 echo "--- Release notes preview ---"
129136 echo "$NOTES_B64" | base64 -d 2>/dev/null || echo "(unavailable)"
130137 else
131138 echo "$NOTES_B64" | base64 -d 2>/dev/null > /tmp/release-notes.md
132139 gh release create "$TAG" \
133- --title "$TAG " \
140+ --title "$TITLE " \
134141 --notes-file /tmp/release-notes.md \
135142 --target "$SHA"
136143 fi
Original file line number Diff line number Diff line change @@ -48,6 +48,10 @@ inputs:
4848 description: "Whether to create a GitHub release"
4949 required: false
5050 default: 'true'
51+ release_title:
52+ description: "GitHub release name/title. Defaults to the release tag when empty."
53+ required: false
54+ default: ''
5155 npm:
5256 description: "Whether to publish to the npm registry"
5357 required: false
Original file line number Diff line number Diff line change @@ -40,6 +40,13 @@ inputs:
4040 description: "npm registry URL"
4141 required: false
4242 default: 'https://registry.npmjs.org'
43+ package_name:
44+ description: >
45+ npm package name (matches the publish action's input). When set, validate fails
46+ fast if this version is already published (covers prereleases, which aren't
47+ git-tagged). Leave empty to skip.
48+ required: false
49+ default: ''
4350 tag_format:
4451 description: "Git tag format, with a {version} placeholder (e.g. js-{version})"
4552 required: false
8895
8996<%= render_step ( 'lang/js/read-version' ) %>
9097
98+ <%= render_step ( 'release/lang/js/npm-availability' ) %>
99+
91100<%= render_step ( 'release/lang/js/validate-channel' ) %>
92101
93102<%= render_step ( 'release/validate' , version : "${{ steps.read-version.outputs.version }}" , tag_format : "${{ inputs.tag_format }}" ) %>
Original file line number Diff line number Diff line change @@ -31,6 +31,10 @@ inputs:
3131 description: "Whether to create a GitHub release"
3232 required: false
3333 default: 'true'
34+ release_title:
35+ description: "GitHub release name/title. Defaults to the release tag when empty."
36+ required: false
37+ default: ''
3438 notes:
3539 description: "Base64-encoded release notes from the prepare action"
3640 required: false
Original file line number Diff line number Diff line change 33 Self-guards in shell on `github_release` (skips when disabled) and `dry_run`
44 (preview vs. create), so the composing action needs no `if:` on it. Requires
55 the composing action to expose github_release / dry_run / release_tag / notes / sha inputs.
6+ Optionally uses release_title for the release name (defaults to the tag).
67-%>
78- name: Create GitHub release
89 shell: bash
1112 ENABLED: ${{ inputs.github_release }}
1213 DRY_RUN: ${{ inputs.dry_run }}
1314 TAG: ${{ inputs.release_tag }}
15+ RELEASE_TITLE: ${{ inputs.release_title }}
1416 NOTES_B64: ${{ inputs.notes }}
1517 SHA: ${{ inputs.sha }}
1618 run: |
1719 if [ "$ENABLED" != "true" ]; then
1820 echo "GitHub release disabled; skipping."
1921 exit 0
2022 fi
23+ # Release name defaults to the tag when no explicit title is provided.
24+ TITLE="${RELEASE_TITLE:-$TAG}"
2125 if [ "$DRY_RUN" = "true" ]; then
22- echo "DRY RUN: would create GitHub release $TAG"
26+ echo "DRY RUN: would create GitHub release $TAG (title: $TITLE) "
2327 echo "--- Release notes preview ---"
2428 echo "$NOTES_B64" | base64 -d 2> /dev/null || echo "(unavailable)"
2529 else
2630 echo "$NOTES_B64" | base64 -d 2> /dev/null > /tmp/release-notes.md
2731 gh release create "$TAG" \
28- --title "$TAG " \
32+ --title "$TITLE " \
2933 --notes-file /tmp/release-notes.md \
3034 --target "$SHA"
3135 fi
Original file line number Diff line number Diff line change 1+ <%#
2+ Fails fast if the package version is already published to the npm registry.
3+ Read-only registry query (no auth). Self-guards: skips when package_name is
4+ empty. Complements release/validate's git-tag check by covering prereleases,
5+ which aren't tagged. Assumes the read-version step (id: read-version) has run.
6+
7+ @param package_name [String] expr for the npm package name. Default: ${{ inputs.package_name }}
8+ @param registry [String] expr for the npm registry URL. Default: ${{ inputs.registry }}
9+ -%>
10+ - name: Check npm version availability
11+ shell: bash
12+ env:
13+ PACKAGE_NAME: <%= locals.fetch(:package_name) { "${{ inputs.package_name }}" } %>
14+ VERSION: ${{ steps.read-version.outputs.version }}
15+ REGISTRY: <%= locals.fetch(:registry) { "${{ inputs.registry }}" } %>
16+ run: |
17+ if [ -z "$PACKAGE_NAME" ]; then
18+ echo "No package_name provided; skipping npm availability check."
19+ exit 0
20+ fi
21+ if npm view "$PACKAGE_NAME@$VERSION" version --registry "$REGISTRY" > /dev/null 2> &1; then
22+ echo "Error: $PACKAGE_NAME@$VERSION already exists on npm — has the version been bumped?"
23+ exit 1
24+ fi
25+ echo "$PACKAGE_NAME@$VERSION is available on npm."
You can’t perform that action at this time.
0 commit comments