From 9b973ebf02c327c21a29c03469bced4f25116d22 Mon Sep 17 00:00:00 2001 From: Robert MacEachern Date: Mon, 25 Nov 2024 14:47:00 -0600 Subject: [PATCH] chore(ios): Scripts for preparing release and changelog (#529) This adds a script to streamline the release (and changelog management) steps for Blueprint. I used it to generate the release for 5.1.0. https://github.com/square/Blueprint/pull/528 Highlights: - Checks out a new branch and updates the version info - Stamps the changelog and adds a new link reference (and updates the `[Main]` one) - Opens a draft PR (requires `gh` to be installed and authed). - The PR description includes post-merge instructions that still need to be run manually. --- CHANGELOG.md | 2 +- RELEASING.md | 16 +++++- Scripts/release.sh | 107 +++++++++++++++++++++++++++++++++++++ Scripts/stamp-changelog.sh | 79 +++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 2 deletions(-) create mode 100755 Scripts/release.sh create mode 100755 Scripts/stamp-changelog.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index f6bf8ed03..0b0299152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Internal -# Past Releases +- Added release and changelog managements scripts to streamline releases. ## [5.0.1] - 2024-11-04 diff --git a/RELEASING.md b/RELEASING.md index 63b13b5bf..442a44238 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,5 +1,16 @@ # Releasing a new version +1. Prepare a release + + ``` + # Cuts a release off of main with the given version number. + Scripts/release.sh --version 1.2.3 + ``` + +Manual instructions can be found here: + +
+ 1. You must be listed as an owner of the pods `BlueprintUI` and `BlueprintUICommonControls`. To check this run: @@ -17,7 +28,7 @@ 1. Update the library version in `version.rb` if it has not already been updated (it should match the version number that you are about to release). -1. Update `CHANGELOG.md` (in the root of the repo), moving current changes under `Main` to a new section under `Past Releases` for the version you are releasing. +1. Update `CHANGELOG.md` (in the root of the repo), moving current changes under `Main` to a new section for the version you are releasing. The changelog uses [reference links](https://daringfireball.net/projects/markdown/syntax#link) to link each version's changes. Remember to add a link to the new version at the bottom of the file, and to update the link to `[main]`. @@ -32,6 +43,8 @@ 1. Push your branch and open a PR into `main`. +
+ 1. Once the PR is merged, fetch changes and tag the release, using the merge commit: ```bash git fetch @@ -49,3 +62,4 @@ # version of BlueprintUI that we just published. bundle exec pod trunk push --synchronous BlueprintUICommonControls.podspec ``` + \ No newline at end of file diff --git a/Scripts/release.sh b/Scripts/release.sh new file mode 100755 index 000000000..1e801a2b2 --- /dev/null +++ b/Scripts/release.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +set -euo pipefail + +branch="main" +diff_check=false + +# Function to display usage +usage() { + echo "Usage: $0 --version [--branch ] [--no-diff-check]" + exit 1 +} + +# Check if gh CLI is installed +if ! command -v gh &> /dev/null; then + echo "Error: GitHub CLI (gh) is not installed. It is required by this script." + echo "Please install it from https://cli.github.com/, authenticate, and try again." + exit 1 +fi + +# Parse options +while [[ $# -gt 0 ]]; do + case $1 in + -v|--version) version="$2"; shift 2 ;; + -b|--branch) branch="$2"; shift 2 ;; + -n|--no-diff-check) diff_check=false; shift ;; + --) shift; break ;; + -*|--*) echo "Unknown option $1"; usage ;; + *) break ;; + esac +done + +# Check if version argument is provided +if [ -z "${version:-}" ]; then + echo "Error: You must provide a version number." + usage +fi + +# Ensure there are no unstaged changes +if [ "$diff_check" = true ] && ! git diff --quiet origin/"$branch"; then + echo "Error: This branch has differences compared to origin/$branch. Please push or undo these changes before continuing." + echo "You can bypass this check with the --no-diff-check flag." + exit 1 +fi + +# This timestamp is used during branch creation. +# It's helpful in cases where the script fails and a new branch needs to +# be created on a subsequent attempt. +timestamp=$(date +"%Y-%m-%d-%H_%M_%S") + +git checkout "$branch" +git pull + +# Create a new branch with the version and timestamp +branch_name="$(whoami)/release-$version-$timestamp" +git checkout -b "$branch_name" + +# Define the git repo root +repo_root=$(git rev-parse --show-toplevel) + +# Extract the previous version number from version.rb +previous_version=$(grep 'BLUEPRINT_VERSION' "$repo_root/version.rb" | awk -F"'" '{print $2}') + +# Update the library version in version.rb +sed -i '' "s/BLUEPRINT_VERSION ||= .*/BLUEPRINT_VERSION ||= '$version'/" "$repo_root/version.rb" + +# Update CHANGELOG.md using stamp-changelog.sh +"$repo_root/Scripts/stamp-changelog.sh" --version "$version" --previous-version "$previous_version" + +# Change directory into the SampleApp dir and update Podfile.lock using a subshell +( + cd "$repo_root/SampleApp" + bundle exec pod install +) + +# Commit the changes +git add . +git commit -m "Bumping versions to $version." + +# Push the branch and open a PR into main +git push origin "$branch_name" + +pr_body=$(cat <<-END +https://github.com/square/Blueprint/blob/main/CHANGELOG.md + +Post-merge steps: + +- Once the PR is merged, fetch changes and tag the release, using the merge commit: + \`\`\` + git fetch + git tag $version + git push origin $version + \`\`\` + +- Publish to CocoaPods: + \`\`\` + bundle exec pod trunk push BlueprintUI.podspec + bundle exec pod trunk push --synchronous BlueprintUICommonControls.podspec + \`\`\` +END +) + +gh pr create --draft --title "release: Blueprint $version" --body "$pr_body" + +gh pr view --web + +echo "Branch $branch_name created and pushed. A draft PR has been created." diff --git a/Scripts/stamp-changelog.sh b/Scripts/stamp-changelog.sh new file mode 100755 index 000000000..99d908fb6 --- /dev/null +++ b/Scripts/stamp-changelog.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Function to display usage +usage() { + echo "Usage: $0 -v -p " + echo " -v, --version Version number (required)" + echo " -p, --previous-version Previous version number (required)" + echo " -d, --release-date The date of the release (optional). Defaults to: date +%Y-%m-%d" + exit 1 +} + +# Parse options +while [[ "$#" -gt 0 ]]; do + case "$1" in + -v|--version) version="$2"; shift 2 ;; + -p|--previous-version) previous_version="$2"; shift 2 ;; + -d|--release-date) release_date="$2"; shift 2 ;; + --) shift; break ;; + -*|--*) echo "Unknown option $1"; usage ;; + *) break ;; + esac +done + +# Check if both version and previous_version arguments are provided +if [ -z "$version" ] || [ -z "$previous_version" ]; then + echo "Error: You must provide both version and previous version numbers." + usage +fi + +if [ -z "$release_date" ]; then + release_date=$(date +%Y-%m-%d) +fi + +repo_root=$(git rev-parse --show-toplevel) +changelog_file="$repo_root/CHANGELOG.md" + +changelog=$(ruby < "$changelog_file" + +echo "CHANGELOG.md updated for version $version." \ No newline at end of file