1313 outputs :
1414 should_publish : ${{ steps.release_metadata.outputs.should_publish }}
1515 tag : ${{ steps.release_metadata.outputs.tag }}
16+ dist_tag : ${{ steps.release_metadata.outputs.dist_tag }}
17+ prerelease : ${{ steps.release_metadata.outputs.prerelease }}
1618 tarball_name : ${{ steps.release_metadata.outputs.tarball_name }}
1719 concurrency :
1820 group : ${{ github.workflow }}-${{ github.ref_name }}
2325 - name : Checkout repo
2426 uses : actions/checkout@v4
2527 with :
28+ # Keep checkout fast: we should only need to scroll back a few
29+ # commits for release notes. If the release commit is older than
30+ # this depth, release:metadata will emit empty release notes.
31+ fetch-depth : 10
2632 persist-credentials : false
2733
2834 - name : Setup Node.js
3743 - name : Read release metadata
3844 id : release_metadata
3945 run : |
40- npm run --silent release:metadata >> "${GITHUB_OUTPUT}"
46+ release_metadata_json="$(npm run --silent release:metadata)"
47+ jq -r '
48+ "version=\(.version)",
49+ "tag=\(.tag)",
50+ "dist_tag=\(.distTag)",
51+ "prerelease=\(.prerelease)",
52+ "package_spec=\(.packageSpec)",
53+ "tarball_name=\(.tarballName)",
54+ "should_publish=\(.shouldPublish)"
55+ ' <<< "${release_metadata_json}" >> "${GITHUB_OUTPUT}"
56+ jq -r '.releaseNotes' <<< "${release_metadata_json}" > ./release-notes.md
4157
4258 - name : Log publish decision
4359 run : |
@@ -62,22 +78,23 @@ jobs:
6278 name : npmDist-tarball
6379 path : ./${{ steps.release_metadata.outputs.tarball_name }}
6480
65- publish-release :
66- name : Publish, tag, and create release
81+ - name : Upload release notes
82+ if : steps.release_metadata.outputs.should_publish == 'true'
83+ uses : actions/upload-artifact@v4
84+ with :
85+ name : release-notes
86+ path : ./release-notes.md
87+
88+ publish-npm :
89+ name : Publish npm package
6790 needs : check-publish
6891 # Keep this guard on every job for defense-in-depth in case job dependencies are refactored.
6992 if : ${{ !github.event.repository.fork && github.repository == 'graphql/graphql-js' && github.ref_name == '17.x.x' && needs.check-publish.outputs.should_publish == 'true' && needs.check-publish.result == 'success' }}
7093 runs-on : ubuntu-latest
7194 environment : release
7295 permissions :
73- contents : write # for creating/pushing tag and creating GitHub release
7496 id-token : write # for npm trusted publishing via OIDC
7597 steps :
76- - name : Checkout repo
77- uses : actions/checkout@v4
78- with :
79- persist-credentials : false
80-
8198 - name : Setup Node.js
8299 uses : actions/setup-node@v4
83100 with :
@@ -89,34 +106,50 @@ jobs:
89106 name : npmDist-tarball
90107 path : ./artifacts
91108
92- - name : Verify package tarball is present
109+ - name : Dry-run npm publish
93110 run : |
94- tarball="./artifacts/ ${{ needs.check-publish.outputs.tarball_name }}"
95- if [ ! -f "${tarball}" ]; then
96- echo "::error::Expected package tarball ${tarball} is missing."
97- exit 1
111+ if [ -n " ${{ needs.check-publish.outputs.dist_tag }}" ]; then
112+ npm publish --provenance --tag "${{ needs.check-publish.outputs.dist_tag }}" "./artifacts/${{ needs.check-publish.outputs.tarball_name }}"
113+ else
114+ npm publish --provenance "./artifacts/${{ needs.check-publish.outputs.tarball_name }}"
98115 fi
99116
100- - name : Create release if needed
117+ create-release :
118+ name : Create release
119+ needs : check-publish
120+ # Keep this guard on every job for defense-in-depth in case job dependencies are refactored.
121+ if : ${{ !github.event.repository.fork && github.repository == 'graphql/graphql-js' && github.ref_name == '17.x.x' && needs.check-publish.outputs.should_publish == 'true' && needs.check-publish.result == 'success' }}
122+ runs-on : ubuntu-latest
123+ environment : release
124+ permissions :
125+ contents : write # for creating GitHub release
126+ steps :
127+ - name : Download release notes
128+ uses : actions/download-artifact@v4
129+ with :
130+ name : release-notes
131+ path : ./artifacts
132+
133+ - name : Create release
101134 env :
102135 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
103136 run : |
104- release_notes_file="./artifacts/release-notes.md"
105- gh api "repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}" \
106- --jq '.commit.message | split("\n")[1:] | join("\n") | ltrimstr("\n")' \
107- > "${release_notes_file}"
108- if [ ! -s "${release_notes_file}" ]; then
109- printf '## Release %s\n' "${{ needs.check-publish.outputs.tag }}" > "${release_notes_file}"
137+ if gh release view "${{ needs.check-publish.outputs.tag }}" > /dev/null 2>&1; then
138+ echo "GitHub release ${{ needs.check-publish.outputs.tag }} already exists. Skipping release creation."
139+ exit 0
110140 fi
111141
112- if gh release view "${{ needs.check-publish.outputs.tag }}" > /dev/null 2>&1; then
113- echo "GitHub release ${{ needs.check-publish.outputs.tag }} already exists."
142+ release_notes_file="./artifacts/release-notes.md"
143+
144+ if [ "${{ needs.check-publish.outputs.prerelease }}" = "true" ]; then
145+ gh release create "${{ needs.check-publish.outputs.tag }}" \
146+ --target "${GITHUB_SHA}" \
147+ --title "${{ needs.check-publish.outputs.tag }}" \
148+ --notes-file "${release_notes_file}" \
149+ --prerelease
114150 else
115151 gh release create "${{ needs.check-publish.outputs.tag }}" \
116152 --target "${GITHUB_SHA}" \
117153 --title "${{ needs.check-publish.outputs.tag }}" \
118154 --notes-file "${release_notes_file}"
119155 fi
120-
121- - name : Dry-run npm publish
122- run : npm publish --provenance --dry-run "./artifacts/${{ needs.check-publish.outputs.tarball_name }}"
0 commit comments