Basics
There are several things to understand first:
- We have a rotating role called the release manager who is responsible for a number of things related to a routine release.
- The branch called
mainalways has the source for the most recent release that has been uploaded to the App Store. - The branch called
developis where changes are made as we work toward the next release. - When a code freeze goes into effect, we create a branch from
developcalledrelease/Major.Minor.Patchthat will be merged tomainwhen the release is ready to go. - If a hot-fix release is required, then we create a branch from
maincalledhotfix/Major.Minor.Patchthat will be merged tomainwhen the release is ready to go.
Routine Release
The anticipated release date can be found on the Figma Board.
The high level steps for making a routine release (not a hot-fix, basically) are as follows:
- Create
release/Major.Minor.Patchfromdevelop. A Jira epic for the release should already exist at this point. This is what we call the code freeze. - Create TestFlight builds from the release branch for QA purposes.
- If changes are required, create branches from
release/Major.Minor.Patchthat will then be merged back torelease/Major.Minor.Patch. Do not create branches fromdevelop, and do not merge PRs todevelop. - When the product team has signed off on the release, open a PR to merge
release/Major.Minor.Patchtomain. See below for more details. - After
release/Major.Minor.Patchis merged tomain, tag the merge commit onmainwith the version number. - Post release notes for approval.
- Open a PR to merge
mainback todevelop. This should include a change to increment the version number in*-Info.plistto reflect thatdevelopis for the next version of the app. See below for the full details.
Hot-fix Release
A hot-fix release is basically the same as a routine release except that the release branch will be created relative to main. Do not create the hot-fix release branch from develop. As a convention, we name the release branch for a hot-fix as hotfix/Major.Minor.Patch.
Depending on the circumstances, the changes for the hot-fix may go directly into the hotfix/Major.Minor.Patch branch, or they may go into branches created relative to that branch. It usually plays out one of two ways:
- The need for the hot-fix is urgent, and/or the number of issues to address is very small—usually one bug or two closely related bugs. The process can therefore be expedited by applying changes directly to the
hotfix/Major.Minor.Patchbranch. If there are more than two issues to address, this approach is not appropriate. - The hot-fix is planned in advance (often for rolling out a feature to a single customer), or there are multiple problems to address. There may still be an urgent need to complete the work, but cutting corners could cause problems due to there being greater complexity involved. In this case, branches should be made relative to the
hotfix/Major.Minor.Patchbranch with individual pull requests opened for review.
Either way, when the issues are fully addressed, the final version number would be applied as a commit to hotfix/Major.Minor.Patch. With the fixes and updated version number in place, a pull request would be opened to merge the hot-fix branch to main.
Ultimately, the handling of a hot-fix release is very much like a routine release but on a much shorter time frame. The instructions for finalizing a hot-fix release are the same as for finalizing a routine release. That information is provided below in the section titled “Finalizing a Release”.
Version-only Release
Once in a while, we have to make a new release where nothing changes but the version number. We try to avoid this because it is disruptive, but sometimes we simply must do this. The process feels tedious when the only thing changing is the version number, and it can feel like an eternity is passing waiting on the PR bots to finish. The steps for this are explained toward the end of this document.
Code Freeze
Code freeze dates are announced months in advance. The date is flexible and may have to change depending on various factors. If the code freeze date will change, an announcement will be made in Slack to inform the team.
The release/Major.Minor.Patch branch is typically create at 5:00 PM Central on the day of the code freeze. TestFlight builds from the qa-uat group should be made from that branch once it is created and pushed to GitHub. The TestFlight build creation is the same as what we do routinely throughout the month except that the branch used for building will be release/Major.Minor.Patch rather than develop.
The effort required to prepare for the code freeze varies from month to month. The best scenario is that there are no open PRs that need to be merged before the release branch can be created. The worst scenario is one in which one or more team members still have PRs to open before the release branch can be created. The team may have to be pinged two or three times during the day of the code freeze to be sure that nothing slips through the cracks.
The actual steps for creating the release branch are straightforward. If the next version of the app is 3.2.0, then the process looks like this:
git checkout develop
git pull
git checkout -b release/3.2.0
git push --set-upstream origin HEAD
An epic must be created in Jira to capture any work required to finalize the release. One example for how these look is the epic for the 2.33.0 release. Take note of the following:
- The epic name and the summary are “Release 2.33.0”
- The fix version is “Mobile 2.33”
The release epic should be seeded with any open Jira issues that were selected for development in the current release cycle. Ideally, there will be none. If there are any such open Jira issues, however, add them to the epic and ask the team for help in getting them finished.
Finalizing a Release
During the QA phase for a release, the product team will be pinged from time to time to get a sense of how they feel about the state of the app. This happens in the #product-mobile-release channel, and Dan Berry and/or Chris Hoekstra usually do this. The release manager should also communicate with the product team in that Slack channel, as described in the Release Manager Checklist. Once the product team has completed their testing and approved the release, the release manager should post in the #product-mobile-release channel to confirm that the release can be finalized. This confirmation will typically come from Dan.
NOTE: The process below is explained using the release/Major.Minor.Patch branch name, but the steps are the same for a hot-fix release.
Merging the Release Branch
First, set the official version number in the source tree. In order to do this you will need to request to be part of the iOS-administrators team. You can do this by going to this link, clicking on members and request to join. Joining the iOS-administrators team is only necessary for this step. For the purposes of the example, assume that the version number will be 3.2.0 (1020). The release branch, then, would be called release/3.2.0.
The “1020” part of the version number example given above is the build number. Choosing the final build number for a release is the last decision that must be made. The build number must always be incremented as part of finalizing the release:
git checkout release/3.2.0
git pull
cd Banno
./update-version 3.2.0 1020
git push origin HEAD
The steps for merging the work for version 3.2.0 to main are as follows:
- Open a PR to merge
release/3.2.0tomain. - Get two approvals.
- Merge the PR and delete
release/3.2.0. - Create a tag on
maincalledv3.2.0.
The tag steps look like this:
git checkout main
git pull
git tag v3.2.0
git push origin v3.2.0
Creating Release Notes
Now, it is time to generate the release notes. This happens using the grip-assets repository. After cloning the repository, it is not necessary to follow the steps in the README.md file. However, it is necessary to ensure that the necessary Ruby gems are installed so that generate_release_notes.rb can be used.
The recommended procedure is to use rbenv. Follow the installation steps in the mobile-deployment repository up to and including the installation of Bundler.
Once rbenv is installed and configured, the following command must be executed from the top-level folder of the grip-assets repository clone:
bundle install
The release notes are generated by a script called generate_release_notes.rb. It needs a GitHub personal access token (PAT) and an SSH key associated with your GitHub account in order to utilize the GitHub API. If the environment variable GITHUB_ACCESS_TOKEN is set, then the script will use it. If that environment variable is not set, then the script will prompt to set up a file called ~/.bub with the PAT. However, it is better to use the GITHUB_ACCESS_TOKEN environment variable.
For the purposes of the example, assume that the version to release is 3.2.0 and that the previous version was 3.1.0. There must be tags in the banno-ios repository named v3.1.0 and v3.2.0. Run the following in the root directory of the grip-assets repository clone:
git pull
git checkout -b ios_release_notes/3.2.0
./generate_release_notes.rb ios -p v3.1.0 -n v3.2.0
IMPORTANT: Choosing the previous version number to use can be tricky. For a routine release, use the previous routine release version number. Use the previous routine release version number even if the latest release was a hot-fix release. For example, if making 3.2.0 release and there is a 3.1.1 hot-fix release, the previous release number to use will still be 3.1.0 for a routine release. For a hot-fix release, use the previous release version number. For example, if making a 3.1.2 hot-fix release following up on 3.1.1, then the previous version number should be 3.1.1. If releasing 3.2.0, then the previous version number should be 3.1.0.
The script will generate three files:
release-notes/ios/3.1.0-3.2.0.changelog.txtrelease-notes/ios/recent_changes_3.2.0.txtrelease-notes/ios/release_notes_email.3.2.0.txt
Open release-notes/ios/release_notes_email.3.2.0.txt in a text editor and do the following:
- Scroll down to the placeholder text
INSERT RECENT CHANGES HEREand paste in the contents ofrelease-notes/ios/recent_changes_3.2.0.txtas a replacement for that text. - Scroll down to the bottom of the file and ensure that full names are shown for each contributing developer. The name of each person with at least one merged PR should be shown, but it depends on the state of their GitHub profile. If there are empty names or there are usernames instead of names, then it is necessary to replace those with the appropriate full names.
- Stage the three added files for commit and commit them.
- Push the branch to GitHub.
- Open a PR for the branch.
- Request reviews on the branch.
Finally, open an email client and send a message to approvers@banno.com:
To: approvers@banno.comReply-To: approvers@banno.comSubject: [For Approval] <first line from release-notes/ios/release_notes_email.3.2.0.txt>- Body: everything else from
release-notes/ios/release_notes_email.3.2.0.txt
NOTE: In most email clients adding a Reply-To email address requires a change of the sender’s account settings. For example, in Gmail you’ll need to go to quick settings->see all settings->Accounts, under the Send mail as: section select Add another email address, and finally select the Specify a different "reply-to" address.
It helps to keep things moving by posting a message to @approvers in the #org-mobile-deployment channel indicating that the release notes for the iOS app have been posted for approval.
NOTE: Approvals from the approvers group for the release notes do not have to come in prior to merging the release notes PR. Once your PR receives approvals from your team on GitHub, merge the release notes PR.
Merging Back to develop
The last step of making a release is to get all the changes from the QA period back into develop.
git checkout main
git pull
git checkout develop
git pull
git checkout -b merge_main_3.2.0
git merge main
If there are merge conflicts (and there often are), they must, of course, be fixed. Please be extremely careful in resolving any conflicts. Sometimes, a critical change will go into the release branch directly. The primary means for such a change to get back to develop and into a future release occurs at this stage. If there is uncertainty about how to resolve one or more conflicts, ask for help in the #team-ios Slack channel.
After the merge commit is in place on the merge_main_3.2.0 branch, the last step is to roll the version number. If the most recent release was 3.2.0 (1020), then we want to update develop to be 3.3.0 (1021):
cd Banno
./update-version 3.3.0 1021
git push --set-upstream origin HEAD
Open a PR for the merge_main_3.2.0 branch so that it can be reviewed the same as any other work.
IMPORTANT: A review must be requested from the @Banno/ios-administrators GitHub group. At least one member of that group must provide an approval.
NOTE: If a code freeze is currently in effect and there is an existing release branch, the back merge should be to the release branch instead of develop. The release branch will ideally be merged back only once as part of our normal release finalization process. This is done to keep our process as simple and consistent as possible in these rare occasions.
Version-only Release
Making a version-only release is similar to making a hot-fix release except that only the *-Info.plist files will be changed. For the purposes of this example, assume that we need to make a version-only release called 3.1.1 with build number 1013.
IMPORTANT: It is necessary to coordinate with the iOS team to determine what the build number should be. A quick rule of thumb is to increment the build number of the most recent TestFlight release from develop by 1.
git checkout main
git pull
git checkout -b hotfix/3.1.1
cd Banno
./update-version 3.1.1 1013
git push --set-upstream origin HEAD
Next, open a PR to merge hotfix/3.1.1 to main and get two approvals on it. Once the PR is merged, then do the following:
git checkout main
git pull
git tag v3.1.1
git push origin v3.1.1
At this point, release notes can be generated and posted for approval. See above for more information about that.
The final step is to open a PR to merge main back to develop. The process for this is the same as for any other release. This is recommended solely to avoid future merge conflicts when the next release/Major.Minor.Patch branch needs to be merged to main.