Philipp Wollermann | a5afe95 | 2016-06-21 14:58:09 +0000 | [diff] [blame] | 1 | #!/bin/bash |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 2 | |
Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 3 | # Copyright 2015 The Bazel Authors. All rights reserved. |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 4 | # |
| 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 Wollermann | a5afe95 | 2016-06-21 14:58:09 +0000 | [diff] [blame] | 17 | set -eu |
| 18 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 19 | # 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 |
| 27 | SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) |
Damien Martin-Guillerez | e4ead96 | 2015-08-17 15:21:50 +0000 | [diff] [blame] | 28 | source $(dirname ${SCRIPT_DIR})/release/common.sh |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 29 | |
Kristina Chodorow | 2b1763a | 2015-09-01 09:15:54 +0000 | [diff] [blame] | 30 | : ${GIT_REPOSITORY_URL:=https://github.com/bazelbuild/bazel} |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 31 | |
| 32 | : ${GCS_BASE_URL:=https://storage.googleapis.com} |
| 33 | : ${GCS_BUCKET:=bucket-o-bazel} |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 34 | : ${GCS_APT_BUCKET:=bazel-apt} |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 35 | |
| 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 Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 42 | : ${BOOTSTRAP_BAZEL:=bazel} |
| 43 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 44 | PLATFORM="$(uname -s | tr 'A-Z' 'a-z')" |
Klaus Aehlig | 1ad08ba | 2017-01-19 16:15:53 +0000 | [diff] [blame] | 45 | if [[ ${PLATFORM} == "darwin" ]] || [[ ${PLATFORM} == "freebsd" ]] ; then |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 46 | function checksum() { |
Damien Martin-Guillerez | c375ea1 | 2015-09-10 09:58:44 +0000 | [diff] [blame] | 47 | (cd "$(dirname "$1")" && shasum -a 256 "$(basename "$1")") |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 48 | } |
| 49 | else |
| 50 | function checksum() { |
Damien Martin-Guillerez | c375ea1 | 2015-09-10 09:58:44 +0000 | [diff] [blame] | 51 | (cd "$(dirname "$1")" && sha256sum "$(basename "$1")") |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 52 | } |
| 53 | fi |
| 54 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 55 | # Returns the full release name in the form NAME(rcRC)? |
| 56 | function 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-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 66 | function 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 Wollermann | 9d9657b | 2016-08-19 10:45:28 +0000 | [diff] [blame] | 71 | # Make sure that WORKSPACE ends with a newline, otherwise we'll end up with |
| 72 | # a syntax error. |
| 73 | echo >>WORKSPACE |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 74 | cat >>WORKSPACE <<EOF |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 75 | android_sdk_repository( |
| 76 | name = "androidsdk", |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 77 | path = "${ANDROID_SDK_PATH}", |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 78 | build_tools_version = "${ANDROID_SDK_BUILD_TOOLS_VERSION:-22.0.1}", |
| 79 | api_level = ${ANDROID_SDK_API_LEVEL:-21}, |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 80 | ) |
| 81 | |
| 82 | bind( |
| 83 | name = "android_sdk_for_testing", |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 84 | actual = "@androidsdk//:files", |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 85 | ) |
| 86 | EOF |
| 87 | if [ -n "${ANDROID_NDK_PATH-}" ]; then |
| 88 | cat >>WORKSPACE <<EOF |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 89 | android_ndk_repository( |
| 90 | name = "androidndk", |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 91 | path = "${ANDROID_NDK_PATH}", |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 92 | api_level = ${ANDROID_NDK_API_LEVEL:-21}, |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 93 | ) |
| 94 | |
| 95 | bind( |
| 96 | name = "android_ndk_for_testing", |
Lukacs Berki | 4e21d90 | 2015-09-07 09:59:50 +0000 | [diff] [blame] | 97 | actual = "@androidndk//:files", |
Damien Martin-Guillerez | dbf5cad | 2015-09-04 12:46:23 +0000 | [diff] [blame] | 98 | ) |
| 99 | EOF |
| 100 | fi |
| 101 | fi |
| 102 | } |
Damien Martin-Guillerez | 9c5deb6 | 2015-09-15 07:38:26 +0000 | [diff] [blame] | 103 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 104 | # 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 |
| 108 | function bazel_build() { |
| 109 | local release_label="$(get_full_release_name)" |
| 110 | local embed_label_opts= |
Damien Martin-Guillerez | 9c5deb6 | 2015-09-15 07:38:26 +0000 | [diff] [blame] | 111 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 112 | if [ -n "${release_label}" ]; then |
| 113 | export EMBED_LABEL="${release_label}" |
| 114 | fi |
Damien Martin-Guillerez | 9c5deb6 | 2015-09-15 07:38:26 +0000 | [diff] [blame] | 115 | |
| 116 | if [[ "${JAVA_VERSION-}" =~ ^(1\.)?7$ ]]; then |
Damien Martin-Guillerez | b95995b | 2016-01-07 18:10:21 +0000 | [diff] [blame] | 117 | JAVA_VERSION=1.7 |
Damien Martin-Guillerez | 9c5deb6 | 2015-09-15 07:38:26 +0000 | [diff] [blame] | 118 | release_label="${release_label}-jdk7" |
Damien Martin-Guillerez | b95995b | 2016-01-07 18:10:21 +0000 | [diff] [blame] | 119 | else |
| 120 | JAVA_VERSION=1.8 |
Damien Martin-Guillerez | 9c5deb6 | 2015-09-15 07:38:26 +0000 | [diff] [blame] | 121 | fi |
| 122 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 123 | # Build the packages |
Damien Martin-Guillerez | 7a02e5d | 2016-01-11 16:47:54 +0000 | [diff] [blame] | 124 | 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 Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 129 | local OPTIONAL_TARGETS="//site:jekyll-tree //scripts/packages //src/tools/benchmark/webapp:site" |
Klaus Aehlig | a2e63b6 | 2017-01-20 11:05:42 +0000 | [diff] [blame] | 130 | if [[ $PLATFORM =~ "freebsd" ]] ; then |
| 131 | OPTIONAL_TARGETS= |
| 132 | fi |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 133 | ${BOOTSTRAP_BAZEL} --bazelrc=${BAZELRC:-/dev/null} --nomaster_bazelrc build \ |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 134 | --embed_label=${release_label} --stamp \ |
| 135 | --workspace_status_command=scripts/ci/build_status_command.sh \ |
Damien Martin-Guillerez | b95995b | 2016-01-07 18:10:21 +0000 | [diff] [blame] | 136 | --define JAVA_VERSION=${JAVA_VERSION} \ |
Damien Martin-Guillerez | 7a02e5d | 2016-01-11 16:47:54 +0000 | [diff] [blame] | 137 | ${ARGS} \ |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 138 | //src:bazel \ |
Klaus Aehlig | a2e63b6 | 2017-01-20 11:05:42 +0000 | [diff] [blame] | 139 | ${OPTIONAL_TARGETS} || exit $? |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 140 | |
Damien Martin-Guillerez | f9b1c33 | 2015-09-14 16:27:14 +0000 | [diff] [blame] | 141 | if [ -n "${1-}" ]; then |
| 142 | # Copy the results to the output directory |
| 143 | mkdir -p $1/packages |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 144 | cp bazel-bin/src/bazel $1/bazel |
Damien Martin-Guillerez | 04d46ab | 2016-04-13 19:27:56 +0000 | [diff] [blame] | 145 | cp bazel-bin/scripts/packages/install.sh $1/bazel-${release_label}-installer.sh |
Damien Martin-Guillerez | 80245bc | 2015-10-09 14:10:42 +0000 | [diff] [blame] | 146 | if [ "$PLATFORM" = "linux" ]; then |
John Cater | b0308d4 | 2017-01-30 17:49:26 +0000 | [diff] [blame] | 147 | 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 Aehlig | 6f9e254 | 2017-03-07 15:51:33 +0000 | [diff] [blame] | 150 | if [ "${JAVA_VERSION}" = "1.8" ]; then |
Klaus Aehlig | 6935ad6 | 2017-03-03 13:38:04 +0000 | [diff] [blame] | 151 | cp bazel-genfiles/bazel-distfile.zip $1/bazel-${release_label}-dist.zip |
| 152 | fi |
Damien Martin-Guillerez | 80245bc | 2015-10-09 14:10:42 +0000 | [diff] [blame] | 153 | fi |
Damien Martin-Guillerez | 4885eef | 2016-10-28 12:02:50 +0000 | [diff] [blame] | 154 | cp bazel-genfiles/site/jekyll-tree.tar $1/www.bazel.build.tar |
Yue Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 155 | cp bazel-bin/src/tools/benchmark/webapp/site.tar $1/perf.bazel.build.tar.nobuild |
Damien Martin-Guillerez | f9b1c33 | 2015-09-14 16:27:14 +0000 | [diff] [blame] | 156 | cp bazel-genfiles/scripts/packages/README.md $1/README.md |
| 157 | fi |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 158 | } |
| 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. |
| 164 | function 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. |
| 178 | function 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-Guillerez | acbcbc2 | 2016-12-20 07:40:42 +0000 | [diff] [blame] | 184 | "%relnotes%" "# $(get_full_release_notes)" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 185 | ) |
| 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 Chodorow | 2b1763a | 2015-09-01 09:15:54 +0000 | [diff] [blame] | 208 | # URL to the github repository (defaulted to https://github.com/bazelbuild/bazel). |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 209 | function 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-Guillerez | bf2e4ee | 2016-07-06 10:04:34 +0000 | [diff] [blame] | 214 | local gpl_warning=" |
| 215 | |
| 216 | _Notice_: Bazel installers contain binaries licensed under the GPLv2 with |
| 217 | Classpath exception. Those installers should always be redistributed along with |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 218 | the source code. |
| 219 | |
Philipp Wollermann | 9504827 | 2017-03-17 15:11:58 +0000 | [diff] [blame] | 220 | Some versions of Bazel contain a bundled version of OpenJDK. The license of the |
| 221 | bundled OpenJDK and other open-source components can be displayed by running |
| 222 | the command `bazel license`. The vendor and version information of the bundled |
| 223 | OpenJDK can be displayed by running the command `bazel info java-runtime`. |
| 224 | The 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-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 227 | _Security_: All our binaries are signed with our |
Klaus Aehlig | baccf24 | 2016-10-28 17:37:35 +0000 | [diff] [blame] | 228 | [public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0. |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 229 | " |
Damien Martin-Guillerez | bf2e4ee | 2016-07-06 10:04:34 +0000 | [diff] [blame] | 230 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 231 | 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-Guillerez | 7e6351a | 2015-09-09 09:45:20 +0000 | [diff] [blame] | 239 | mkdir -p "${tmpdir}/to-github" |
| 240 | cp "${@}" "${tmpdir}/to-github" |
Damien Martin-Guillerez | bf2e4ee | 2016-07-06 10:04:34 +0000 | [diff] [blame] | 241 | "${GITHUB_RELEASE}" "${github_repo}" "${release_name}" "" "# $(git_commit_msg) ${gpl_warning}" "${tmpdir}/to-github/"'*' |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 242 | fi |
| 243 | } |
| 244 | |
| 245 | # Creates an index of the files contained in folder $1 in mardown format |
| 246 | function 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-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 256 | # Security notice |
| 257 | echo "_Security_: All our binaries are signed with our" |
Klaus Aehlig | baccf24 | 2016-10-28 17:37:35 +0000 | [diff] [blame] | 258 | echo "[public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0." |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 259 | echo |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 260 | for f in $1/*.sha256; do # just list the sha256 ones |
| 261 | local filename=$(basename $f .sha256); |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 262 | echo " - [${filename}](${filename}) [[SHA-256](${filename}.sha256)] [[SIG](${filename}.sig)]" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 263 | 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. |
| 269 | function 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-Guillerez | 697c61d | 2015-11-24 19:19:03 +0000 | [diff] [blame] | 274 | /' | sed 's/^ + / - /' | sed 's/_/\\_/g' \ |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 275 | | "${hoedown}" |
| 276 | } |
| 277 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 278 | function 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-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 289 | # 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 |
| 295 | function release_to_gcs() { |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 296 | local gs="$(get_gsutil)" |
| 297 | local release_name="$(get_release_name)" |
| 298 | local rc="$(get_release_candidate)" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 299 | 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 Csomor | 6331a94 | 2016-11-30 12:17:55 +0000 | [diff] [blame] | 314 | "${gs}" -m cp -a public-read -r . "gs://${GCS_BUCKET}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 315 | cd "${prev_dir}" |
| 316 | rm -fr "${dir}" |
| 317 | trap - EXIT |
| 318 | fi |
| 319 | } |
| 320 | |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 321 | function 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 Peng | 2d1d492 | 2016-11-15 13:33:47 +0000 | [diff] [blame] | 324 | # 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 Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 330 | } |
| 331 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 332 | function create_apt_repository() { |
| 333 | mkdir conf |
| 334 | cat > conf/distributions <<EOF |
| 335 | Origin: Bazel Authors |
| 336 | Label: Bazel |
| 337 | Codename: stable |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 338 | Architectures: amd64 source |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 339 | Components: jdk1.7 jdk1.8 |
| 340 | Description: Bazel APT Repository |
| 341 | DebOverride: override.stable |
| 342 | DscOverride: override.stable |
| 343 | SignWith: ${APT_GPG_KEY_ID} |
| 344 | |
| 345 | Origin: Bazel Authors |
| 346 | Label: Bazel |
| 347 | Codename: testing |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 348 | Architectures: amd64 source |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 349 | Components: jdk1.7 jdk1.8 |
| 350 | Description: Bazel APT Repository |
| 351 | DebOverride: override.testing |
| 352 | DscOverride: override.testing |
| 353 | SignWith: ${APT_GPG_KEY_ID} |
| 354 | EOF |
| 355 | |
| 356 | cat > conf/options <<EOF |
| 357 | verbose |
| 358 | ask-passphrase |
| 359 | basedir . |
| 360 | EOF |
| 361 | |
Damien Martin-Guillerez | 4fb378c | 2016-12-20 11:04:02 +0000 | [diff] [blame] | 362 | # TODO(#2264): this is a quick workaround #2256, figure out a correct fix. |
| 363 | cat > conf/override.stable <<EOF |
| 364 | bazel Section contrib/devel |
| 365 | bazel Priority optional |
| 366 | EOF |
| 367 | cat > conf/override.testing <<EOF |
| 368 | bazel Section contrib/devel |
| 369 | bazel Priority optional |
| 370 | EOF |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 371 | |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 372 | ensure_gpg_secret_key_imported |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 373 | |
| 374 | local distribution="$1" |
| 375 | local deb_pkg_name_jdk8="$2" |
| 376 | local deb_pkg_name_jdk7="$3" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 377 | local deb_dsc_name="$4" |
| 378 | |
| 379 | debsign -k ${APT_GPG_KEY_ID} "${deb_dsc_name}" |
| 380 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 381 | reprepro -C jdk1.8 includedeb "${distribution}" "${deb_pkg_name_jdk8}" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 382 | reprepro -C jdk1.8 includedsc "${distribution}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 383 | reprepro -C jdk1.7 includedeb "${distribution}" "${deb_pkg_name_jdk7}" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 384 | reprepro -C jdk1.7 includedsc "${distribution}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 385 | |
| 386 | "${gs}" -m cp -a public-read -r dists "gs://${GCS_APT_BUCKET}/" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 387 | "${gs}" -m cp -a public-read -r pool "gs://${GCS_APT_BUCKET}/" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 388 | } |
| 389 | |
| 390 | function 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-Guillerez | 4fb378c | 2016-12-20 11:04:02 +0000 | [diff] [blame] | 411 | local deb_dsc_name="${release_name}/bazel_${release_label}.dsc" |
| 412 | local deb_tar_name="${release_name}/bazel_${release_label}.tar.gz" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 413 | 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 Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 415 | cp "${tmpdir}/bazel.dsc" "${dir}/${deb_dsc_name}" |
| 416 | cp "${tmpdir}/bazel.tar.gz" "${dir}/${deb_tar_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 417 | cd "${dir}" |
| 418 | if [ -n "${rc}" ]; then |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 419 | create_apt_repository testing "${deb_pkg_name_jdk8}" "${deb_pkg_name_jdk7}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 420 | else |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 421 | create_apt_repository stable "${deb_pkg_name_jdk8}" "${deb_pkg_name_jdk7}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 422 | fi |
| 423 | cd "${prev_dir}" |
| 424 | rm -fr "${dir}" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 425 | trap - EXIT |
| 426 | fi |
| 427 | } |
| 428 | |
| 429 | # A wrapper around the release deployment methods. |
| 430 | function deploy_release() { |
| 431 | local github_args=() |
| 432 | # Filters out README.md for github releases |
| 433 | for i in "$@"; do |
Yue Gan | 80ce6fe | 2017-03-15 15:31:02 +0000 | [diff] [blame] | 434 | if ! ( [[ "$i" =~ README.md$ ]] || [[ "$i" =~ bazel.dsc ]] || [[ "$i" =~ bazel.tar.gz ]] || [[ "$i" =~ .nobuild$ ]] ) ; then |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 435 | github_args+=("$i") |
| 436 | fi |
| 437 | done |
Yue Gan | 80ce6fe | 2017-03-15 15:31:02 +0000 | [diff] [blame] | 438 | 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-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 445 | release_to_github "${github_args[@]}" |
Yue Gan | 80ce6fe | 2017-03-15 15:31:02 +0000 | [diff] [blame] | 446 | release_to_gcs "${gcs_args[@]}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 447 | release_to_apt |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 448 | } |
| 449 | |
| 450 | # A wrapper for the whole release phase: |
| 451 | # Compute the SHA-256, and arrange the input |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 452 | # Sign every binary using gpg and generating .sig files |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 453 | # 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 |
| 463 | function bazel_release() { |
| 464 | local README=$2/README.md |
Damien Martin-Guillerez | 7e6351a | 2015-09-09 09:45:20 +0000 | [diff] [blame] | 465 | tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX) |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 466 | trap 'rm -fr ${tmpdir}' EXIT |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 467 | ensure_gpg_secret_key_imported |
| 468 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 469 | while (( $# > 1 )); do |
| 470 | local platform=$1 |
| 471 | local folder=$2 |
| 472 | shift 2 |
| 473 | for file in $folder/*; do |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 474 | local filename=$(basename $file) |
| 475 | if [ "$filename" != README.md ]; then |
Klaus Aehlig | 279a061 | 2016-11-11 09:51:44 +0000 | [diff] [blame] | 476 | if [ "$filename" == "bazel.dsc" ] || [ "$filename" == "bazel.tar.gz" ] \ |
Klaus Aehlig | e626f74 | 2016-11-23 14:18:30 +0000 | [diff] [blame] | 477 | || [[ "$filename" =~ bazel-(.*)-dist\.zip ]] ; then |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 478 | local destfile=${tmpdir}/$filename |
| 479 | elif [[ "$file" =~ /([^/]*)(\.[^\./]+)$ ]]; then |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 480 | local destfile=${tmpdir}/${BASH_REMATCH[1]}-${platform}${BASH_REMATCH[2]} |
| 481 | else |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 482 | local destfile=${tmpdir}/$filename-${platform} |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 483 | fi |
Yun Peng | 6a3565e | 2016-10-26 11:54:40 +0000 | [diff] [blame] | 484 | # 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-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 491 | 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-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 502 | |
| 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 Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 506 | # $3 "nobuild" if only publish without build |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 507 | # It requires to have gsutil installed. You can force the path to gsutil |
| 508 | # by setting the GSUTIL environment variable |
| 509 | function 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 Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 515 | local nobuild="$3" |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 516 | |
| 517 | if [ ! -f "${site}" ] || [ -z "${bucket}" ]; then |
| 518 | echo "Usage: build_and_publish_site <site-tarball> <bucket>" >&2 |
| 519 | return 1 |
| 520 | fi |
Yue Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 521 | local prod_dir="${tmpdir}" |
Yue Gan | 06c3a54 | 2017-02-15 18:19:41 +0000 | [diff] [blame] | 522 | tar xf "${site}" --exclude=CNAME -C "${tmpdir}" |
Yue Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 523 | if [ "$nobuild" != "nobuild" ]; then |
Yue Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 524 | jekyll build -s "${tmpdir}" -d "${tmpdir}/production" |
| 525 | prod_dir="${tmpdir}/production" |
| 526 | fi |
| 527 | |
Damien Martin-Guillerez | d38ee63 | 2016-10-12 11:20:42 +0000 | [diff] [blame] | 528 | # Rsync: |
| 529 | # -r: recursive |
| 530 | # -c: compute checksum even though the input is from the filesystem |
Yue Gan | adaeaed | 2017-02-15 09:43:56 +0000 | [diff] [blame] | 531 | "${gs}" rsync -r -c "${prod_dir}" "gs://${bucket}" |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 532 | "${gs}" web set -m index.html -e 404.html "gs://${bucket}" |
| 533 | "${gs}" -m acl ch -R -u AllUsers:R "gs://${bucket}" |
| 534 | } |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 535 | |
| 536 | # Push json file to perf site, also add to file_list |
Yue Gan | e86550a | 2017-02-20 13:33:09 +0000 | [diff] [blame] | 537 | # Input: $1 json file to push |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 538 | # $2 name of the bucket to deploy the site to |
| 539 | function 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 Gan | e86550a | 2017-02-20 13:33:09 +0000 | [diff] [blame] | 543 | local output_file="$1" |
| 544 | local output_file_basename="$(basename ${output_file})" |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 545 | local bucket="$2" |
| 546 | |
Yue Gan | e86550a | 2017-02-20 13:33:09 +0000 | [diff] [blame] | 547 | if [ ! -f "${output_file}" ] || [ -z "${bucket}" ]; then |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 548 | echo "Usage: push_benchmark_output_to_site <json-file-name> <bucket>" >&2 |
| 549 | return 1 |
| 550 | fi |
| 551 | |
| 552 | # Upload json file |
Yue Gan | e86550a | 2017-02-20 13:33:09 +0000 | [diff] [blame] | 553 | "${gs}" cp "${output_file}" "gs://${bucket}/data/${output_file_basename}" |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 554 | |
| 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 Gan | e86550a | 2017-02-20 13:33:09 +0000 | [diff] [blame] | 559 | echo "${output_file_basename}" >> "${list_file}" |
Yue Gan | 2667326 | 2017-02-16 17:40:12 +0000 | [diff] [blame] | 560 | "${gs}" cp "${list_file}" "gs://${bucket}/file_list" |
| 561 | |
| 562 | "${gs}" -m acl ch -R -u AllUsers:R "gs://${bucket}" |
| 563 | } |