diff --git a/Makefile b/Makefile index 01cf8912..de9c56d2 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ assets: release: @echo ">> building release binaries" - @RELEASE=true ./build/build.sh + @./build/release.sh docker: @docker build -t cadvisor:$(shell git rev-parse --short HEAD) -f deploy/Dockerfile . diff --git a/build/build.sh b/build/build.sh index 7263bc74..e01c7fce 100755 --- a/build/build.sh +++ b/build/build.sh @@ -16,40 +16,19 @@ set -e -RELEASE=${RELEASE:-false} # Whether to build for an official release. GO_FLAGS=${GO_FLAGS:-} # Extra go flags to use in the build. +GO_CMD=${GO_CMD:-"install"} +BUILD_USER=${BUILD_USER:-"${USER}@${HOSTNAME}"} +BUILD_DATE=${BUILD_DATE:-$( date +%Y%m%d-%H:%M:%S )} +VERBOSE=${VERBOSE:-} repo_path="github.com/google/cadvisor" version=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' ) revision=$( git rev-parse --short HEAD 2> /dev/null || echo 'unknown' ) branch=$( git rev-parse --abbrev-ref HEAD 2> /dev/null || echo 'unknown' ) -build_user="${USER}@${HOSTNAME}" -build_date=$( date +%Y%m%d-%H:%M:%S ) go_version=$( go version | sed -e 's/^[^0-9.]*\([0-9.]*\).*/\1/' ) -GO_CMD="install" - -if [ "$RELEASE" == "true" ]; then - # Only allow releases of tagged versions. - TAGGED='^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)[0-9]*)?$' - if [[ ! "$version" =~ $TAGGED ]]; then - echo "Error: Only tagged versions are allowed for releases" >&2 - echo "Found: $version" >&2 - exit 1 - fi - - # Don't include hostname with release builds - if ! build_user="$(git config --get user.email)"; then - echo "Error: git user not set, use:" - echo "git config user.email " - exit 1 - fi - build_date=$( date +%Y%m%d ) # Release date is only to day-granularity - - # Don't use cached build objects for releases. - GO_CMD="build" -fi # go 1.4 requires ldflags format to be "-X key value", not "-X key=value" ldseparator="=" @@ -62,14 +41,14 @@ ldflags=" -X ${repo_path}/version.Version${ldseparator}${version} -X ${repo_path}/version.Revision${ldseparator}${revision} -X ${repo_path}/version.Branch${ldseparator}${branch} - -X ${repo_path}/version.BuildUser${ldseparator}${build_user} - -X ${repo_path}/version.BuildDate${ldseparator}${build_date} + -X ${repo_path}/version.BuildUser${ldseparator}${BUILD_USER} + -X ${repo_path}/version.BuildDate${ldseparator}${BUILD_DATE} -X ${repo_path}/version.GoVersion${ldseparator}${go_version}" echo ">> building cadvisor" -if [ "$RELEASE" == "true" ]; then - echo "Building release candidate with -ldflags $ldflags" +if [ -n "$VERBOSE" ]; then + echo "Building with -ldflags $ldflags" fi GOBIN=$PWD go "$GO_CMD" ${GO_FLAGS} -ldflags "${ldflags}" "${repo_path}" diff --git a/build/release.sh b/build/release.sh new file mode 100755 index 00000000..fba1527a --- /dev/null +++ b/build/release.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Copyright 2015 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +VERSION=$( git describe --tags --dirty --abbrev=14 | sed -E 's/-([0-9]+)-g/.\1+/' ) +# Only allow releases of tagged versions. +TAGGED='^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)[0-9]*)?$' +if [[ ! "$VERSION" =~ $TAGGED ]]; then + echo "Error: Only tagged versions are allowed for releases" >&2 + echo "Found: $VERSION" >&2 + exit 1 +fi + +# Don't include hostname with release builds +if ! git_user="$(git config --get user.email)"; then + echo "Error: git user not set, use:" + echo "git config user.email " + exit 1 +fi + +# Build the release. +export BUILD_USER="$git_user" +export BUILD_DATE=$( date +%Y%m%d ) # Release date is only to day-granularity +export GO_CMD="build" # Don't use cached build objects for releases. +export VERBOSE=true +build/build.sh + +# Build the docker image +echo ">> building cadvisor docker image" +docker_tag="google/cadvisor:$VERSION" +gcr_tag="gcr.io/google_containers/cadvisor:$VERSION" +docker build -t $docker_tag -t $gcr_tag -f deploy/Dockerfile . + +echo +echo "Release info:" +echo "VERSION=$VERSION" +sha1sum --tag cadvisor +md5sum --tag cadvisor +echo "docker image: $docker_tag" +echo "gcr.io image: $gcr_tag" + +exit 0 diff --git a/docs/development/releasing.md b/docs/development/releasing.md index 40dc4d8f..29d9e558 100644 --- a/docs/development/releasing.md +++ b/docs/development/releasing.md @@ -1,3 +1,101 @@ # cAdvisor Release Instructions -See https://docs.google.com/a/google.com/document/d/102wNLDR9ls5NGRpBIfhQaD53q97DVLfmmuILLUE4AIk (Google internal-only) +Google internal-only version: [cAdvisor Release Instructions](http://go/cadvisor-release-instructions) + +## 1. Send Release PR + +Example: https://github.com/google/cadvisor/pull/1281 + +Add release notes to [CHANGELOG.md](../../CHANGELOG.md) + +- Tip: Use a github PR search to find changes since the last release + `is:pr is:merged merged:>2016-04-21` + +## 2. Create the release tag + +### 2.a Create the release branch (only for major/minor releases) + +Skip this step for patch releases. + +``` +# Sync to HEAD, or the commit to branch at +$ git fetch upstream && git checkout upstream/master +# Create the branch +$ git branch release-v0.XX +# Push it to upstream +$ git push git@github.com:google/cadvisor.git release-v0.XX +``` + +### 2.b Tag the release + +For a release of minor version XX, patch version YY: + +``` +# Checkout the release branch +$ git fetch upstream && git checkout upstream/release-v0.XX +# Tag the release commit. If you aren't signing, ommit the -s +$ git tag -s -a v0.XX.YY +# Push it to upstream +$ git push git@github.com:google/cadvisor.git v0.XX.YY +``` + +## 3. Build release binary + +Command: `make release` + +- Make sure your git client is synced to the release cut point +- Try to build it from the release branch, since we include that in the binary version +- Verify the ldflags output, in particular check the Version, BuildUser, and GoVersion are expected + +Once the build is complete, check the VERSION and note the sha1 and md5 hashes. + +## 4. Push the Docker images + +Docker Hub: +``` +$ docker login +Username: **** +Password: **** +$ docker push google/cadvisor:$VERSION +$ docker logout # Good practice with shared account +``` + +Google Container Registry: + +``` +$ gcloud auth login +... +Go to the following link in your browser: + + https://accounts.google.com/o/oauth2/auth? + +Enter verification code: **** +$ gcloud docker push gcr.io/google_containers/cadvisor:$VERSION +$ gcloud auth revoke # Log out of shared account +``` + +## 5. Cut the release + +Go to https://github.com/google/cadvisor/releases and click "Draft a new release" + +- "Tag version" and "Release title" should be preceded by 'v' and then the version. Select the tag pushed in step 2.b +- Copy an old release as a template (e.g. github.com/google/cadvisor/releases/tag/v0.23.1) +- Body should start with release notes (from CHANGELOG.md) +- Next is the Docker image: `google/cadvisor:$VERSION` +- Next are the binary hashes (from step 3) +- Upload the binary build in step 3 +- If this is an alpha or beta release, mark the release as a "pre-release" +- Click publish when done + +## 6. Finalize the release + +Once you are satisfied with the release quality (consider waiting a week for bug reports to come in), it is time to promote the release to *latest* + +1. Edit the github release a final time, and uncheck the "Pre-release" checkbox +2. Tag the docker & gcr.io releases with the latest version + ``` + $ docker pull google/cadvisor:$VERSION + $ docker tag -f google/cadvisor:$VERSION google/cadvisor:latest + $ docker tag -f google/cadvisor:$VERSION gcr.io/google_containers/cadvisor:latest + ``` +3. Repeat steps 4.a and 4.b to push the image tagged with latest