Skip to content

Commit 4e52163

Browse files
committed
refactor: make release script OS-agnostic by migrating from bash to node
1 parent 7daeb44 commit 4e52163

File tree

3 files changed

+79
-64
lines changed

3 files changed

+79
-64
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"package": "npx ncc build src/index.ts -o dist --source-map --license licenses.txt",
3434
"package:watch": "npm run package -- --watch",
3535
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest",
36+
"release": "node script/release.js",
3637
"all": "npm run format:write && npm run lint && npm run test && npm run coverage && npm run package"
3738
},
3839
"license": "MIT",

script/release

-64
This file was deleted.

script/release.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* This is a helper script to tag and push a new release. GitHub Actions use
3+
* release tags to allow users to select a specific version of the action to use.
4+
*
5+
* See: https://github.com/actions/typescript-action#publishing-a-new-release
6+
*
7+
* This script will do the following:
8+
*
9+
* 1. Get the latest release tag
10+
* 2. Prompt the user for a new release tag
11+
* 3. Tag the new release
12+
* 4. Push the new tag to the remote
13+
*
14+
* Usage: node script/release.js
15+
*/
16+
17+
import readline from 'node:readline/promises'
18+
import { stdin as input, stdout as output } from 'node:process'
19+
import { simpleGit } from 'simple-git'
20+
21+
// Terminal colors
22+
const OFF = '\x1B[0m'
23+
const RED = '\x1B[0;31m'
24+
const GREEN = '\x1B[0;32m'
25+
const BLUE = '\x1B[0;34m'
26+
27+
const git = simpleGit()
28+
29+
try {
30+
// Get the latest release tag
31+
let latestTag = (await git.tags()).latest
32+
33+
if (!latestTag) {
34+
// There are no existing release tags
35+
console.log(
36+
'No tags found (yet) - Continue to create and push your first tag'
37+
)
38+
latestTag = '[unknown]'
39+
}
40+
41+
// Display the latest release tag
42+
console.log(`The latest release tag is: ${BLUE}${latestTag}${OFF}`)
43+
44+
// Prompt the user for the new release tag
45+
const rl = readline.createInterface({ input, output })
46+
const newTag = (
47+
await rl.question('Enter a new release tag (vX.X.X format): ')
48+
).trim()
49+
rl.close()
50+
51+
// Validate if the new release tag is in the format vX.X.X
52+
const tagRegex = /^v\d+\.\d+\.\d+$/
53+
if (tagRegex.test(newTag)) {
54+
console.log(`Tag: ${BLUE}${newTag}${OFF} is valid`)
55+
} else {
56+
console.error(
57+
`Tag: ${BLUE}${newTag}${OFF} is ${RED}not valid${OFF} (must be in vX.X.X format)`
58+
)
59+
process.exit(1)
60+
}
61+
62+
// Tag the new release
63+
await git.addAnnotatedTag(newTag, `${newTag} Release`)
64+
console.log(`${GREEN}Tagged: ${newTag}${OFF}`)
65+
66+
// Tag major version (extract the "vX" from "vX.X.X")
67+
const newMajorTag = newTag.split('.')[0]
68+
await git.tag(['-fa', newMajorTag, '-m', `Update ${newMajorTag} tag`])
69+
console.log(`${GREEN}Tagged: ${newMajorTag}${OFF}`)
70+
71+
// Push the new tag to the remote
72+
await git.push(['--tags', '--force'])
73+
console.log(`${GREEN}Release tag pushed to remote${OFF}`)
74+
console.log(`${GREEN}Done!${OFF}`)
75+
} catch (error) {
76+
console.error(`${RED}Error:${OFF} ${error}`)
77+
process.exit(1)
78+
}

0 commit comments

Comments
 (0)