Skip to content

Commit c2ad5c6

Browse files
authored
internal: backport new release flow from 17.x.x (#4608)
1 parent adff4e6 commit c2ad5c6

File tree

9 files changed

+621
-80
lines changed

9 files changed

+621
-80
lines changed

.github/CONTRIBUTING.md

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,19 @@ ensure your pull request matches the style guides, run `npm run prettier`.
7676

7777
## Release on NPM
7878

79-
_Only core contributors may release to NPM._
80-
81-
To release a new version on NPM, first ensure all tests pass with `npm test`,
82-
then use `npm version patch|minor|major` in order to increment the version in
83-
package.json and tag and commit a release. Then `git push && git push --tags`
84-
to sync this change with source control. Then `npm publish npmDist` to actually
85-
publish the release to NPM.
86-
Once published, add [release notes](https://github.com/graphql/graphql-js/tags).
87-
Use [semver](https://semver.org/) to determine which version part to increment.
88-
89-
Example for a patch release:
90-
91-
```sh
92-
npm test
93-
npm version patch --ignore-scripts=false
94-
git push --follow-tags
95-
cd npmDist && npm publish
79+
Releases on `16.x.x` are managed by local scripts and GitHub Actions:
80+
81+
```bash
82+
git switch 16.x.x
83+
git switch -c <my_release_branch>
84+
export GH_TOKEN=<token> # required to build changelog via GitHub API requests
85+
npm run release:prepare -- 16.x.x patch
9686
```
9787

88+
Push `<my_release_branch>`, open a PR from `<my_release_branch>` to `16.x.x`,
89+
wait for CI to pass, merge the PR, and then approve the GitHub Actions release
90+
workflow.
91+
9892
## License
9993

10094
By contributing to graphql-js, you agree that your contributions will be

.github/workflows/release.yml

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
name: Release
2+
on:
3+
push:
4+
branches:
5+
- 16.x.x
6+
permissions: {}
7+
jobs:
8+
check-publish:
9+
name: Check for publish need and prepare artifacts
10+
# Keep this guard on every job for defense-in-depth in case job dependencies are refactored.
11+
if: ${{ !github.event.repository.fork && github.repository == 'graphql/graphql-js' && github.ref_name == '16.x.x' }}
12+
runs-on: ubuntu-latest
13+
outputs:
14+
should_publish: ${{ steps.release_metadata.outputs.should_publish }}
15+
tag: ${{ steps.release_metadata.outputs.tag }}
16+
dist_tag: ${{ steps.release_metadata.outputs.dist_tag }}
17+
prerelease: ${{ steps.release_metadata.outputs.prerelease }}
18+
tarball_name: ${{ steps.release_metadata.outputs.tarball_name }}
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.ref_name }}
21+
cancel-in-progress: true
22+
permissions:
23+
contents: read # for actions/checkout
24+
steps:
25+
- name: Checkout repo
26+
uses: actions/checkout@v4
27+
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
32+
persist-credentials: false
33+
34+
- name: Setup Node.js
35+
uses: actions/setup-node@v4
36+
with:
37+
cache: npm
38+
node-version-file: '.node-version'
39+
40+
- name: Install Dependencies
41+
run: npm ci --ignore-scripts
42+
43+
- name: Read release metadata
44+
id: release_metadata
45+
run: |
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
57+
58+
- name: Log publish decision
59+
run: |
60+
if [ "${{ steps.release_metadata.outputs.should_publish }}" = "true" ]; then
61+
echo "${{ steps.release_metadata.outputs.package_spec }} is not published yet."
62+
else
63+
echo "${{ steps.release_metadata.outputs.package_spec }} is already published."
64+
fi
65+
66+
- name: Build NPM package
67+
if: steps.release_metadata.outputs.should_publish == 'true'
68+
run: npm run build:npm
69+
70+
- name: Pack npmDist package
71+
if: steps.release_metadata.outputs.should_publish == 'true'
72+
run: npm pack ./npmDist --pack-destination . > /dev/null
73+
74+
- name: Upload npm package tarball
75+
if: steps.release_metadata.outputs.should_publish == 'true'
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: npmDist-tarball
79+
path: ./${{ steps.release_metadata.outputs.tarball_name }}
80+
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
90+
needs: check-publish
91+
# Keep this guard on every job for defense-in-depth in case job dependencies are refactored.
92+
if: ${{ !github.event.repository.fork && github.repository == 'graphql/graphql-js' && github.ref_name == '16.x.x' && needs.check-publish.outputs.should_publish == 'true' && needs.check-publish.result == 'success' }}
93+
runs-on: ubuntu-latest
94+
environment: release
95+
permissions:
96+
contents: read # for actions/checkout
97+
id-token: write # for npm trusted publishing via OIDC
98+
steps:
99+
- name: Checkout repo
100+
uses: actions/checkout@v4
101+
with:
102+
persist-credentials: false
103+
104+
- name: Setup Node.js
105+
uses: actions/setup-node@v4
106+
with:
107+
node-version-file: '.node-version'
108+
109+
- name: Download npmDist package
110+
uses: actions/download-artifact@v4
111+
with:
112+
name: npmDist-tarball
113+
path: ./artifacts
114+
115+
- name: Publish npm package
116+
run: |
117+
if [ -n "${{ needs.check-publish.outputs.dist_tag }}" ]; then
118+
npm publish --provenance --tag "${{ needs.check-publish.outputs.dist_tag }}" "./artifacts/${{ needs.check-publish.outputs.tarball_name }}"
119+
else
120+
npm publish --provenance "./artifacts/${{ needs.check-publish.outputs.tarball_name }}"
121+
fi
122+
123+
create-release:
124+
name: Create release
125+
needs: check-publish
126+
# Keep this guard on every job for defense-in-depth in case job dependencies are refactored.
127+
if: ${{ !github.event.repository.fork && github.repository == 'graphql/graphql-js' && github.ref_name == '16.x.x' && needs.check-publish.outputs.should_publish == 'true' && needs.check-publish.result == 'success' }}
128+
runs-on: ubuntu-latest
129+
environment: release
130+
permissions:
131+
contents: write # for creating GitHub release
132+
steps:
133+
- name: Checkout repo
134+
uses: actions/checkout@v4
135+
with:
136+
persist-credentials: false
137+
138+
- name: Download release notes
139+
uses: actions/download-artifact@v4
140+
with:
141+
name: release-notes
142+
path: ./artifacts
143+
144+
- name: Create release
145+
env:
146+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147+
run: |
148+
if gh release view "${{ needs.check-publish.outputs.tag }}" > /dev/null 2>&1; then
149+
echo "GitHub release ${{ needs.check-publish.outputs.tag }} already exists. Skipping release creation."
150+
exit 0
151+
fi
152+
153+
release_notes_file="./artifacts/release-notes.md"
154+
155+
if [ "${{ needs.check-publish.outputs.prerelease }}" = "true" ]; then
156+
gh release create "${{ needs.check-publish.outputs.tag }}" \
157+
--target "${GITHUB_SHA}" \
158+
--title "${{ needs.check-publish.outputs.tag }}" \
159+
--notes-file "${release_notes_file}" \
160+
--prerelease
161+
else
162+
gh release create "${{ needs.check-publish.outputs.tag }}" \
163+
--target "${GITHUB_SHA}" \
164+
--title "${{ needs.check-publish.outputs.tag }}" \
165+
--notes-file "${release_notes_file}"
166+
fi

cspell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ words:
7070
# TODO: contribute upstream
7171
- deno
7272
- codecov
73+
- preid
7374

7475
# Website tech
7576
- Nextra

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
3131
},
3232
"scripts": {
33-
"preversion": "bash -c '. ./resources/checkgit.sh && npm ci --ignore-scripts'",
34-
"version": "node resources/gen-version.js && npm test && git add src/version.ts",
3533
"fuzzonly": "mocha --full-trace src/**/__tests__/**/*-fuzz.ts",
3634
"changelog": "node resources/gen-changelog.js",
35+
"release:prepare": "node resources/release-prepare.js",
36+
"release:metadata": "node resources/release-metadata.js",
3737
"benchmark": "node benchmark/benchmark.js",
3838
"test": "npm run lint && npm run check && npm run testonly && npm run prettier:check && npm run check:spelling && npm run check:integrations",
3939
"lint": "eslint --cache --max-warnings 0 .",
@@ -45,9 +45,7 @@
4545
"check:spelling": "cspell --cache --no-progress '**/*'",
4646
"check:integrations": "npm run build:npm && npm run build:deno && mocha --full-trace integrationTests/*-test.js",
4747
"build:npm": "node resources/build-npm.js",
48-
"build:deno": "node resources/build-deno.js",
49-
"gitpublish:npm": "bash ./resources/gitpublish.sh npm npmDist",
50-
"gitpublish:deno": "bash ./resources/gitpublish.sh deno denoDist"
48+
"build:deno": "node resources/build-deno.js"
5149
},
5250
"devDependencies": {
5351
"@babel/core": "7.17.9",

resources/checkgit.sh

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)