Skip to content

Commit 2b27d9f

Browse files
authored
Improve release workflow (#2719)
* add scripts to help with automating releases * add prepare-release and release workflows * bump actions from v2 to v3 * use `github.ref_name` for getting the tag name * ensure we use `**` for matching tags with slashes in them
1 parent 134c0fb commit 2b27d9f

File tree

8 files changed

+203
-13
lines changed

8 files changed

+203
-13
lines changed

.github/workflows/main.yml

+9-9
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ jobs:
1818

1919
steps:
2020
- name: Begin CI...
21-
uses: actions/checkout@v2
21+
uses: actions/checkout@v3
2222
- name: Use Node ${{ env.NODE_VERSION }}
23-
uses: actions/setup-node@v2
23+
uses: actions/setup-node@v3
2424
with:
2525
node-version: ${{ env.NODE_VERSION }}
26-
- uses: actions/cache@v2
26+
- uses: actions/cache@v3
2727
with:
2828
path: '**/node_modules'
2929
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
@@ -38,8 +38,8 @@ jobs:
3838

3939
steps:
4040
- name: Begin CI...
41-
uses: actions/checkout@v2
42-
- uses: actions/cache@v2
41+
uses: actions/checkout@v3
42+
- uses: actions/cache@v3
4343
with:
4444
path: '**/node_modules'
4545
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
@@ -54,8 +54,8 @@ jobs:
5454

5555
steps:
5656
- name: Begin CI...
57-
uses: actions/checkout@v2
58-
- uses: actions/cache@v2
57+
uses: actions/checkout@v3
58+
- uses: actions/cache@v3
5959
with:
6060
path: '**/node_modules'
6161
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
@@ -71,8 +71,8 @@ jobs:
7171

7272
steps:
7373
- name: Begin CI...
74-
uses: actions/checkout@v2
75-
- uses: actions/cache@v2
74+
uses: actions/checkout@v3
75+
- uses: actions/cache@v3
7676
with:
7777
path: '**/node_modules'
7878
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}

.github/workflows/prepare-release.yml

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Prepare Release
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- '**'
8+
9+
env:
10+
CI: true
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
build:
17+
permissions:
18+
contents: write # for softprops/action-gh-release to create GitHub release
19+
20+
runs-on: ubuntu-latest
21+
22+
strategy:
23+
matrix:
24+
node-version: [18]
25+
26+
steps:
27+
- uses: actions/checkout@v3
28+
29+
- run: git fetch --tags -f
30+
31+
- name: Resolve version
32+
id: vars
33+
run: |
34+
echo "TAG_NAME=${{ github.ref_name }}" >> $GITHUB_ENV
35+
36+
- name: Get release notes
37+
run: |
38+
RELEASE_NOTES=$(npm run release-notes $TAG_NAME --silent)
39+
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
40+
echo "$RELEASE_NOTES" >> $GITHUB_ENV
41+
echo "EOF" >> $GITHUB_ENV
42+
43+
- name: Use Node.js ${{ matrix.node-version }}
44+
uses: actions/setup-node@v3
45+
with:
46+
node-version: ${{ matrix.node-version }}
47+
registry-url: 'https://registry.npmjs.org'
48+
49+
- name: Release
50+
uses: softprops/action-gh-release@v1
51+
with:
52+
draft: true
53+
tag_name: ${{ env.TAG_NAME }}
54+
body: |
55+
${{ env.RELEASE_NOTES }}

.github/workflows/release-insiders.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ jobs:
1717
node-version: [16]
1818

1919
steps:
20-
- uses: actions/checkout@v2
20+
- uses: actions/checkout@v3
2121

2222
- name: Use Node.js ${{ matrix.node-version }}
23-
uses: actions/setup-node@v2
23+
uses: actions/setup-node@v3
2424
with:
2525
node-version: ${{ matrix.node-version }}
2626
registry-url: 'https://registry.npmjs.org'
2727

2828
- name: Use cached node_modules
2929
id: cache
30-
uses: actions/cache@v2
30+
uses: actions/cache@v3
3131
with:
3232
path: '**/node_modules'
3333
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}

