blob: 8bcaf693b4bd541121977053462015c190db5b4f [file] [log] [blame]
Philipp Wollermanna5afe952016-06-21 14:58:09 +00001#!/bin/bash
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +00002
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00003# Copyright 2015 The Bazel Authors. All rights reserved.
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
Philipp Wollermanna5afe952016-06-21 14:58:09 +000017set -eu
18
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000019# Main deploy functions for the continous build system
20# Just source this file and use the various method:
21# bazel_build build bazel and run all its test
22# bazel_release use the artifact generated by bazel_build and push
23# them to github for a release and to GCS for a release candidate.
24# Also prepare an email for announcing the release.
25
26# Load common.sh
27SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
Damien Martin-Guillereze4ead962015-08-17 15:21:50 +000028source $(dirname ${SCRIPT_DIR})/release/common.sh
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000029
Kristina Chodorow2b1763a2015-09-01 09:15:54 +000030: ${GIT_REPOSITORY_URL:=https://github.com/bazelbuild/bazel}
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000031
32: ${GCS_BASE_URL:=https://storage.googleapis.com}
33: ${GCS_BUCKET:=bucket-o-bazel}
Yun Peng70b29f42016-05-24 18:04:37 +000034: ${GCS_APT_BUCKET:=bazel-apt}
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000035
36: ${EMAIL_TEMPLATE_RC:=${SCRIPT_DIR}/rc_email.txt}
37: ${EMAIL_TEMPLATE_RELEASE:=${SCRIPT_DIR}/release_email.txt}
38
39: ${RELEASE_CANDIDATE_URL:="${GCS_BASE_URL}/${GCS_BUCKET}/%release_name%/rc%rc%/index.html"}
40: ${RELEASE_URL="${GIT_REPOSITORY_URL}/releases/tag/%release_name%"}
41
Klaus Aehlig736c46d2016-11-10 16:09:34 +000042: ${BOOTSTRAP_BAZEL:=bazel}
43
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000044PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"
Klaus Aehlig1ad08ba2017-01-19 16:15:53 +000045if [[ ${PLATFORM} == "darwin" ]] || [[ ${PLATFORM} == "freebsd" ]] ; then
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000046 function checksum() {
Damien Martin-Guillerezc375ea12015-09-10 09:58:44 +000047 (cd "$(dirname "$1")" && shasum -a 256 "$(basename "$1")")
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000048 }
49else
50 function checksum() {
Damien Martin-Guillerezc375ea12015-09-10 09:58:44 +000051 (cd "$(dirname "$1")" && sha256sum "$(basename "$1")")
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000052 }
53fi
54
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +000055# Returns the full release name in the form NAME(rcRC)?
56function get_full_release_name() {
57 local rc=$(get_release_candidate)
58 local name=$(get_release_name)
59 if [ -n "${rc}" ]; then
60 echo "${name}rc${rc}"
61 else
62 echo "${name}"
63 fi
64}
65
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000066function setup_android_repositories() {
67 if [ ! -f WORKSPACE.bak ] && [ -n "${ANDROID_SDK_PATH-}" ]; then
68 cp WORKSPACE WORKSPACE.bak
69 trap '[ -f WORKSPACE.bak ] && rm WORKSPACE && mv WORKSPACE.bak WORKSPACE' \
70 EXIT
Philipp Wollermann9d9657b2016-08-19 10:45:28 +000071 # Make sure that WORKSPACE ends with a newline, otherwise we'll end up with
72 # a syntax error.
73 echo >>WORKSPACE
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000074 cat >>WORKSPACE <<EOF
Lukacs Berki4e21d902015-09-07 09:59:50 +000075android_sdk_repository(
76 name = "androidsdk",
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000077 path = "${ANDROID_SDK_PATH}",
Lukacs Berki4e21d902015-09-07 09:59:50 +000078 build_tools_version = "${ANDROID_SDK_BUILD_TOOLS_VERSION:-22.0.1}",
79 api_level = ${ANDROID_SDK_API_LEVEL:-21},
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000080)
81
82bind(
83 name = "android_sdk_for_testing",
Lukacs Berki4e21d902015-09-07 09:59:50 +000084 actual = "@androidsdk//:files",
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000085)
86EOF
87 if [ -n "${ANDROID_NDK_PATH-}" ]; then
88 cat >>WORKSPACE <<EOF
Lukacs Berki4e21d902015-09-07 09:59:50 +000089android_ndk_repository(
90 name = "androidndk",
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000091 path = "${ANDROID_NDK_PATH}",
Lukacs Berki4e21d902015-09-07 09:59:50 +000092 api_level = ${ANDROID_NDK_API_LEVEL:-21},
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000093)
94
95bind(
96 name = "android_ndk_for_testing",
Lukacs Berki4e21d902015-09-07 09:59:50 +000097 actual = "@androidndk//:files",
Damien Martin-Guillerezdbf5cad2015-09-04 12:46:23 +000098)
99EOF
100 fi
101 fi
102}
Damien Martin-Guillerez9c5deb62015-09-15 07:38:26 +0000103
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000104# Main entry point for building bazel.
105# It sets the embed label to the release name if any, calls the whole
106# test suite, compile the various packages, then copy the artifacts
107# to the folder in $1
108function bazel_build() {
109 local release_label="$(get_full_release_name)"
110 local embed_label_opts=
Damien Martin-Guillerez9c5deb62015-09-15 07:38:26 +0000111
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000112 if [ -n "${release_label}" ]; then
113 export EMBED_LABEL="${release_label}"
114 fi
Damien Martin-Guillerez9c5deb62015-09-15 07:38:26 +0000115
116 if [[ "${JAVA_VERSION-}" =~ ^(1\.)?7$ ]]; then
Damien Martin-Guillerezb95995b2016-01-07 18:10:21 +0000117 JAVA_VERSION=1.7
Damien Martin-Guillerez9c5deb62015-09-15 07:38:26 +0000118 release_label="${release_label}-jdk7"
Damien Martin-Guillerezb95995b2016-01-07 18:10:21 +0000119 else
120 JAVA_VERSION=1.8
Damien Martin-Guillerez9c5deb62015-09-15 07:38:26 +0000121 fi
122
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000123 # Build the packages
Damien Martin-Guillerez7a02e5d2016-01-11 16:47:54 +0000124 local ARGS=
125 if [[ $PLATFORM == "darwin" ]] && \
126 xcodebuild -showsdks 2> /dev/null | grep -q '\-sdk iphonesimulator'; then
127 ARGS="--define IPHONE_SDK=1"
128 fi
Yue Ganadaeaed2017-02-15 09:43:56 +0000129 local OPTIONAL_TARGETS="//site:jekyll-tree //scripts/packages //src/tools/benchmark/webapp:site"
Klaus Aehliga2e63b62017-01-20 11:05:42 +0000130 if [[ $PLATFORM =~ "freebsd" ]] ; then
131 OPTIONAL_TARGETS=
132 fi
Klaus Aehlig736c46d2016-11-10 16:09:34 +0000133 ${BOOTSTRAP_BAZEL} --bazelrc=${BAZELRC:-/dev/null} --nomaster_bazelrc build \
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000134 --embed_label=${release_label} --stamp \
135 --workspace_status_command=scripts/ci/build_status_command.sh \
Damien Martin-Guillerezb95995b2016-01-07 18:10:21 +0000136 --define JAVA_VERSION=${JAVA_VERSION} \
Damien Martin-Guillerez7a02e5d2016-01-11 16:47:54 +0000137 ${ARGS} \
Klaus Aehlig736c46d2016-11-10 16:09:34 +0000138 //src:bazel \
Klaus Aehliga2e63b62017-01-20 11:05:42 +0000139 ${OPTIONAL_TARGETS} || exit $?
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000140
Damien Martin-Guillerezf9b1c332015-09-14 16:27:14 +0000141 if [ -n "${1-}" ]; then
142 # Copy the results to the output directory
143 mkdir -p $1/packages
Klaus Aehlig736c46d2016-11-10 16:09:34 +0000144 cp bazel-bin/src/bazel $1/bazel
Damien Martin-Guillerez04d46ab2016-04-13 19:27:56 +0000145 cp bazel-bin/scripts/packages/install.sh $1/bazel-${release_label}-installer.sh
Damien Martin-Guillerez80245bc2015-10-09 14:10:42 +0000146 if [ "$PLATFORM" = "linux" ]; then
John Caterb0308d42017-01-30 17:49:26 +0000147 cp bazel-bin/scripts/packages/debian/bazel-debian.deb $1/bazel_${release_label}.deb
148 cp -f bazel-genfiles/scripts/packages/debian/bazel.dsc $1/bazel.dsc
149 cp -f bazel-genfiles/scripts/packages/debian/bazel.tar.gz $1/bazel.tar.gz
Klaus Aehlig6f9e2542017-03-07 15:51:33 +0000150 if [ "${JAVA_VERSION}" = "1.8" ]; then
Klaus Aehlig6935ad62017-03-03 13:38:04 +0000151 cp bazel-genfiles/bazel-distfile.zip $1/bazel-${release_label}-dist.zip
152 fi
Damien Martin-Guillerez80245bc2015-10-09 14:10:42 +0000153 fi
Damien Martin-Guillerez4885eef2016-10-28 12:02:50 +0000154 cp bazel-genfiles/site/jekyll-tree.tar $1/www.bazel.build.tar
Yue Ganadaeaed2017-02-15 09:43:56 +0000155 cp bazel-bin/src/tools/benchmark/webapp/site.tar $1/perf.bazel.build.tar.nobuild
Damien Martin-Guillerezf9b1c332015-09-14 16:27:14 +0000156 cp bazel-genfiles/scripts/packages/README.md $1/README.md
157 fi
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000158}
159
160# Generate a string from a template and a list of substitutions.
161# The first parameter is the template name and each subsequent parameter
162# is taken as a couple: first is the string the substitute and the second
163# is the result of the substitution.
164function generate_from_template() {
165 local value="$1"
166 shift
167 while (( $# >= 2 )); do
168 value="${value//$1/$2}"
169 shift 2
170 done
171 echo "${value}"
172}
173
174# Generate the email for the release.
175# The first line of the output will be the recipient, the second line
176# the mail subjects and the subsequent lines the mail, its content.
177# If no planed release, then this function output will be empty.
178function generate_email() {
179 local release_name=$(get_release_name)
180 local rc=$(get_release_candidate)
181 local args=(
182 "%release_name%" "${release_name}"
183 "%rc%" "${rc}"
Damien Martin-Guillerezacbcbc22016-12-20 07:40:42 +0000184 "%relnotes%" "# $(get_full_release_notes)"
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000185 )
186 if [ -n "${rc}" ]; then
187 args+=(
188 "%url%"
189 "$(generate_from_template "${RELEASE_CANDIDATE_URL}" "${args[@]}")"
190 )
191 generate_from_template "$(cat ${EMAIL_TEMPLATE_RC})" "${args[@]}"
192 elif [ -n "${release_name}" ]; then
193 args+=(
194 "%url%"
195 "$(generate_from_template "${RELEASE_URL}" "${args[@]}")"
196 )
197 generate_from_template "$(cat ${EMAIL_TEMPLATE_RELEASE})" "${args[@]}"
198 fi
199}
200
201# Deploy a github release using a third party tool:
202# https://github.com/c4milo/github-release
203# This methods expects the following arguments:
204# $1..$n files generated by package_build (should not contains the README file)
205# Please set GITHUB_TOKEN to talk to the Github API and GITHUB_RELEASE
206# for the path to the https://github.com/c4milo/github-release tool.
207# This method is also affected by GIT_REPOSITORY_URL which should be the
Kristina Chodorow2b1763a2015-09-01 09:15:54 +0000208# URL to the github repository (defaulted to https://github.com/bazelbuild/bazel).
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000209function release_to_github() {
210 local url="${GIT_REPOSITORY_URL}"
211 local release_name=$(get_release_name)
212 local rc=$(get_release_candidate)
213 local release_tool="${GITHUB_RELEASE:-$(which github-release 2>/dev/null || true)}"
Damien Martin-Guillerezbf2e4ee2016-07-06 10:04:34 +0000214 local gpl_warning="
215
216_Notice_: Bazel installers contain binaries licensed under the GPLv2 with
217Classpath exception. Those installers should always be redistributed along with
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000218the source code.
219
Philipp Wollermann95048272017-03-17 15:11:58 +0000220Some versions of Bazel contain a bundled version of OpenJDK. The license of the
221bundled OpenJDK and other open-source components can be displayed by running
222the command `bazel license`. The vendor and version information of the bundled
223OpenJDK can be displayed by running the command `bazel info java-runtime`.
224The binaries and source-code of the bundled OpenJDK can be
225[downloaded from our mirror server](https://bazel-mirror.storage.googleapis.com/openjdk/index.html).
226
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000227_Security_: All our binaries are signed with our
Klaus Aehligbaccf242016-10-28 17:37:35 +0000228[public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0.
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000229"
Damien Martin-Guillerezbf2e4ee2016-07-06 10:04:34 +0000230
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000231 if [ ! -x "${release_tool}" ]; then
232 echo "Please set GITHUB_RELEASE to the path to the github-release binary." >&2
233 echo "This probably means you haven't installed https://github.com/c4milo/github-release " >&2
234 echo "on this machine." >&2
235 return 1
236 fi
237 local github_repo="$(echo "$url" | sed -E 's|https?://github.com/([^/]*/[^/]*).*$|\1|')"
238 if [ -n "${release_name}" ] && [ -z "${rc}" ]; then
Damien Martin-Guillerez7e6351a2015-09-09 09:45:20 +0000239 mkdir -p "${tmpdir}/to-github"
240 cp "${@}" "${tmpdir}/to-github"
Damien Martin-Guillerezbf2e4ee2016-07-06 10:04:34 +0000241 "${GITHUB_RELEASE}" "${github_repo}" "${release_name}" "" "# $(git_commit_msg) ${gpl_warning}" "${tmpdir}/to-github/"'*'
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000242 fi
243}
244
245# Creates an index of the files contained in folder $1 in mardown format
246function create_index_md() {
247 # First, add the README.md
248 local file=$1/__temp.md
249 if [ -f $1/README.md ]; then
250 cat $1/README.md
251 fi
252 # Then, add the list of files
253 echo
254 echo "## Index of files"
255 echo
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000256 # Security notice
257 echo "_Security_: All our binaries are signed with our"
Klaus Aehligbaccf242016-10-28 17:37:35 +0000258 echo "[public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0."
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000259 echo
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000260 for f in $1/*.sha256; do # just list the sha256 ones
261 local filename=$(basename $f .sha256);
Damien Martin-Guillerez671045b2016-10-11 14:17:28 +0000262 echo " - [${filename}](${filename}) [[SHA-256](${filename}.sha256)] [[SIG](${filename}.sig)]"
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000263 done
264}
265
266# Creates an index of the files contained in folder $1 in HTML format
267# It supposes hoedown (https://github.com/hoedown/hoedown) is on the path,
268# if not, set the HOEDOWN environment variable to the good path.
269function create_index_html() {
270 local hoedown="${HOEDOWN:-$(which hoedown 2>/dev/null || true)}"
271 # Second line is to trick hoedown to behave as Github
272 create_index_md "${@}" \
273 | sed -E 's/^(Baseline.*)$/\1\
Damien Martin-Guillerez697c61d2015-11-24 19:19:03 +0000274/' | sed 's/^ + / - /' | sed 's/_/\\_/g' \
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000275 | "${hoedown}"
276}
277
Yun Peng70b29f42016-05-24 18:04:37 +0000278function get_gsutil() {
279 local gs="${GSUTIL:-$(which gsutil 2>/dev/null || true) -m}"
280 if [ ! -x "${gs}" ]; then
281 echo "Please set GSUTIL to the path the gsutil binary." >&2
282 echo "gsutil (https://cloud.google.com/storage/docs/gsutil/) is the" >&2
283 echo "command-line interface to google cloud." >&2
284 exit 1
285 fi
286 echo "${gs}"
287}
288
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000289# Deploy a release candidate to Google Cloud Storage.
290# It requires to have gsutil installed. You can force the path to gsutil
291# by setting the GSUTIL environment variable. The GCS_BUCKET should be the
292# name of the Google cloud bucket to deploy to.
293# This methods expects the following arguments:
294# $1..$n files generated by package_build
295function release_to_gcs() {
Yun Peng70b29f42016-05-24 18:04:37 +0000296 local gs="$(get_gsutil)"
297 local release_name="$(get_release_name)"
298 local rc="$(get_release_candidate)"
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000299 if [ -z "${GCS_BUCKET-}" ]; then
300 echo "Please set GCS_BUCKET to the name of your Google Cloud Storage bucket." >&2
301 return 1
302 fi
303 if [ -n "${release_name}" ] && [ -n "${rc}" ]; then
304 # Make a temporary folder with the desired structure
305 local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)"
306 local prev_dir="$PWD"
307 trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT
308 mkdir -p "${dir}/${release_name}/rc${rc}"
309 cp "${@}" "${dir}/${release_name}/rc${rc}"
310 # Add a index.html file:
311 create_index_html "${dir}/${release_name}/rc${rc}" \
312 >"${dir}/${release_name}/rc${rc}"/index.html
313 cd ${dir}
Laszlo Csomor6331a942016-11-30 12:17:55 +0000314 "${gs}" -m cp -a public-read -r . "gs://${GCS_BUCKET}"
Yun Peng70b29f42016-05-24 18:04:37 +0000315 cd "${prev_dir}"
316 rm -fr "${dir}"
317 trap - EXIT
318 fi
319}
320
Yun Peng3d8ae222016-10-11 13:02:42 +0000321function ensure_gpg_secret_key_imported() {
322 (gpg --list-secret-keys | grep "${APT_GPG_KEY_ID}" > /dev/null) || \
323 gpg --allow-secret-key-import --import "${APT_GPG_KEY_PATH}"
Yun Peng2d1d4922016-11-15 13:33:47 +0000324 # Make sure we use stronger digest algorithm。
325 # We use reprepro to generate the debian repository,
326 # but there's no way to pass flags to gpg using reprepro, so writting it into
327 # ~/.gnupg/gpg.conf
328 (grep "digest-algo sha256" ~/.gnupg/gpg.conf > /dev/null) || \
329 echo "digest-algo sha256" >> ~/.gnupg/gpg.conf
Yun Peng3d8ae222016-10-11 13:02:42 +0000330}
331
Yun Peng70b29f42016-05-24 18:04:37 +0000332function create_apt_repository() {
333 mkdir conf
334 cat > conf/distributions <<EOF
335Origin: Bazel Authors
336Label: Bazel
337Codename: stable
Yun Peng55e042a2016-07-26 13:36:42 +0000338Architectures: amd64 source
Yun Peng70b29f42016-05-24 18:04:37 +0000339Components: jdk1.7 jdk1.8
340Description: Bazel APT Repository
341DebOverride: override.stable
342DscOverride: override.stable
343SignWith: ${APT_GPG_KEY_ID}
344
345Origin: Bazel Authors
346Label: Bazel
347Codename: testing
Yun Peng55e042a2016-07-26 13:36:42 +0000348Architectures: amd64 source
Yun Peng70b29f42016-05-24 18:04:37 +0000349Components: jdk1.7 jdk1.8
350Description: Bazel APT Repository
351DebOverride: override.testing
352DscOverride: override.testing
353SignWith: ${APT_GPG_KEY_ID}
354EOF
355
356 cat > conf/options <<EOF
357verbose
358ask-passphrase
359basedir .
360EOF
361
Damien Martin-Guillerez4fb378c2016-12-20 11:04:02 +0000362 # TODO(#2264): this is a quick workaround #2256, figure out a correct fix.
363 cat > conf/override.stable <<EOF
364bazel Section contrib/devel
365bazel Priority optional
366EOF
367 cat > conf/override.testing <<EOF
368bazel Section contrib/devel
369bazel Priority optional
370EOF
Yun Peng70b29f42016-05-24 18:04:37 +0000371
Yun Peng3d8ae222016-10-11 13:02:42 +0000372 ensure_gpg_secret_key_imported
Yun Peng70b29f42016-05-24 18:04:37 +0000373
374 local distribution="$1"
375 local deb_pkg_name_jdk8="$2"
376 local deb_pkg_name_jdk7="$3"
Yun Peng55e042a2016-07-26 13:36:42 +0000377 local deb_dsc_name="$4"
378
379 debsign -k ${APT_GPG_KEY_ID} "${deb_dsc_name}"
380
Yun Peng70b29f42016-05-24 18:04:37 +0000381 reprepro -C jdk1.8 includedeb "${distribution}" "${deb_pkg_name_jdk8}"
Yun Peng55e042a2016-07-26 13:36:42 +0000382 reprepro -C jdk1.8 includedsc "${distribution}" "${deb_dsc_name}"
Yun Peng70b29f42016-05-24 18:04:37 +0000383 reprepro -C jdk1.7 includedeb "${distribution}" "${deb_pkg_name_jdk7}"
Yun Peng55e042a2016-07-26 13:36:42 +0000384 reprepro -C jdk1.7 includedsc "${distribution}" "${deb_dsc_name}"
Yun Peng70b29f42016-05-24 18:04:37 +0000385
386 "${gs}" -m cp -a public-read -r dists "gs://${GCS_APT_BUCKET}/"
Yun Peng55e042a2016-07-26 13:36:42 +0000387 "${gs}" -m cp -a public-read -r pool "gs://${GCS_APT_BUCKET}/"
Yun Peng70b29f42016-05-24 18:04:37 +0000388}
389
390function release_to_apt() {
391 local gs="$(get_gsutil)"
392 local release_name="$(get_release_name)"
393 local rc="$(get_release_candidate)"
394 if [ -z "${GCS_APT_BUCKET-}" ]; then
395 echo "Please set GCS_APT_BUCKET to the name of your GCS bucket for apt repository." >&2
396 return 1
397 fi
398 if [ -z "${APT_GPG_KEY_ID-}" ]; then
399 echo "Please set APT_GPG_KEY_ID for apt repository." >&2
400 return 1
401 fi
402 if [ -n "${release_name}" ]; then
403 # Make a temporary folder with the desired structure
404 local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)"
405 local prev_dir="$PWD"
406 trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT
407 mkdir -p "${dir}/${release_name}"
408 local release_label="$(get_full_release_name)"
409 local deb_pkg_name_jdk8="${release_name}/bazel_${release_label}-linux-x86_64.deb"
410 local deb_pkg_name_jdk7="${release_name}/bazel_${release_label}-jdk7-linux-x86_64.deb"
Damien Martin-Guillerez4fb378c2016-12-20 11:04:02 +0000411 local deb_dsc_name="${release_name}/bazel_${release_label}.dsc"
412 local deb_tar_name="${release_name}/bazel_${release_label}.tar.gz"
Yun Peng70b29f42016-05-24 18:04:37 +0000413 cp "${tmpdir}/bazel_${release_label}-linux-x86_64.deb" "${dir}/${deb_pkg_name_jdk8}"
414 cp "${tmpdir}/bazel_${release_label}-jdk7-linux-x86_64.deb" "${dir}/${deb_pkg_name_jdk7}"
Yun Peng55e042a2016-07-26 13:36:42 +0000415 cp "${tmpdir}/bazel.dsc" "${dir}/${deb_dsc_name}"
416 cp "${tmpdir}/bazel.tar.gz" "${dir}/${deb_tar_name}"
Yun Peng70b29f42016-05-24 18:04:37 +0000417 cd "${dir}"
418 if [ -n "${rc}" ]; then
Yun Peng55e042a2016-07-26 13:36:42 +0000419 create_apt_repository testing "${deb_pkg_name_jdk8}" "${deb_pkg_name_jdk7}" "${deb_dsc_name}"
Yun Peng70b29f42016-05-24 18:04:37 +0000420 else
Yun Peng55e042a2016-07-26 13:36:42 +0000421 create_apt_repository stable "${deb_pkg_name_jdk8}" "${deb_pkg_name_jdk7}" "${deb_dsc_name}"
Yun Peng70b29f42016-05-24 18:04:37 +0000422 fi
423 cd "${prev_dir}"
424 rm -fr "${dir}"
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000425 trap - EXIT
426 fi
427}
428
429# A wrapper around the release deployment methods.
430function deploy_release() {
431 local github_args=()
432 # Filters out README.md for github releases
433 for i in "$@"; do
Yue Gan80ce6fe2017-03-15 15:31:02 +0000434 if ! ( [[ "$i" =~ README.md$ ]] || [[ "$i" =~ bazel.dsc ]] || [[ "$i" =~ bazel.tar.gz ]] || [[ "$i" =~ .nobuild$ ]] ) ; then
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000435 github_args+=("$i")
436 fi
437 done
Yue Gan80ce6fe2017-03-15 15:31:02 +0000438 local gcs_args=()
439 # Filters out perf.bazel.*.nobuild
440 for i in "$@"; do
441 if ! [[ "$i" =~ .nobuild$ ]] ; then
442 gcs_args+=("$i")
443 fi
444 done
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000445 release_to_github "${github_args[@]}"
Yue Gan80ce6fe2017-03-15 15:31:02 +0000446 release_to_gcs "${gcs_args[@]}"
Yun Peng70b29f42016-05-24 18:04:37 +0000447 release_to_apt
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000448}
449
450# A wrapper for the whole release phase:
451# Compute the SHA-256, and arrange the input
Yun Peng3d8ae222016-10-11 13:02:42 +0000452# Sign every binary using gpg and generating .sig files
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000453# Deploy the release
454# Generate the email
455# Input: $1 $2 [$3 $4 [$5 $6 ...]]
456# Each pair denotes a couple (platform, folder) where the platform
457# is the platform built for and the folder is the folder where the
458# artifacts for this platform are.
459# Ouputs:
460# RELEASE_EMAIL_RECIPIENT: who to send a mail to
461# RELEASE_EMAIL_SUBJECT: the subject of the email to be sent
462# RELEASE_EMAIL_CONTENT: the content of the email to be sent
463function bazel_release() {
464 local README=$2/README.md
Damien Martin-Guillerez7e6351a2015-09-09 09:45:20 +0000465 tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000466 trap 'rm -fr ${tmpdir}' EXIT
Yun Peng3d8ae222016-10-11 13:02:42 +0000467 ensure_gpg_secret_key_imported
468
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000469 while (( $# > 1 )); do
470 local platform=$1
471 local folder=$2
472 shift 2
473 for file in $folder/*; do
Yun Peng55e042a2016-07-26 13:36:42 +0000474 local filename=$(basename $file)
475 if [ "$filename" != README.md ]; then
Klaus Aehlig279a0612016-11-11 09:51:44 +0000476 if [ "$filename" == "bazel.dsc" ] || [ "$filename" == "bazel.tar.gz" ] \
Klaus Aehlige626f742016-11-23 14:18:30 +0000477 || [[ "$filename" =~ bazel-(.*)-dist\.zip ]] ; then
Yun Peng55e042a2016-07-26 13:36:42 +0000478 local destfile=${tmpdir}/$filename
479 elif [[ "$file" =~ /([^/]*)(\.[^\./]+)$ ]]; then
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000480 local destfile=${tmpdir}/${BASH_REMATCH[1]}-${platform}${BASH_REMATCH[2]}
481 else
Yun Peng55e042a2016-07-26 13:36:42 +0000482 local destfile=${tmpdir}/$filename-${platform}
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000483 fi
Yun Peng6a3565e2016-10-26 11:54:40 +0000484 # bazel.tar.gz is duplicated under different platforms
485 # if the file is already there, skip signing and checksum it again.
486 if [ ! -f "$destfile" ]; then
487 mv $file $destfile
488 checksum $destfile > $destfile.sha256
489 gpg --no-tty --detach-sign -u "${APT_GPG_KEY_ID}" "$destfile"
490 fi
Damien Martin-Guillerezf7a39312015-08-17 08:32:09 +0000491 fi
492 done
493 done
494 deploy_release $README $(find ${tmpdir} -type f)
495
496 export RELEASE_EMAIL="$(generate_email)"
497
498 export RELEASE_EMAIL_RECIPIENT="$(echo "${RELEASE_EMAIL}" | head -1)"
499 export RELEASE_EMAIL_SUBJECT="$(echo "${RELEASE_EMAIL}" | head -2 | tail -1)"
500 export RELEASE_EMAIL_CONTENT="$(echo "${RELEASE_EMAIL}" | tail -n +3)"
501}
Damien Martin-Guillerez1164a4f2016-05-24 18:22:22 +0000502
503# Use jekyll build to build the site and then gsutil to copy it to GCS
504# Input: $1 tarball to the jekyll site
505# $2 name of the bucket to deploy the site to
Yue Ganadaeaed2017-02-15 09:43:56 +0000506# $3 "nobuild" if only publish without build
Damien Martin-Guillerez1164a4f2016-05-24 18:22:22 +0000507# It requires to have gsutil installed. You can force the path to gsutil
508# by setting the GSUTIL environment variable
509function build_and_publish_site() {
510 tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)
511 trap 'rm -fr ${tmpdir}' EXIT
512 local gs="$(get_gsutil)"
513 local site="$1"
514 local bucket="$2"
Yue Ganadaeaed2017-02-15 09:43:56 +0000515 local nobuild="$3"
Damien Martin-Guillerez1164a4f2016-05-24 18:22:22 +0000516
517 if [ ! -f "${site}" ] || [ -z "${bucket}" ]; then
518 echo "Usage: build_and_publish_site <site-tarball> <bucket>" >&2
519 return 1
520 fi
Yue Ganadaeaed2017-02-15 09:43:56 +0000521 local prod_dir="${tmpdir}"
Yue Gan06c3a542017-02-15 18:19:41 +0000522 tar xf "${site}" --exclude=CNAME -C "${tmpdir}"
Yue Ganadaeaed2017-02-15 09:43:56 +0000523 if [ "$nobuild" != "nobuild" ]; then
Yue Ganadaeaed2017-02-15 09:43:56 +0000524 jekyll build -s "${tmpdir}" -d "${tmpdir}/production"
525 prod_dir="${tmpdir}/production"
526 fi
527
Damien Martin-Guillerezd38ee632016-10-12 11:20:42 +0000528 # Rsync:
529 # -r: recursive
530 # -c: compute checksum even though the input is from the filesystem
Yue Ganadaeaed2017-02-15 09:43:56 +0000531 "${gs}" rsync -r -c "${prod_dir}" "gs://${bucket}"
Damien Martin-Guillerez1164a4f2016-05-24 18:22:22 +0000532 "${gs}" web set -m index.html -e 404.html "gs://${bucket}"
533 "${gs}" -m acl ch -R -u AllUsers:R "gs://${bucket}"
534}
Yue Gan26673262017-02-16 17:40:12 +0000535
536# Push json file to perf site, also add to file_list
Yue Gane86550a2017-02-20 13:33:09 +0000537# Input: $1 json file to push
Yue Gan26673262017-02-16 17:40:12 +0000538# $2 name of the bucket to deploy the site to
539function push_benchmark_output_to_site() {
540 tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)
541 trap 'rm -fr ${tmpdir}' EXIT
542 local gs="$(get_gsutil)"
Yue Gane86550a2017-02-20 13:33:09 +0000543 local output_file="$1"
544 local output_file_basename="$(basename ${output_file})"
Yue Gan26673262017-02-16 17:40:12 +0000545 local bucket="$2"
546
Yue Gane86550a2017-02-20 13:33:09 +0000547 if [ ! -f "${output_file}" ] || [ -z "${bucket}" ]; then
Yue Gan26673262017-02-16 17:40:12 +0000548 echo "Usage: push_benchmark_output_to_site <json-file-name> <bucket>" >&2
549 return 1
550 fi
551
552 # Upload json file
Yue Gane86550a2017-02-20 13:33:09 +0000553 "${gs}" cp "${output_file}" "gs://${bucket}/data/${output_file_basename}"
Yue Gan26673262017-02-16 17:40:12 +0000554
555 # Download file_list (it might not exist)
556 "${gs}" cp "gs://${bucket}/file_list" "${tmpdir}" || true
557 # Update file_list
558 local list_file="${tmpdir}/file_list"
Yue Gane86550a2017-02-20 13:33:09 +0000559 echo "${output_file_basename}" >> "${list_file}"
Yue Gan26673262017-02-16 17:40:12 +0000560 "${gs}" cp "${list_file}" "gs://${bucket}/file_list"
561
562 "${gs}" -m acl ch -R -u AllUsers:R "gs://${bucket}"
563}