diff --git a/package.json b/package.json index 2536812..b57a692 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "package": "npx ncc build src/index.ts -o dist --source-map --license licenses.txt", "package:watch": "npm run package -- --watch", "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest", + "release": "node script/release.js", "all": "npm run format:write && npm run lint && npm run test && npm run coverage && npm run package" }, "license": "MIT", diff --git a/script/release b/script/release deleted file mode 100755 index 47ad5bd..0000000 --- a/script/release +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -# About: -# -# This is a helper script to tag and push a new release. GitHub Actions use -# release tags to allow users to select a specific version of the action to use. -# -# See: https://github.com/actions/typescript-action#publishing-a-new-release -# -# This script will do the following: -# -# 1. Get the latest release tag -# 2. Prompt the user for a new release tag -# 3. Tag the new release -# 4. Push the new tag to the remote -# -# Usage: -# -# script/release - -# Terminal colors -OFF='\033[0m' -RED='\033[0;31m' -GREEN='\033[0;32m' -BLUE='\033[0;34m' - -# Get the latest release tag -latest_tag=$(git describe --tags --match='v*.*.*' "$(git rev-list --tags --max-count=1)") - -if [[ -z "$latest_tag" ]]; then - # There are no existing release tags - echo -e "No tags found (yet) - Continue to create and push your first tag" - latest_tag="[unknown]" -fi - -# Display the latest release tag -echo -e "The latest release tag is: ${BLUE}${latest_tag}${OFF}" - -# Prompt the user for the new release tag -read -r -p 'Enter a new release tag (vX.X.X format): ' new_tag - -# Validate the new release tag -tag_regex='v[0-9]+\.[0-9]+\.[0-9]+$' -if echo "$new_tag" | grep -q -E "$tag_regex"; then - echo -e "Tag: ${BLUE}$new_tag${OFF} is valid" -else - # Release tag is not `vX.X.X` format - echo -e "Tag: ${BLUE}$new_tag${OFF} is ${RED}not valid${OFF} (must be in vX.X.X format)" - exit 1 -fi - -# Tag the new release -git tag -a "$new_tag" -m "$new_tag Release" -echo -e "${GREEN}Tagged: $new_tag${OFF}" - -# Tag major version -new_major_tag=${new_tag%%.*} -git tag -fa "$new_major_tag" -m "Update $new_major_tag tag" -echo -e "${GREEN}Tagged: $new_major_tag${OFF}" - -# Push the new tag to the remote -git push --tags --force -echo -e "${GREEN}Release tag pushed to remote${OFF}" -echo -e "${GREEN}Done!${OFF}" diff --git a/script/release.js b/script/release.js new file mode 100644 index 0000000..a125872 --- /dev/null +++ b/script/release.js @@ -0,0 +1,78 @@ +/** + * This is a helper script to tag and push a new release. GitHub Actions use + * release tags to allow users to select a specific version of the action to use. + * + * See: https://github.com/actions/typescript-action#publishing-a-new-release + * + * This script will do the following: + * + * 1. Get the latest release tag + * 2. Prompt the user for a new release tag + * 3. Tag the new release + * 4. Push the new tag to the remote + * + * Usage: node script/release.js + */ + +import readline from 'node:readline/promises' +import { stdin as input, stdout as output } from 'node:process' +import { simpleGit } from 'simple-git' + +// Terminal colors +const OFF = '\x1B[0m' +const RED = '\x1B[0;31m' +const GREEN = '\x1B[0;32m' +const BLUE = '\x1B[0;34m' + +const git = simpleGit() + +try { + // Get the latest release tag + let latestTag = (await git.tags()).latest + + if (!latestTag) { + // There are no existing release tags + console.log( + 'No tags found (yet) - Continue to create and push your first tag' + ) + latestTag = '[unknown]' + } + + // Display the latest release tag + console.log(`The latest release tag is: ${BLUE}${latestTag}${OFF}`) + + // Prompt the user for the new release tag + const rl = readline.createInterface({ input, output }) + const newTag = ( + await rl.question('Enter a new release tag (vX.X.X format): ') + ).trim() + rl.close() + + // Validate if the new release tag is in the format vX.X.X + const tagRegex = /^v\d+\.\d+\.\d+$/ + if (tagRegex.test(newTag)) { + console.log(`Tag: ${BLUE}${newTag}${OFF} is valid`) + } else { + console.error( + `Tag: ${BLUE}${newTag}${OFF} is ${RED}not valid${OFF} (must be in vX.X.X format)` + ) + process.exit(1) + } + + // Tag the new release + await git.addAnnotatedTag(newTag, `${newTag} Release`) + console.log(`${GREEN}Tagged: ${newTag}${OFF}`) + + // Tag major version (extract the "vX" from "vX.X.X") + const newMajorTag = newTag.split('.')[0] + await git.tag(['-fa', newMajorTag, '-m', `Update ${newMajorTag} tag`]) + console.log(`${GREEN}Tagged: ${newMajorTag}${OFF}`) + + // Push the new tag to the remote + await git.push(['--tags', '--force']) + console.log(`${GREEN}Release tag pushed to remote${OFF}`) + console.log(`${GREEN}Done!${OFF}`) +} catch (error) { + console.error(`${RED}Error:${OFF} ${error}`) + process.exit(1) +}