From 37d8316ef2aefa86c20149de9d3b3137e6ca5d2c Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:32:15 -0600 Subject: [PATCH] feat: automate many release steps (#429) --- ...t_template.md => PULL_REQUEST_TEMPLATE.md} | 0 .../PULL_REQUEST_TEMPLATE/release_template.md | 29 ++++++ bin/release-functions.sh | 19 ++++ bin/release-prepare.sh | 95 +++++++++++++++++++ bin/release-publish.sh | 63 ++++++++++++ docs/contributing.md | 18 ++++ package.json | 1 - 7 files changed, 224 insertions(+), 1 deletion(-) rename .github/{pull_request_template.md => PULL_REQUEST_TEMPLATE.md} (100%) create mode 100644 .github/PULL_REQUEST_TEMPLATE/release_template.md create mode 100644 bin/release-functions.sh create mode 100755 bin/release-prepare.sh create mode 100755 bin/release-publish.sh diff --git a/.github/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/pull_request_template.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE/release_template.md b/.github/PULL_REQUEST_TEMPLATE/release_template.md new file mode 100644 index 000000000..90dac2f9a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/release_template.md @@ -0,0 +1,29 @@ +## Overview + +… + +## Related + +… + +## Changes + +… + +## Testing + +1. + +## UI + +… + + diff --git a/bin/release-functions.sh b/bin/release-functions.sh new file mode 100644 index 000000000..16382da09 --- /dev/null +++ b/bin/release-functions.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Function to prompt for confirmation +confirm() { + read -r -p "${1:-Are you sure?} [y/N] " response + case "$response" in + [yY][eE][sS]|[yY]) + true + ;; + *) + false + ;; + esac +} + +# Function to check if command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} diff --git a/bin/release-prepare.sh b/bin/release-prepare.sh new file mode 100755 index 000000000..55689db8b --- /dev/null +++ b/bin/release-prepare.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e # Exit on any error + +# Source shared functions +source "$(dirname "$0")/release-functions.sh" + +# Check required commands +if ! command_exists npm; then + echo "Error: npm is required but not installed" + exit 1 +fi +if ! command_exists git; then + echo "Error: git is required but not installed" + exit 1 +fi + +# Ensure working directory is clean except for CHANGELOG +if [ -n "$(git status --porcelain | grep -v 'CHANGELOG.md')" ]; then + echo "Error: Working directory has unexpected changes. Please commit or stash changes." + exit 1 +fi + +# Get current version and prompt for new version +current_version=$(npm pkg get version | tr -d '"') +read -r -p "Enter version number (current: $current_version, format: N.N.N): " version +version_tag="v$version" + +# Name the branch +branch_name="release/$version_tag" + +# Check if branch exists and handle accordingly +if git rev-parse --verify "$branch_name" >/dev/null 2>&1 || \ + git rev-parse --verify "origin/$branch_name" >/dev/null 2>&1; then + echo "Branch '$branch_name' already exists." + if confirm "Would you like to use the existing branch?"; then + git checkout "$branch_name" + git pull origin "$branch_name" 2>/dev/null || true # Pull if remote exists, ignore if it doesn't + else + echo "Release preparation cancelled." + exit 0 + fi +else + # Create new branch + git checkout -b "$branch_name" +fi + +# Confirm with user +echo "This script will:" +echo "1. Build CSS" +echo "2. Update version" +echo "3. Create release commit" +echo "4. Push branch to remote" +echo "5. Describe next steps" +if ! confirm "Do you want to proceed?"; then + echo "Release preparation cancelled." + exit 0 +fi + +# Build CSS +echo "Building CSS..." +npm run build:css + +# Check for substantial changes +if [ -n "$(git status --porcelain | grep -v 'CHANGELOG.md' | grep -v '^.. dist/')" ]; then + echo "Warning: Unexpected changes detected in build:" + git status --porcelain | grep -v 'CHANGELOG.md' | grep -v '^.. dist/' + echo "Please review changes and create an independent PR if necessary." + if ! confirm "Continue anyway?"; then + exit 1 + fi +fi + +# Prompt for CHANGELOG update +echo "Please update CHANGELOG.md now." +if ! confirm "Have you updated CHANGELOG.md?"; then + exit 1 +fi + +# Update version +echo "Updating version..." +npm version "$version_tag" --no-git-tag-version + +# Build again with new version +echo "Building with new version..." +npm run build:css + +# Commit changes +git add . +git commit -m "chore: $version_tag" + +# Push branch +git push origin "$branch_name" + +echo "Branch pushed. Please create and merge PR for $branch_name" +echo -e "After PR is merged, run:\n ./bin/release-publish.sh $version_tag" diff --git a/bin/release-publish.sh b/bin/release-publish.sh new file mode 100755 index 000000000..847379190 --- /dev/null +++ b/bin/release-publish.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e # Exit on any error + +# Source shared functions +source "$(dirname "$0")/release-functions.sh" + +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "Example: $0 v1.2.3" + exit 1 +fi + +version_tag=$1 + +# Check npm login status +if ! npm whoami >/dev/null 2>&1; then + echo "Error: You are not logged in to npm." + echo -e "Please login first with:\n npm login" + echo -e "\nNote: When running npm login, you'll be prompted to visit a URL in your browser." + echo "Make sure you're already logged into npmjs.com in your browser before starting." + exit 1 +fi + +# Ensure we're on main branch +git checkout main +git pull origin main + +# Check if version is already published +if npm view "@tacc/core-styles@${version_tag#v}" >/dev/null 2>&1; then + echo "Version ${version_tag#v} is already published to npm." + if confirm "Skip npm publish step?"; then + echo "Skipping npm publish..." + else + echo "Aborting to avoid version conflict." + exit 1 + fi +else + # Publish to npm + echo "Publishing to npm..." + npm publish --access public +fi + +# Create GitHub release +echo "Please create a release on GitHub now." +echo "Visit: https://github.com/TACC/Core-Styles/releases/new" +read -p "Press Enter once you've created the release..." + +# Fetch and check tags +echo "Fetching tags..." +git fetch --tags + +echo "Checking if tag is annotated..." +if git describe --exact-match "$version_tag" >/dev/null 2>&1; then + echo "Tag $version_tag is already annotated" +else + echo "Tag $version_tag is not annotated, annotating..." + ./bin/annotate-tag.sh "$version_tag" + + echo "Force pushing annotated tag..." + git push --tags --force +fi + +echo "Release process complete!" \ No newline at end of file diff --git a/docs/contributing.md b/docs/contributing.md index 91ff8fc42..1b14f2213 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -33,6 +33,22 @@ We use a modifed version of [GitFlow](https://datasift.github.io/gitflow/Introdu Only appointed team members may release versions. +### Automated Release (Bash Scripts) + +1. (one time) Login to npm via:\ + `npm login` +2. Run the release preparation script:\ + `./bin/release-prepare.sh` +3. Create and merge the PR. +4. Run the release publish script:\ + `./bin/release-publish.sh vN.N.N`\ + (where `N.N.N` is the version tag) + +### Manual Release Steps + +
+Instructions + 1. (one time) Login to npm via:\ `npm login` 1. Create new branch for version bump. @@ -61,3 +77,5 @@ Only appointed team members may release versions. (where `N.N.N` is the version tag) 1. Overwrite remote tag with annotated one:\ `git push --tags --force` + +
diff --git a/package.json b/package.json index 9ef4a7bcc..09339ec40 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "build:demo": "fractal build", "test": "bin/test.js && echo \"Test output at 'dist/_tests' (compare to test input)\"", "build:watch": "npm run build:css && touch src/lib/_imports/fractal.server.refresh.css", - "prepublishOnly": "npm run build:css", "watch": "npm-watch" }, "engines": {