Skip to content

Commit

Permalink
chore(ios): Scripts for preparing release and changelog (#529)
Browse files Browse the repository at this point in the history
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.
#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.
  • Loading branch information
robmaceachern authored Nov 25, 2024
1 parent 594b6c5 commit 9b973eb
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 15 additions & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
@@ -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:

<details>

1. You must be listed as an owner of the pods `BlueprintUI` and `BlueprintUICommonControls`.

To check this run:
Expand All @@ -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]`.

Expand All @@ -32,6 +43,8 @@

1. Push your branch and open a PR into `main`.

</details>

1. Once the PR is merged, fetch changes and tag the release, using the merge commit:
```bash
git fetch
Expand All @@ -49,3 +62,4 @@
# version of BlueprintUI that we just published.
bundle exec pod trunk push --synchronous BlueprintUICommonControls.podspec
```

107 changes: 107 additions & 0 deletions Scripts/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash

set -euo pipefail

branch="main"
diff_check=false

# Function to display usage
usage() {
echo "Usage: $0 --version <version> [--branch <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 <merge commit SHA>
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."
79 changes: 79 additions & 0 deletions Scripts/stamp-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

# Function to display usage
usage() {
echo "Usage: $0 -v <version> -p <previous-version>"
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 <<EOF
changelog_contents = File.read('$changelog_file')
changelog_contents.gsub!(/(###.*\n\n)+#/, '#')
puts changelog_contents
EOF
)

# Define the changelog template
unreleased_changelog_template="## [Main]\n\
\n\
### Fixed\n\
\n\
### Added\n\
\n\
### Removed\n\
\n\
### Changed\n\
\n\
### Deprecated\n\
\n\
### Security\n\
\n\
### Documentation\n\
\n\
### Misc\n\
\n\
### Internal\n\
\n\
## [$version] - $release_date"

# Replace the Main section with the new template
changelog=$(echo "$changelog" | sed "s/^## \[Main\]/$unreleased_changelog_template/")

# Replace the line starting with "[main]: " to the new URL
changelog=$(echo "$changelog" | sed "s|^\[main\]: .*|\[main\]: https://github.com/square/Blueprint/compare/$version...HEAD|")

# Append the new version comparison link at the end of the file
changelog="$changelog"$'\n'"[$version]: https://github.com/square/Blueprint/compare/$previous_version...$version"

# Write the updated contents back to the changelog file
echo "$changelog" > "$changelog_file"

echo "CHANGELOG.md updated for version $version."

0 comments on commit 9b973eb

Please sign in to comment.