.github/workflows/release.yml

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
9+
cancel-in-progress: true
10+
11+
permissions:
12+
contents: read
13+
14+
env:
15+
CI: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
21+
strategy:
22+
matrix:
23+
node-version: [16]
24+
25+
steps:
26+
- uses: actions/checkout@v3
27+
28+
- name: Use Node.js ${{ matrix.node-version }}
29+
uses: actions/setup-node@v3
30+
with:
31+
node-version: ${{ matrix.node-version }}
32+
registry-url: 'https://registry.npmjs.org'
33+
34+
- name: Use cached node_modules
35+
id: cache
36+
uses: actions/cache@v3
37+
with:
38+
path: '**/node_modules'
39+
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
40+
restore-keys: |
41+
nodeModules-
42+
43+
- name: Install dependencies
44+
run: yarn install --frozen-lockfile
45+
env:
46+
CI: true
47+
48+
- name: Test
49+
run: |
50+
yarn test || yarn test || yarn test || exit 1
51+
env:
52+
CI: true
53+
54+
- name: Calculate environment variables
55+
run: |
56+
echo "TAG_NAME=${{ github.event.tag_name }}" >> $GITHUB_ENV
57+
echo "RELEASE_CHANNEL=$(npm run release-channel $TAG_NAME --silent)" >> $GITHUB_ENV
58+
echo "PACKAGE_PATH=$(npm run package-path $TAG_NAME --silent)" >> $GITHUB_ENV
59+
60+
- name: Publish
61+
run: npm publish ${{ env.PACKAGE_PATH }} --tag ${{ env.RELEASE_CHANNEL }}
62+
env:
63+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
"build": "npm-run-all -p 'react build' 'vue build'",
2121
"test": "./scripts/test.sh",
2222
"lint": "./scripts/lint.sh",
23-
"lint-check": "CI=true ./scripts/lint.sh"
23+
"lint-check": "CI=true ./scripts/lint.sh",
24+
"release-channel": "node ./scripts/release-channel.js",
25+
"release-notes": "node ./scripts/release-notes.js",
26+
"package-path": "node ./scripts/package-path.js"
2427
},
2528
"husky": {
2629
"hooks": {

scripts/package-path.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Given a version, figure out what the release notes are so that we can use this to pre-fill the
2+
// relase notes on a GitHub release for the current version.
3+
4+
let path = require('path')
5+
let { execSync } = require('child_process')
6+
7+
let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim()
8+
let pkgPath = path.resolve(
9+
__dirname,
10+
'..',
11+
'packages',
12+
tag.slice(0, tag.indexOf('@', 1)).replace('/', '-')
13+
)
14+
15+
console.log('./' + path.relative(process.cwd(), pkgPath))

scripts/release-channel.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Given a version, figure out what the release channel is so that we can publish to the correct
2+
// channel on npm.
3+
//
4+
// E.g.:
5+
//
6+
// 1.2.3 -> latest (default)
7+
// 0.0.0-insiders.ffaa88 -> insiders
8+
// 4.1.0-alpha.4 -> alpha
9+
10+
let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim()
11+
let pkgPath = path.resolve(
12+
__dirname,
13+
'..',
14+
'packages',
15+
tag.slice(0, tag.indexOf('@', 1)).replace('/', '-')
16+
)
17+
18+
let version = require(path.resolve(pkgPath, 'package.json')).version
19+
20+
let match = /\d+\.\d+\.\d+-(.*)\.\d+/g.exec(version)
21+
if (match) {
22+
console.log(match[1])
23+
} else {
24+
console.log('latest')
25+
}

scripts/release-notes.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Given a version, figure out what the release notes are so that we can use this to pre-fill the
2+
// relase notes on a GitHub release for the current version.
3+
4+
let path = require('path')
5+
let fs = require('fs')
6+
let { execSync } = require('child_process')
7+
8+
let tag = process.argv[2] || execSync(`git describe --tags --abbrev=0`).toString().trim()
9+
let pkgPath = path.resolve(
10+
__dirname,
11+
'..',
12+
'packages',
13+
tag.slice(0, tag.indexOf('@', 1)).replace('/', '-')
14+
)
15+
16+
let version = require(path.resolve(pkgPath, 'package.json')).version
17+
18+
let changelog = fs.readFileSync(path.resolve(pkgPath, 'CHANGELOG.md'), 'utf8')
19+
let match = new RegExp(
20+
`## \\[${version}\\] - (.*)\\n\\n([\\s\\S]*?)\\n(?:(?:##\\s)|(?:\\[))`,
21+
'g'
22+
).exec(changelog)
23+
24+
if (match) {
25+
let [, , notes] = match
26+
console.log(notes.trim())
27+
} else {
28+
console.log(`Placeholder release notes for version: v${version}`)
29+
}

0 commit comments

Comments
 (0)