From 7eec70276e2f18cd9f15abe5339133e48e138778 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 15 Oct 2020 12:57:38 -0600 Subject: [PATCH] Add release scripts and RELEASE_GUIDE (#3191) --- BRANCHING.md | 52 ----------- RELEASE_GUIDE.md | 138 +++++++++++++++++++++++++++ build/common/bump-version.sh | 75 +++++++++++++++ build/common/release.sh | 175 +++++++++++++++++++++++++++++++++++ 4 files changed, 388 insertions(+), 52 deletions(-) create mode 100644 RELEASE_GUIDE.md create mode 100755 build/common/bump-version.sh create mode 100755 build/common/release.sh diff --git a/BRANCHING.md b/BRANCHING.md index 7c628fc88b..cf15e12754 100644 --- a/BRANCHING.md +++ b/BRANCHING.md @@ -27,55 +27,3 @@ Bugs are defined as one of the following _introduced since the prior release_: - unintentional public API changes For example, a long-standing crash just recently discovered would not necessitate a bug fix PR. - -## Creating a GitHub Release - -Be sure to choose the *release* branch when drafting a GitHub release. - -## Git Commands - -These commands assume a release candidate branch called *rc/1.9.0*. - -### Creating a Release Candidate Branch - -``` -$ git checkout main -$ git pull -$ git branch rc/1.9.0 -$ git push origin rc/1.9.0 -``` - -### Merging the Release Candidate Branch Into Release - -There may be temporary hotfixes in the release branch that should be overriden by the new release -candidate. To accomplish this, we first merge release into rc using the _ours_ strategy. Then we -merge rc into release. - -``` -$ git checkout rc/1.9.0 -$ git pull -$ git fetch origin release:release -$ git merge -s ours release -$ git checkout release -$ git merge --no-ff rc/1.9.0 -$ git push origin release -``` - -### Deleting the Release Candidate Branch - -``` -$ git branch -d rc/1.9.0 -$ git push origin --delete rc/1.9.0 -``` - -### See a History of the Release Branch - -``` -$ git log --oneline --first-parent - -442b061 (HEAD -> release) Merge branch 'rc/1.9.2' into release -ac50d21 Hotfix -94dc2f7 Hotfix -b34ed5b Merge branch 'rc/1.9.1' into release -aeef498 Merge branch 'rc/1.9.0' into release -``` diff --git a/RELEASE_GUIDE.md b/RELEASE_GUIDE.md new file mode 100644 index 0000000000..8e9aa4f267 --- /dev/null +++ b/RELEASE_GUIDE.md @@ -0,0 +1,138 @@ +# Filament Release Guide + +This guide makes use of some "environment variables": +- $RELEASE = the new version of Filament we are releasing today. (e.g., 1.9.3) +- $NEXT_RELEASE = the version we plan to release next week (e.g., 1.9.4) + +Before starting, ensure that each of these branches is up-to-date with origin: +- release +- rc/$RELEASE +- main + +## 0. Make sure the rc/$RELEASE branch has the correct version. + +It should have the version corresponding to its name, $RELEASE. + +## 1. Update RELEASE_NOTES.md on the rc branch. + +Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE +and write release notes. To see which commits make up the release, run: + +``` +build/common/release.sh -c rc/$RELEASE +``` + +Commit the changes to rc/$RELEASE with the title: + +``` +Update RELEASE_NOTES for $RELEASE +``` + +## 2. Bump versions on main to $RELEASE. + +Checkout main and run the following command to bump Filament's version to $RELEASE: + +``` +build/common/bump-version.sh $RELEASE +``` + +Commit changes to main with the title: + +``` +Bump version to $RELEASE +``` + +Do not push to origin yet. + +## 3. Cherry-pick RELEASE_NOTES change from rc branch to main. + +``` +git cherry-pick rc/$RELEASE +``` + +Update the headers. The "Next release" header becomes a header for $NEXT_RELEASE, and a new "Next +release" header is added. + +For example, this: + +``` +## Next release (main branch) +- foo +- bar + +## v1.9.3 +- baz +- bat +``` + +becomes: + +``` +## Next release (main branch) + +## v1.9.4 +- foo +- bar + +## v1.9.3 +- baz +- bat +``` + +Ammend these changes to the cherry-picked change. + +``` +git add -u +git commit --amend --no-edit +``` + +## 4. Run release script. + +``` +build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE +``` + +This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc +branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally. + +## 5. Push the release branch. + +``` +git push origin release +``` + +## 6. Create the GitHub release. + +Use the GitHub UI to create a GitHub release corresponding to $RELEASE version. +Make sure the target is set to the release branch. + +## 7. Delete the old rc branch. + +``` +git push origin --delete rc/$RELEASE +``` + +## 8. Bump the version on the new rc branch to $NEXT_RELEASE. + +``` +git checkout rc/$NEXT_RELEASE +build/common/bump-version.sh $NEXT_RELEASE +``` + +Commit the changes to rc/$NEXT_RELEASE with the title: + +``` +Bump version to $NEXT_RELEASE +``` + +## 9. Push main. + +``` +git push origin main +``` + +## 10. Push the new rc branch. + +``` +git push origin rc/$NEXT_RELEASE +``` diff --git a/build/common/bump-version.sh b/build/common/bump-version.sh new file mode 100755 index 0000000000..2a8bcb135d --- /dev/null +++ b/build/common/bump-version.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +set -e + +function print_help { + local SELF_NAME + SELF_NAME=$(basename "$0") + echo "$SELF_NAME. Update the Filament version number." + echo "" + echo "Usage:" + echo " $SELF_NAME " + echo "" + echo " should be a 3 part semantic version, such as 1.9.3" + echo "" + echo "This script does not interface with git. It is up to the user to commit the change." + echo "" + echo "Options:" + echo " -h" + echo " Print this help message and exit." +} + +while getopts "h" opt; do + case ${opt} in + h) + print_help + exit 0 + ;; + *) + print_help + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ "$#" -ne 1 ]]; then + print_help + exit 1 +fi + +VERSION_REGEX="[[:digit:]]+.[[:digit:]]+.[[:digit:]]+" +NEW_VERSION="$1" + +function replace { + FIND_STR="${1//\{\{VERSION\}\}/${VERSION_REGEX}}" + REPLACE_STR="${1//\{\{VERSION\}\}/${NEW_VERSION}}" + local FILE_NAME="$2" + sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}" +} + +# The following are the canonical locations where the Filament version number is referenced. + +replace \ + "implementation 'com.google.android.filament:filament-android:{{VERSION}}'" \ + README.md + +replace \ + "pod 'Filament', '~> {{VERSION}}'" \ + README.md + +replace \ + "VERSION_NAME={{VERSION}}" \ + android/gradle.properties + +replace \ + "spec.version = \"{{VERSION}}\"" \ + ios/CocoaPods/Filament.podspec + +replace \ + ":http => \"https:\/\/github.com\/google\/filament\/releases\/download\/v{{VERSION}}\/filament-v{{VERSION}}-ios.tgz\" }" \ + ios/CocoaPods/Filament.podspec + +replace \ + "\"version\": \"{{VERSION}}\"" \ + web/filament-js/package.json diff --git a/build/common/release.sh b/build/common/release.sh new file mode 100755 index 0000000000..81c87e303b --- /dev/null +++ b/build/common/release.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash + +set -e + +function print_help { + local SELF_NAME + SELF_NAME=$(basename "$0") + echo "$SELF_NAME. Merge the release candidate (rc) branch into release and cut a new rc branch." + echo "" + echo "Usage:" + echo " $SELF_NAME [options] " + echo " $SELF_NAME -c " + echo "" + echo "current rc branch name should be the name of an existing rc/* branch" + echo "new rc branch name should be the new rc branch name and should not exist" + echo "" + echo "Example:" + echo " $SELF_NAME rc/1.9.3 rc/1.9.4" + echo "" + echo "Options:" + echo " -c" + echo " List the commits that make up a release and exit." + echo " -h" + echo " Print this help message and exit." + echo " -p" + echo " Automatically push changes to origin (dangerous)." +} + +function list_commits { + git log --oneline release.."$1" +} + +PUSH_CHANGES=false +LIST_COMMITS=false +while getopts "hpc" opt; do + case ${opt} in + h) + print_help + exit 0 + ;; + p) + PUSH_CHANGES=true + ;; + c) + LIST_COMMITS=true + ;; + *) + print_help + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ "${LIST_COMMITS}" == "true" ]]; then + if [[ "$#" -ne 1 ]]; then + print_help + exit 1 + fi + + RC_BRANCH=$1 + + list_commits "${RC_BRANCH}" + exit 0 +fi + +if [[ "$#" -ne 2 ]]; then + print_help + exit 1 +fi + +RC_BRANCH=$1 +NEW_RC_BRANCH=$2 + +#################################################################################################### +# Preamble +#################################################################################################### + +# Check that the RC_BRANCH is a real branch. +git show-branch "${RC_BRANCH}" >/dev/null 2>&1 || { + echo "Branch ${RC_BRANCH} does not exist (try running git fetch first)." + exit 1 +} + +# Ensure no staged or working changes +if [ ! -z "$(git status --untracked-files=no --porcelain)" ]; then + echo "You have uncommited changes. Please stash or commit before running." + exit 1 +fi + +# Make sure release, main, and the release candidate branch are up-to-date. +git checkout main +git pull origin main --rebase + +git checkout "${RC_BRANCH}" +git pull origin "${RC_BRANCH}" --rebase + +git checkout release +git pull origin release --rebase + +#################################################################################################### +# Merge rc branch into release +#################################################################################################### + +# We need to merge rc into release in a somewhat roundabout way because we want the merge to always +# favor the changes on the rc branch. Any commits *only* on the release branch should be lost. These +# abandonded commits should only ever be temporary hotfixes. +# See the last part of https://stackoverflow.com/a/27338013/2671441 for more details. +# The benefit of this strategy is that we'll never get any merge conflicts. All of these commands +# can run without human intervention. + +git checkout release + +# Do a merge commit. The content of this commit does not matter, so we use a strategy that never +# fails. This advances release. +git merge --no-edit -s ours "${RC_BRANCH}" + +# Change working tree and index to desired content. +# --detach ensures rc branch will not move when doing the reset in the next step. +git checkout --detach "${RC_BRANCH}" + +# Move HEAD to release without changing contents of working tree and index. +git reset --soft release + +# 'attach' HEAD to release. +# This ensures release will move when doing 'commit --amend'. +git checkout release + +# Change content of merge commit to current index (i.e. content of rc branch). +git commit --amend -C HEAD + +#################################################################################################### +# Cut a new release candidate branch +#################################################################################################### + +git checkout main +git branch --track "${NEW_RC_BRANCH}" + +#################################################################################################### +# Delete the old release candidate branch +#################################################################################################### + +git branch -D "${RC_BRANCH}" + +#################################################################################################### +# Push changes +#################################################################################################### + +if [[ "${PUSH_CHANGES}" == "true" ]]; then + # Push the release branch + git push origin release + + # Delete the old rc branch remotely + git push origin --delete "${RC_BRANCH}" + + # Push the new rc branch + git push origin "${NEW_RC_BRANCH}" +else + echo "" + echo "Done." + echo "" + echo "Changes have not been pushed." + echo "If everything looks good locally, run the following:" + echo "---------------------------------------------------------" + echo "git push origin release" + echo "git push origin --delete ${RC_BRANCH}" + echo "git push origin ${NEW_RC_BRANCH}" + echo "---------------------------------------------------------" + echo "Or, to undo everything:" + echo "---------------------------------------------------------" + echo "git checkout release && git reset --hard origin/release" + echo "git branch -D ${NEW_RC_BRANCH}" + echo "git checkout --track origin/rc/${RC_BRANCH}" + echo "---------------------------------------------------------" +fi