-
Notifications
You must be signed in to change notification settings - Fork 6
Release Process
The release process has two components:
- Things that can be done anywhere (cutting the branch, writing release notes, building binaries)
- Things that have to be done at Google (signing the binaries, deploying them to
dl.google.com
)
Most of the process is in the first category, and this doc only covers that category.
We have two kinds of releases:
- Feature releases: cut a new branch off of
master
, which contains all work up to this point. - Point release: patch a few small changes onto an existing branch.
- Stable release: re-release an existing beta release as stable.
For example:
- Release 1.9.32.1 was a feature release
- All later 1.9.x.x releases (1.9.31.2 through 1.9.32.14) were point releases.
- Release 1.9.32.3 was released as beta on 2015-01-05 and re-released as stable on 2015-01-14.
A feature release is generally a lot more work to get out, because we've made larger changes and it's more likely that something has broken that needs to be fixed before releasing. A point release, on the other hand, should be as small as possible to minimize the risk of breaking one thing while fixing another. Often this means we'll fix a bug two ways if the real fix involves a refactor: release a minimal fix for a point release, and put the larger refactor on master for the future.
Point releases are further broken down into "bugfix" and "security" releases. A bugfix release does exactly that: fixes bugs. We won't generally put one out unless there are serious bugs, but if there's a bug serious enough to be putting out a release then we'll generally backport fixes for less serious bugs to release along with it. Security releases are ones that people need to apply to avoid their site being exploited. Because we want people to apply these as quickly as possible, other fixes should go out in a separate bugfix release.
We release both beta and stable versions of mps and nps. Version x.x.x.x-beta and x.x.x.x-stable always have the same code; beta vs stable is just metadata to let sites know what they're likely to want to run. New feature releases start as beta, often have a few rounds of bugfix releases, have a few months of time for issues to crop up, and then once we have a version we think is solid we release the most recent point release as stable. For example, 1.9.32.1 was released as beta on 2014-09-16, then we made a security update to it on 2014-10-27 as 1.9.32.2 and a bug fix release on 2015-01-05 as 1.9.32.3, and then re-released 1.9.32.3 as stable on 2015-01-14.
For each feature release series we maintain a branch. The name (number) of the branch is the third component of the release version. For example, the 1.12.x.x series of releases is based on branch 34
, and the 1.10.x.x and 1.11.x.x series were based on branch 33
. When working on a release you work with the branch, and then when you have something ready to release you'll tag it.
cd .../mod_pagespeed
git checkout master
git checkout -b NN
git push --set-upstream origin NN
cd .../ngx_pagespeed
git checkout master
git checkout -b NN
git push --set-upstream origin NN
If the current most recent branch is 34
(1.12.x.x) then you'd make a new branch and call it 35
. Any changes you need to make to get this release ready should be committed to this branch.
Edit net/instaweb/public/VERSION to match the expected release version. For example, change:
MAJOR=1
MINOR=13
BUILD=0
PATCH=0
to:
MAJOR=1
MINOR=13
BUILD=35
PATCH=1
Then commit:
git commit -a -m "Update VERSION for release 1.13.35.1"
When building from development branches mod_pagespeed reports its version as x.x.x.x-REVISION
, where REVISION
is the number of commits we've made on the master branch. For a release branch, however, we want it to report x.x.x.x-0
:
git cherry-pick 2a4b2047
Builds from master always report with a minor version number one more than the current one, a branch number of 0, and a patch number of 0. For example, currently our most recent release is 1.12.34.2 so master builds report as 1.13.0.0. When you cut a feature release, update net/instaweb/public/VERSION
on master
to increment MINOR
and zero BUILD
and PATCH
.
If you're making a point release, say 1.13.35.7, then first check out the branch for that release (35
). Now you can cherry-pick
commits onto it. For example:
cd .../mod_pagespeed
git checkout 35
git cherry-pick COMMIT-HASH
git cherry-pick OTHER-COMMIT-HASH
git push
Then update net/instaweb/public/VERSION
to increment the patch number.
When re-releasing a beta release as stable we don't make any code changes, we just run the commands below with stable
instead of beta
.
Start a draft of the release notes early: they take a surprisingly long time to get right.
The goal is to list everything that has changed between releases that users might care about. For a patch release this is simple: list the bugs fixed and the commits applied. For a feature release it's a bit more work to get a picture of what changed:
- Look over bugs that have been marked fixed since the last release (both for nps and mps)
- Look over pull requests that have been closed since the last release (both for nps and mps)
- Don't look at the full diff between versions, because that's way too big, but look at diffs for files that often correspond to changes we should be noting:
apache/mod_instaweb.cc
system/system_rewrite_options.cc
rewriter/rewrite_filter_names.gperf
rewriter/rewrite_options.cc
- everything under
doc/
-
ngx_rewrite_options.cc
in ngx_pagespeed
- Also look over the open issues for mps and nps to find ones that are fixed but are still marked as open
Make edits to doc/release_notes.html
, and send out a pull request for review.
We normally build the following files for release on dl.google.com
:
- mod_pagespeed: 32bit rpm
- mod_pagespeed: 32bit deb
- mod_pagespeed: 64bit rpm
- mod_pagespeed: 64bit deb
- mod_pagespeed: source tarball
- psol: 32 bit headers+binary tarball
- psol: 64 bit headers+binary tarball
We build these on GCE instances
Note: if you're internal to google you already have the cloud sdk and a gcloud project; see the internal release supplement doc.
Install the cloud sdk for talking to GCE (https://cloud.google.com/sdk/) and create a gcloud project to do the builds under.
PATH=/path/to/cloud-sdk
CLOUDSDK_COMPUTE_ZONE=us-central1-a
BRANCH=36 # can't use a tag because CentOS git is too old to understand tags in "git clone -b BRANCH"
gcloud config set project [gcloud project name]
gcloud auth login
git checkout $BRANCH
# For beta releases, omit --stable
install/build_on_vm.sh --build_branch=$BRANCH --centos -- --stable
install/build_on_vm.sh --build_branch=$BRANCH --centos -- --32bit --stable
install/build_on_vm.sh --build_branch=$BRANCH -- --skip_psol --stable
install/build_on_vm.sh --build_branch=$BRANCH -- --32bit --skip_psol --stable
build_on_vm.sh
will spinup a vm, clone $BRANCH
, build and test it and then (if successful) drop the final objects in ~/release/$RELEASE
.
This is what the OpenSUSE maintainer builds from, and potentially other distributions might use this as well.
First check out the branch you're working on:
git checkout NN
Then run:
devel/build_release_tarball.sh <beta|stable>
This will install deps, build a tarball, check that it compiles, and run tests on it. It puts the tarball in ~/release/VERSION/
.
[note: this is written assuming https://github.com/we-amp/mod_pagespeed/pull/1474 lands without interface changes]
At this point, your ~/release/VERSION
should contain:
- OS packages:
mod-pagespeed-[beta|stable]-VERSION-0.i386.rpm
mod-pagespeed-[beta|stable]-VERSION-0.x86_64.rpm
mod-pagespeed-[beta|stable]_VERSION-r0_amd64.deb
mod-pagespeed-[beta|stable]_VERSION-r0_i386.deb
- PSOL binary tarballs: * *
- Source tarball:
mod-pagespeed-[beta|stable]-VERSION-r0.tar.bz2
Point releases should only contain changes small enough that they shouldn't be performance relevant, and so can generally skip load tests. If you're doing a feature release, though, you definitely need to run load tests.
We have two kinds of load tests: one that tries to run PageSpeed in full, like in real usage, and another test that runs a series of microbenchmarks. We call these the "load test" and the "siege tests" though really they're all load tests.
The goal of load testing is to make sure our performance doesn't go down over time as we add features and things get more complex. Because machines vary over time, to get an apples-to-apples comparison we run load tests for the previous release and the current release.
First we need to get copies of the two .so
files to compare: the currently released beta version and the version you're preparing to release. These are in the .deb
files, so we need to get those first:
- For the most recent beta, download
https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-beta_current_amd64.deb
- For your current release: this should be
~/release/VERSION/mod-pagespeed-beta_VERSION-r0_amd64.deb
Now we can use devel/extract_so_from_deb.sh
to pull the apache 2.2 and 2.4 .so files out:
$ ls
mod-pagespeed-beta_VERSION-r0_amd64.deb
mod-pagespeed-beta_current_amd64.deb
$ .../net/instaweb/scripts/extract_so_from_deb.sh mod-pagespeed-beta_VERSION-r0_amd64.deb
The .so files are:
/tmp/tmp.AbrjbobkzA/mod_pagespeed.so
/tmp/tmp.AbrjbobkzA/mod_pagespeed_ap24.so
$ cp /tmp/tmp.AbrjbobkzA/mod_pagespeed.so VERSION-mod_pagespeed.so
$ cp /tmp/tmp.AbrjbobkzA/mod_pagespeed_ap24.so VERSION-mod_pagespeed_ap24.so
... repeat for the other deb ...
$ ls .*.so
VERSION-mod_pagespeed_ap24.so
VERSION-mod_pagespeed.so
CURRENT-mod_pagespeed_ap24.so
CURRENT-mod_pagespeed.so
The traditional load test needs a corpus. There's one that Google uses internally that can't be open sourced for IP reasons, but as of 2017-01-11 Maks is writing an open-source corpus generator: https://github.com/we-amp/mod_pagespeed/pull/1473
For now I'll assume you have a corpus in /path/to/corpus
This load test selects pages and resources from the corpus and loads them in a random order. Best not to do anything else with your machine at the same time, to get more reproducible results. To start it run:
devel/mps_load_test.sh -custom_so /path/to/so_to_test /path/to/corpus
At the end it prints out the queries-per-second, a histogram of response codes, and greps the Apache error_log for "exit signal". The presence of such text should be investigated. Absence of such makes us happy.
To get comparisons across versions you'll need to make a pair of config files that should give similar behavior. For example, if we added a new feature that's optional and slow, we should make sure that we're not load testing with that feature on.
Run the load test with both the new version and the old version, and send the QPS numbers to [email protected]. If there's a major regression, figure out what it is, bisecting if necessary. With 1.10 we saw a qps decrease that, on bisecting, turned out to be us removing an extra layer of caching from our slurp, which was a load-test specific change. (And then by the time we cut the final version we had merged some last-minute changes with large QPS improvements.)
Please load-test using multiple Apache version & MPMs. These can all be built using install/build_development_apache.sh
, which builds a new ~/apache2
with the version you specify. For example:
install/build_development_apache.sh 2.2 prefork
[run load tests for both new and old versions]
install/build_development_apache.sh 2.2 worker
[run ...]
install/build_development_apache.sh 2.4 event
We need to resolve crashes before releasing. Rare shutdown crashes might be ok in some cases, since the way we run arbitrary duration background optimization tasks isn't a good fit for graceful restarts, but if you run into anything like this make sure everyone else on pagespeed-dev@ is ok with you continuing.
You really need to stop and consider that the release might be broken performance-wise. It is pretty important that we don't ruin performance in the pursuit of features!
To run the siege load tests, just do devel/siege/siege_all.sh
[TODO: doc how to run this with custom .so
s.]
If the tests results look good, tag the mod_pagespeed release: For 1.13.35.1 I ran:
git tag -a "v1.13.35.1" -m "Release 1.13.35.1"
git push origin v1.13.35.1
Follow https://github.com/we-amp/ngx_pagespeed/wiki/creating-a-release but don't tag latest-beta
until we're ready to go live.
When we release all our recent work moves from UNRELEASED
to a specific version. So cd into the html/
directory and run:
RELEASE=a.b.c.d
sed -i -e "s/\<UNRELEASED\>/$RELEASE/" $(grep -rwl UNRELEASED .)
and send it out for review.
We need to tar up the examples directory to copy up to modpagespeed.com:
cd mod_pagespeed/install
tar -czf mod_pagespeed_examples.tar.gz mod_pagespeed_example/
First, install doxygen:
sudo apt-get install doxygen
Build the documentation from an open-source client synced to the same revision as the released code (for branch 34, you will need to copy the devel/ directory from master):
cd devel
make doxygen
This creates psol_doc.tar.gz in the git root. Copy that to modpagespeed.com
and install it:
scp psol_doc.tar.gz [email protected]:
ssh [email protected]
cd /var/www/html
mkdir psol-$RELEASE
cd psol-$RELEASE
tar xzf ~/psol_doc.tar.gz
chmod -R a+rX .
cd ..
ln -Tsf psol-$RELEASE/html psol
Verify that your new version is visible on the internet, by browsing to http://modpagespeed.com/psol/. Check the version at the top.
Before asking google to make things live, make sure:
- the release notes are approved and ready to be deployed
- the documentation changes are ready to go in
- the announcement emails are drafted
- the mps examples tarball is ready to deploy
Now people at google need to follow the google-internal release docs to:
- sign binaries
- put binaries on
dl.google.com
- stage the linux repos
- they won't deploy the changes until it's time to announce
- tell google to deploy the linux repo changes
- update modpagespeed.com and ngxpagespeed.com to the new version
- submit the release notes and documentation pull requests, and deploy them to modpagespeed.com
- deploy the examples tarball to modpagespeed.com and ngxpagespeed.com following our doc
- send out the announcement emails to mod-pagespeed-announce and ngx-pagespeed-announce, ccing mod-pagespeed-discuss and ngx-pagespeed-discuss
- retag
latest-[beta|stable]
for both mod_pagespeed and ngx_pagespeed - update https://github.com/we-amp/mod_pagespeed/issues/968 with a new source tarball link