blob: 410e728ce4a17f25a1f8e0f4a4d5a0496423efa3 [file] [log] [blame] [view]
# Bazel Release Playbook
This is the guide to conducting a Bazel release. This is especially relevant for
release managers, but will be of interest to anyone who is curious about the
release process.
## Preface
> For future reference and release managers - the release manager playbook should
> be treated like an IKEA manual. That means: Do not try to be smart, optimize /
> skip / reorder steps, otherwise chaos will ensue. Just follow it and the end
> result will be.. well, a usable piece of furniture, or a Bazel release
> (depending on the manual).
>
> Like aviation and workplace safety regulations, the playbook is written in the
> tears and blood of broken Bazelisks, pipelines, releases and Git branches.
> Assume that every step is exactly there for a reason, even if it might not be
> obvious. If you follow them to the letter, they are not error prone. Errors
> have only happened in the past, when a release manager thought it's ok to
> follow them by spirit instead. ;)
>
> -- @philwo
## Setup
Do this once.
* Make sure you are a member of the Bazel [release-managers](https://buildkite.com/organizations/bazel-trusted/teams/release-managers/members)
group. If that link does not work for you, ask one of the Buildkite org admins to add you to
the group.
* Set up github ssh key if you haven't already.
* https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
Do these steps once per release.
* Find baseline commit and cherrypicks
* Check Bazel nightly build at
https://buildkite.com/bazel/bazel-with-downstream-projects-bazel. If
many downstream jobs are failing then this is not a good baseline
commit. If only a few downstream jobs are failing and the issues are
known then this is a good baseline commit. Fixes for the known issues
should be cherry-picked, any remaining issues should become release
blockers.
* Begin the [internal release process](http://go/bazel-internal-launch-checklist), too.
## Release issue
Each release has a tracking bug (see the
[list](https://github.com/bazelbuild/bazel/issues?utf8=%E2%9C%93&q=label%3Arelease+)).
The last and the next releases should be pinned. The bug includes a "Target RC
date". On that day, create a new release candidate.
A milestone should also be [created](https://github.com/bazelbuild/bazel/milestones/new)
for the release to keep track of any release blocking issues. ([Example](https://github.com/bazelbuild/bazel/milestone/31))
The release manager adds a comment to the issue with the following content:
```
# Status of Bazel X.Y
- Target baseline: [date]
- Expected release date: [date]
- [List of release blockers](link-to-milestone)
To report a release-blocking bug, please add it to the release blocker milestone above, and cc me.
Task list:
- [ ] Pick release baseline:
- [ ] Create release candidate:
- [ ] Check downstream projects:
- [ ] [Create draft release announcement](https://docs.google.com/document/d/1wDvulLlj4NAlPZamdlEVFORks3YXJonCjyuQMUQEmB0/edit)
- [ ] Send for review the release announcement PR:
- [ ] Push the release, notify package maintainers:
- [ ] Update the documentation
- [ ] Push the blog post
- [ ] Update the [release page](https://github.com/bazelbuild/bazel/releases/)
```
Keep the task list updated and check boxes as you follow the release process. [Example](https://github.com/bazelbuild/bazel/issues/7816#issuecomment-497037232).
## Create a Candidate
Create candidates with the `release.sh` script. See above how to pick a good baseline commit.
* If it's the first candidate for this version, run:
```bash
RELEASE_NUMBER=<CURRENT RELEASE NUMBER x.yy.z>
BASELINE_COMMIT=01234567890abcdef # From the Setup phase
git clone https://github.com/bazelbuild/bazel.git ~/bazel-release-$RELEASE_NUMBER
cd ~/bazel-release-$RELEASE_NUMBER
scripts/release/release.sh create $RELEASE_NUMBER $BASELINE_COMMIT [CHERRY_PICKS...]
```
Note that the three-digit version is important: "0.19.0". not "0.19".
* For cherry-picks, you need `--force_rc=N` where `N` is the number of the
release candidate of `$RELEASE_NUMBER`. For example, the first time you do a
cherry-pick (after the initial candidate), N will be 2.
```bash
scripts/release/release.sh create --force_rc=2 $RELEASE_NUMBER $BASELINE_COMMIT [CHERRY_PICKS...]
```
* If you already did some cherry-picks and you want to add more, use "git log"
to find the latest commit (this corresponds to the last cherry-pick commit).
Use that as the new baseline and list the new cherry-picks to add on top. Or
simply re-use the same baseline and cherrypicks from the previous candidate,
and add the new cherrypicks.
```bash
scripts/release/release.sh create --force_rc=3 $RELEASE_NUMBER NEW_BASELINE_COMMIT [NEW_CHERRY_PICKS...]
```
Resolve conflicts if there are any, type `exit` when you are done, then the script will continue.
WARNING: `release.sh create` handles conflicts in a subshell (which is why you need to type `exit`).
Editing the release notes is not needed (it will be done later).
## Push the candidate
1. Run `release.sh push`. This uploads the candidate and starts the release
process on BuildKite.
```bash
scripts/release/release.sh push
```
1. Update GitHub issue with the command that was run and the new candidate name
(ie, 0.19.1rc3). Update the issue with the estimated release date, assuming no
regression is found.
1. Check BuildKite results at https://buildkite.com/bazel-trusted/bazel-release. You should
see the `release-$RELEASE_NUMBER` branch here and a new build running for
your release.
1. Check the postsubmit test run for the release branch to ensure that all
tests on all platforms pass with the version you're about to release.
* Go to https://buildkite.com/bazel/bazel-bazel and find the
`release-$RELEASE_NUMBER` branch in the list. A build should
automatically run. Make sure that it passes.
1. When it all looks good, go back to the job in the
[release pipeline](https://buildkite.com/bazel-trusted/bazel-release/builds),
click "Deploy release artifacts" for the deployment step.
* This will upload the release candidate binaries to GitHub and our
apt-get repository. The github link is probably of the form:
https://releases.bazel.build/3.6.0/rc1/index.html
1. If that worked, click on the "Generate announcement mail text" step to unblock it.
If it's the first release candidate, prepare the release announcement (see
next section).
1. Copy & paste the generated text into a new e-mail and send it. If you're
creating a new release candidate, reply to the previous e-mail to keep all
the information in one thread.
* The first line is the recipient address.
* The second line is the subject.
* The rest is the body of the message.
* Replace the generated notes with a link to the release announcement draft.
`https://docs.google.com/document/d/1wDvulLlj4NAlPZamdlEVFORks3YXJonCjyuQMUQEmB0/view`
1. Trigger a new pipeline in BuildKite to test the release candidate with all the downstream projects.
* Go to https://buildkite.com/bazel/bazel-with-downstream-projects-bazel
* Click "New Build", then fill in the fields like this:
* Message: Test Release-3.0.0rc2 (Or any message you like)
* Commit: HEAD
* Branch: release-3.0.0rc2
1. Look for failing projects in red.
* Compare the results with the latest Bazel release:
* Jobs built with the latest Bazel:
https://buildkite.com/bazel?team=bazel
* Jobs built with release candidate: e.g.
https://buildkite.com/bazel/bazel-with-downstream-projects-bazel/builds/287
If a project is failing with release candidate but not with the latest
Bazel release, then there's probably a regression in the candidate. Ask
the Bazel sheriff if the problem is already noticed. If not, find out
the culprit, file an issue at
https://github.com/bazelbuild/bazel/issues and mark it as release
blocker.
If a project is failing with both release candidate and the latest Bazel
release, it could be a breakage from the project itself. Go through the
build history (eg.
[TensorFlow_serving](https://buildkite.com/bazel/tensorflow-serving/builds?page=2))
to confirm this, then file an issue to their owners.
* File bugs (**TODO: how to find the owner/project link?**)
1. Once issues are fixed, create a new candidate with the relevant cherry-picks.
## Google-internal launch review
Once the first candidate is available:
1. Follow the steps in [go/bazel-internal-launch-checklist](http://goto.google.com/bazel-internal-launch-checklist) to kick-off Google's internal launch review process.
## Release announcement
The release manager is responsible for the [draft release
announcement](https://docs.google.com/document/d/1wDvulLlj4NAlPZamdlEVFORks3YXJonCjyuQMUQEmB0/edit).
Once the first candidate is available:
1. Open the doc, create a new section with your release number, add a link to
the GitHub issue.
1. Copy & paste the generated text from the "Generate Announcement" step.
1. Reorganize the notes per category (C++, Java, etc.).
1. For each category, add a comment and assign it to the corresponding
[team contact](https://www.bazel.build/maintainers-guide.html#team-labels):
"+person for review (see guidelines at the top of the doc)".
1. Send an email to [bazel-dev](https://groups.google.com/forum/#!forum/bazel-dev) for
additional reviews.
1. Assign a comment to "+[aiuto@google.com](mailto:aiuto@google.com)"
and "+[daroberts@google.com](mailto:daroberts@google.com)"
for a global review.
After a few days of iteration:
1. Make sure all comments have been resolved, and the text follows the
guidelines (see "How to review the notes?" in the document).
1. Send a pull request to [bazel-blog](https://github.com/bazelbuild/bazel-blog/).
## Release requirements
1. The release announcement must be ready (the pull request has been reviewed).
1. Verify that the [conditions outlined in our policy](https://bazel.build/support.html#policy) **all apply**. As of
May 2019 those were the following, but _double check_ that they have not changed since then.
1. at least **1 week passed since you pushed RC1**, and
1. at least **2 business days passed since you pushed the last RC**, and
1. there are **no open ["Release blocking" Bazel bugs](https://github.com/bazelbuild/bazel/labels/Release%20blocker)** on GitHub.
## Push a release
1. Generate a new identifier: https://bazel.googlesource.com/new-password (and paste the code in your shell).
This is only necessary the first time you handle a release.
1. **Push the final release (do not cancel midway)**:
```bash
scripts/release/release.sh release
```
**Warning**: If this process is interrupted for any reason, please check the following before running:
* Both `release-x.x.xrcN` and `master` branch are restored to the previous clean state (without addtional release commits).
* Release tag is deleted locally (`git tag -d x.x.x`), otherwise rerun will cause an error that complains the tag already exists.
1. A CI job is uploading the release artifacts to GitHub. Look for the release
workflow on https://buildkite.com/bazel-trusted/bazel-release/. Unblock the steps.
1. Ensure all binaries were uploaded to GitHub properly.
1. **Why?** Sometimes binaries are uploaded incorrectly.
1. **How?** Go to the [GH releases page](https://github.com/bazelbuild/bazel/releases),
click "Edit", see if there's a red warning sign next to any binary. You
need to manually upload those; get them from
`https://storage.googleapis.com/bazel/$RELEASE_NUMBER/release/index.html`.
1. Update the release bug:
1. State the fact that you pushed the release
1. Ask the package maintainers to update the package definitions:
[@vbatts](https://github.com/vbatts) [@petemounce](https://github.com/petemounce) [@excitoon](https://github.com/excitoon)
1. Example: [https://github.com/bazelbuild/bazel/issues/3773#issuecomment-352692144]
1. Publish versioned documentation
1. Fetch the git tag for the release: `git fetch --tags`
1. Do a checkout to that tag: `git checkout $RELEASE_NUMBER`
1. You should see this message (e.g. for 0.21.0):
```
$ git checkout 0.21.0
Note: checking out '0.21.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at defd737761 Release 0.21.0 (2018-12-19)
```
1. [Install `gsutil`](https://cloud.google.com/storage/docs/gsutil_install)
and ensure you have access to the `bazel-public` GCP project.
1. Run `scripts/docs/generate_versioned_docs.sh`. If you get interrupted,
it is safe to re-run the script. This script will build the web assets
for the documentation, generate a tarball from them, and push the
tarball to Google Cloud Storage.
* The script will fail to run if you're not in a git checkout of a
release.
* If the tarball has already been pushed to GCS, this script will not
overwrite the existing tarball.
1. Update `site/_config.yml` and `scripts/docs/doc_versions.bzl` with `$RELEASE_NUMBER`.
1. `site/_config.yml`: set `version:` to `$RELEASE_NUMBER` and add `$RELEASE_NUMBER` to `doc_versions:`.
1. `scripts/docs/doc_versions.bzl`: add the following list item to `DOC_VERSIONS`
<pre>
{
"version": "<i>$RELEASE_NUMBER</i>",
"sha256": "<i>result of `sha256sum bazel-bin/site/jekyll-tree.tar`</i>",
},
</pre>
1. After the changes are submitted, it will take 30 mins-1 hour for them to show up on bazel.build.
1. Merge the blog post pull request.
1. Make sure you update the date in your post (and the path) to reflect when
it is actually published.
1. **Note:** The blog sometimes takes time to update the homepage, so use
the full path to your post to check that it is live.
1. Update the [release page](https://github.com/bazelbuild/bazel/releases/) to
replace the generated notes with a link to the blog post.
1. Close the release-tracking bug. If you need to do a patch release, create a
new tracking bug.
### Updating Google's internal mirror
Please ping @philwo and @meteorcloudy to copy the release binary to their
internal mirror.
### Updating the Homebrew recipe
[Homebrew](http://brew.sh/index.html) is a package manager for OS X. This
section assumes that you are on a Mac OS machine with homebrew installed.
To update the `bazel` recipe on Homebrew, you can send a pull request to
https://github.com/Homebrew/homebrew-core/blob/master/Formula/bazel.rb.
Example: https://github.com/Homebrew/homebrew-core/pull/57966
However, usually the Homebrew community takes care of this reasonably
quickly, so feel free to skip this step, if you aren't familiar with it.
### Updating the Chocolatey package
As of November 2016, this is done by an external contributor,
[@petemounce](https://github.com/petemounce) on GitHub. Ping him when there's a
new release coming out.
### Updating the Scoop pakage
As of February 2019, this is done by an external contributor,
[@excitoon](https://github.com/excitoon) on GitHub. [Ping him](http://telegram.me/excitoon) when there's a
new release coming out.
### Updating the Fedora package
This is done by an external contributor, [@vbatts](https://github.com/vbatts) on
GitHub. Ping him when there's a new release coming out.