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')" |
| 45 | if [[ ${PLATFORM} == "darwin" ]]; then |
| 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 | |
| 123 | setup_android_repositories |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 124 | |
| 125 | # Build the packages |
Damien Martin-Guillerez | 7a02e5d | 2016-01-11 16:47:54 +0000 | [diff] [blame] | 126 | local ARGS= |
| 127 | if [[ $PLATFORM == "darwin" ]] && \ |
| 128 | xcodebuild -showsdks 2> /dev/null | grep -q '\-sdk iphonesimulator'; then |
| 129 | ARGS="--define IPHONE_SDK=1" |
| 130 | fi |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 131 | ${BOOTSTRAP_BAZEL} --bazelrc=${BAZELRC:-/dev/null} --nomaster_bazelrc build \ |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 132 | --embed_label=${release_label} --stamp \ |
| 133 | --workspace_status_command=scripts/ci/build_status_command.sh \ |
Damien Martin-Guillerez | b95995b | 2016-01-07 18:10:21 +0000 | [diff] [blame] | 134 | --define JAVA_VERSION=${JAVA_VERSION} \ |
Damien Martin-Guillerez | 7a02e5d | 2016-01-11 16:47:54 +0000 | [diff] [blame] | 135 | ${ARGS} \ |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 136 | //src:bazel \ |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 137 | //site:jekyll-tree \ |
Yun Peng | 047b0e6 | 2016-07-27 12:50:15 +0000 | [diff] [blame] | 138 | //scripts/packages || exit $? |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 139 | |
Damien Martin-Guillerez | f9b1c33 | 2015-09-14 16:27:14 +0000 | [diff] [blame] | 140 | if [ -n "${1-}" ]; then |
| 141 | # Copy the results to the output directory |
| 142 | mkdir -p $1/packages |
Klaus Aehlig | 736c46d | 2016-11-10 16:09:34 +0000 | [diff] [blame] | 143 | cp bazel-bin/src/bazel $1/bazel |
Damien Martin-Guillerez | 04d46ab | 2016-04-13 19:27:56 +0000 | [diff] [blame] | 144 | 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] | 145 | if [ "$PLATFORM" = "linux" ]; then |
Damien Martin-Guillerez | 04d46ab | 2016-04-13 19:27:56 +0000 | [diff] [blame] | 146 | cp bazel-bin/scripts/packages/bazel-debian.deb $1/bazel_${release_label}.deb |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 147 | cp -f bazel-genfiles/scripts/packages/bazel.dsc $1/bazel.dsc |
| 148 | cp -f bazel-genfiles/scripts/packages/bazel.tar.gz $1/bazel.tar.gz |
Klaus Aehlig | 034ad04 | 2016-11-11 10:53:30 +0000 | [diff] [blame] | 149 | cp bazel-genfiles/bazel-distfile.zip $1/bazel-${release_label}-dist.zip |
Damien Martin-Guillerez | 80245bc | 2015-10-09 14:10:42 +0000 | [diff] [blame] | 150 | fi |
Damien Martin-Guillerez | 4885eef | 2016-10-28 12:02:50 +0000 | [diff] [blame] | 151 | cp bazel-genfiles/site/jekyll-tree.tar $1/www.bazel.build.tar |
Damien Martin-Guillerez | f9b1c33 | 2015-09-14 16:27:14 +0000 | [diff] [blame] | 152 | cp bazel-genfiles/scripts/packages/README.md $1/README.md |
| 153 | fi |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | # Generate a string from a template and a list of substitutions. |
| 157 | # The first parameter is the template name and each subsequent parameter |
| 158 | # is taken as a couple: first is the string the substitute and the second |
| 159 | # is the result of the substitution. |
| 160 | function generate_from_template() { |
| 161 | local value="$1" |
| 162 | shift |
| 163 | while (( $# >= 2 )); do |
| 164 | value="${value//$1/$2}" |
| 165 | shift 2 |
| 166 | done |
| 167 | echo "${value}" |
| 168 | } |
| 169 | |
| 170 | # Generate the email for the release. |
| 171 | # The first line of the output will be the recipient, the second line |
| 172 | # the mail subjects and the subsequent lines the mail, its content. |
| 173 | # If no planed release, then this function output will be empty. |
| 174 | function generate_email() { |
| 175 | local release_name=$(get_release_name) |
| 176 | local rc=$(get_release_candidate) |
| 177 | local args=( |
| 178 | "%release_name%" "${release_name}" |
| 179 | "%rc%" "${rc}" |
| 180 | "%relnotes%" "# $(git_commit_msg)" |
| 181 | ) |
| 182 | if [ -n "${rc}" ]; then |
| 183 | args+=( |
| 184 | "%url%" |
| 185 | "$(generate_from_template "${RELEASE_CANDIDATE_URL}" "${args[@]}")" |
| 186 | ) |
| 187 | generate_from_template "$(cat ${EMAIL_TEMPLATE_RC})" "${args[@]}" |
| 188 | elif [ -n "${release_name}" ]; then |
| 189 | args+=( |
| 190 | "%url%" |
| 191 | "$(generate_from_template "${RELEASE_URL}" "${args[@]}")" |
| 192 | ) |
| 193 | generate_from_template "$(cat ${EMAIL_TEMPLATE_RELEASE})" "${args[@]}" |
| 194 | fi |
| 195 | } |
| 196 | |
| 197 | # Deploy a github release using a third party tool: |
| 198 | # https://github.com/c4milo/github-release |
| 199 | # This methods expects the following arguments: |
| 200 | # $1..$n files generated by package_build (should not contains the README file) |
| 201 | # Please set GITHUB_TOKEN to talk to the Github API and GITHUB_RELEASE |
| 202 | # for the path to the https://github.com/c4milo/github-release tool. |
| 203 | # 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] | 204 | # 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] | 205 | function release_to_github() { |
| 206 | local url="${GIT_REPOSITORY_URL}" |
| 207 | local release_name=$(get_release_name) |
| 208 | local rc=$(get_release_candidate) |
| 209 | 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] | 210 | local gpl_warning=" |
| 211 | |
| 212 | _Notice_: Bazel installers contain binaries licensed under the GPLv2 with |
| 213 | Classpath exception. Those installers should always be redistributed along with |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 214 | the source code. |
| 215 | |
| 216 | _Security_: All our binaries are signed with our |
Klaus Aehlig | baccf24 | 2016-10-28 17:37:35 +0000 | [diff] [blame] | 217 | [public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0. |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 218 | " |
Damien Martin-Guillerez | bf2e4ee | 2016-07-06 10:04:34 +0000 | [diff] [blame] | 219 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 220 | if [ ! -x "${release_tool}" ]; then |
| 221 | echo "Please set GITHUB_RELEASE to the path to the github-release binary." >&2 |
| 222 | echo "This probably means you haven't installed https://github.com/c4milo/github-release " >&2 |
| 223 | echo "on this machine." >&2 |
| 224 | return 1 |
| 225 | fi |
| 226 | local github_repo="$(echo "$url" | sed -E 's|https?://github.com/([^/]*/[^/]*).*$|\1|')" |
| 227 | if [ -n "${release_name}" ] && [ -z "${rc}" ]; then |
Damien Martin-Guillerez | 7e6351a | 2015-09-09 09:45:20 +0000 | [diff] [blame] | 228 | mkdir -p "${tmpdir}/to-github" |
| 229 | cp "${@}" "${tmpdir}/to-github" |
Damien Martin-Guillerez | bf2e4ee | 2016-07-06 10:04:34 +0000 | [diff] [blame] | 230 | "${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] | 231 | fi |
| 232 | } |
| 233 | |
| 234 | # Creates an index of the files contained in folder $1 in mardown format |
| 235 | function create_index_md() { |
| 236 | # First, add the README.md |
| 237 | local file=$1/__temp.md |
| 238 | if [ -f $1/README.md ]; then |
| 239 | cat $1/README.md |
| 240 | fi |
| 241 | # Then, add the list of files |
| 242 | echo |
| 243 | echo "## Index of files" |
| 244 | echo |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 245 | # Security notice |
| 246 | echo "_Security_: All our binaries are signed with our" |
Klaus Aehlig | baccf24 | 2016-10-28 17:37:35 +0000 | [diff] [blame] | 247 | echo "[public key](https://bazel.build/bazel-release.pub.gpg) 48457EE0." |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 248 | echo |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 249 | for f in $1/*.sha256; do # just list the sha256 ones |
| 250 | local filename=$(basename $f .sha256); |
Damien Martin-Guillerez | 671045b | 2016-10-11 14:17:28 +0000 | [diff] [blame] | 251 | echo " - [${filename}](${filename}) [[SHA-256](${filename}.sha256)] [[SIG](${filename}.sig)]" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 252 | done |
| 253 | } |
| 254 | |
| 255 | # Creates an index of the files contained in folder $1 in HTML format |
| 256 | # It supposes hoedown (https://github.com/hoedown/hoedown) is on the path, |
| 257 | # if not, set the HOEDOWN environment variable to the good path. |
| 258 | function create_index_html() { |
| 259 | local hoedown="${HOEDOWN:-$(which hoedown 2>/dev/null || true)}" |
| 260 | # Second line is to trick hoedown to behave as Github |
| 261 | create_index_md "${@}" \ |
| 262 | | sed -E 's/^(Baseline.*)$/\1\ |
Damien Martin-Guillerez | 697c61d | 2015-11-24 19:19:03 +0000 | [diff] [blame] | 263 | /' | sed 's/^ + / - /' | sed 's/_/\\_/g' \ |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 264 | | "${hoedown}" |
| 265 | } |
| 266 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 267 | function get_gsutil() { |
| 268 | local gs="${GSUTIL:-$(which gsutil 2>/dev/null || true) -m}" |
| 269 | if [ ! -x "${gs}" ]; then |
| 270 | echo "Please set GSUTIL to the path the gsutil binary." >&2 |
| 271 | echo "gsutil (https://cloud.google.com/storage/docs/gsutil/) is the" >&2 |
| 272 | echo "command-line interface to google cloud." >&2 |
| 273 | exit 1 |
| 274 | fi |
| 275 | echo "${gs}" |
| 276 | } |
| 277 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 278 | # Deploy a release candidate to Google Cloud Storage. |
| 279 | # It requires to have gsutil installed. You can force the path to gsutil |
| 280 | # by setting the GSUTIL environment variable. The GCS_BUCKET should be the |
| 281 | # name of the Google cloud bucket to deploy to. |
| 282 | # This methods expects the following arguments: |
| 283 | # $1..$n files generated by package_build |
| 284 | function release_to_gcs() { |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 285 | local gs="$(get_gsutil)" |
| 286 | local release_name="$(get_release_name)" |
| 287 | local rc="$(get_release_candidate)" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 288 | if [ -z "${GCS_BUCKET-}" ]; then |
| 289 | echo "Please set GCS_BUCKET to the name of your Google Cloud Storage bucket." >&2 |
| 290 | return 1 |
| 291 | fi |
| 292 | if [ -n "${release_name}" ] && [ -n "${rc}" ]; then |
| 293 | # Make a temporary folder with the desired structure |
| 294 | local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)" |
| 295 | local prev_dir="$PWD" |
| 296 | trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT |
| 297 | mkdir -p "${dir}/${release_name}/rc${rc}" |
| 298 | cp "${@}" "${dir}/${release_name}/rc${rc}" |
| 299 | # Add a index.html file: |
| 300 | create_index_html "${dir}/${release_name}/rc${rc}" \ |
| 301 | >"${dir}/${release_name}/rc${rc}"/index.html |
| 302 | cd ${dir} |
Laszlo Csomor | f17fb3a | 2016-11-24 11:01:33 +0000 | [diff] [blame] | 303 | "${gs}" cp -m -a public-read -r . "gs://${GCS_BUCKET}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 304 | cd "${prev_dir}" |
| 305 | rm -fr "${dir}" |
| 306 | trap - EXIT |
| 307 | fi |
| 308 | } |
| 309 | |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 310 | function ensure_gpg_secret_key_imported() { |
| 311 | (gpg --list-secret-keys | grep "${APT_GPG_KEY_ID}" > /dev/null) || \ |
| 312 | gpg --allow-secret-key-import --import "${APT_GPG_KEY_PATH}" |
Yun Peng | 2d1d492 | 2016-11-15 13:33:47 +0000 | [diff] [blame] | 313 | # Make sure we use stronger digest algorithm。 |
| 314 | # We use reprepro to generate the debian repository, |
| 315 | # but there's no way to pass flags to gpg using reprepro, so writting it into |
| 316 | # ~/.gnupg/gpg.conf |
| 317 | (grep "digest-algo sha256" ~/.gnupg/gpg.conf > /dev/null) || \ |
| 318 | echo "digest-algo sha256" >> ~/.gnupg/gpg.conf |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 319 | } |
| 320 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 321 | function create_apt_repository() { |
| 322 | mkdir conf |
| 323 | cat > conf/distributions <<EOF |
| 324 | Origin: Bazel Authors |
| 325 | Label: Bazel |
| 326 | Codename: stable |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 327 | Architectures: amd64 source |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 328 | Components: jdk1.7 jdk1.8 |
| 329 | Description: Bazel APT Repository |
| 330 | DebOverride: override.stable |
| 331 | DscOverride: override.stable |
| 332 | SignWith: ${APT_GPG_KEY_ID} |
| 333 | |
| 334 | Origin: Bazel Authors |
| 335 | Label: Bazel |
| 336 | Codename: testing |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 337 | Architectures: amd64 source |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 338 | Components: jdk1.7 jdk1.8 |
| 339 | Description: Bazel APT Repository |
| 340 | DebOverride: override.testing |
| 341 | DscOverride: override.testing |
| 342 | SignWith: ${APT_GPG_KEY_ID} |
| 343 | EOF |
| 344 | |
| 345 | cat > conf/options <<EOF |
| 346 | verbose |
| 347 | ask-passphrase |
| 348 | basedir . |
| 349 | EOF |
| 350 | |
| 351 | touch conf/override.stable |
| 352 | touch conf/override.testing |
| 353 | |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 354 | ensure_gpg_secret_key_imported |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 355 | |
| 356 | local distribution="$1" |
| 357 | local deb_pkg_name_jdk8="$2" |
| 358 | local deb_pkg_name_jdk7="$3" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 359 | local deb_dsc_name="$4" |
| 360 | |
| 361 | debsign -k ${APT_GPG_KEY_ID} "${deb_dsc_name}" |
| 362 | |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 363 | reprepro -C jdk1.8 includedeb "${distribution}" "${deb_pkg_name_jdk8}" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 364 | reprepro -C jdk1.8 includedsc "${distribution}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 365 | reprepro -C jdk1.7 includedeb "${distribution}" "${deb_pkg_name_jdk7}" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 366 | reprepro -C jdk1.7 includedsc "${distribution}" "${deb_dsc_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 367 | |
| 368 | "${gs}" -m cp -a public-read -r dists "gs://${GCS_APT_BUCKET}/" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 369 | "${gs}" -m cp -a public-read -r pool "gs://${GCS_APT_BUCKET}/" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 370 | } |
| 371 | |
| 372 | function release_to_apt() { |
| 373 | local gs="$(get_gsutil)" |
| 374 | local release_name="$(get_release_name)" |
| 375 | local rc="$(get_release_candidate)" |
| 376 | if [ -z "${GCS_APT_BUCKET-}" ]; then |
| 377 | echo "Please set GCS_APT_BUCKET to the name of your GCS bucket for apt repository." >&2 |
| 378 | return 1 |
| 379 | fi |
| 380 | if [ -z "${APT_GPG_KEY_ID-}" ]; then |
| 381 | echo "Please set APT_GPG_KEY_ID for apt repository." >&2 |
| 382 | return 1 |
| 383 | fi |
| 384 | if [ -n "${release_name}" ]; then |
| 385 | # Make a temporary folder with the desired structure |
| 386 | local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)" |
| 387 | local prev_dir="$PWD" |
| 388 | trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT |
| 389 | mkdir -p "${dir}/${release_name}" |
| 390 | local release_label="$(get_full_release_name)" |
| 391 | local deb_pkg_name_jdk8="${release_name}/bazel_${release_label}-linux-x86_64.deb" |
| 392 | local deb_pkg_name_jdk7="${release_name}/bazel_${release_label}-jdk7-linux-x86_64.deb" |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 393 | local deb_dsc_name="${release_name}/bazel_$(get_release_name).dsc" |
| 394 | local deb_tar_name="${release_name}/bazel_$(get_release_name).tar.gz" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 395 | cp "${tmpdir}/bazel_${release_label}-linux-x86_64.deb" "${dir}/${deb_pkg_name_jdk8}" |
| 396 | 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] | 397 | cp "${tmpdir}/bazel.dsc" "${dir}/${deb_dsc_name}" |
| 398 | cp "${tmpdir}/bazel.tar.gz" "${dir}/${deb_tar_name}" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 399 | cd "${dir}" |
| 400 | if [ -n "${rc}" ]; then |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 401 | 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] | 402 | else |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 403 | 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] | 404 | fi |
| 405 | cd "${prev_dir}" |
| 406 | rm -fr "${dir}" |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 407 | trap - EXIT |
| 408 | fi |
| 409 | } |
| 410 | |
| 411 | # A wrapper around the release deployment methods. |
| 412 | function deploy_release() { |
| 413 | local github_args=() |
| 414 | # Filters out README.md for github releases |
| 415 | for i in "$@"; do |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 416 | if ! ( [[ "$i" =~ README.md$ ]] || [[ "$i" =~ bazel.dsc ]] || [[ "$i" =~ bazel.tar.gz ]] ) ; then |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 417 | github_args+=("$i") |
| 418 | fi |
| 419 | done |
| 420 | release_to_github "${github_args[@]}" |
| 421 | release_to_gcs "$@" |
Yun Peng | 70b29f4 | 2016-05-24 18:04:37 +0000 | [diff] [blame] | 422 | release_to_apt |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 423 | } |
| 424 | |
| 425 | # A wrapper for the whole release phase: |
| 426 | # Compute the SHA-256, and arrange the input |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 427 | # Sign every binary using gpg and generating .sig files |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 428 | # Deploy the release |
| 429 | # Generate the email |
| 430 | # Input: $1 $2 [$3 $4 [$5 $6 ...]] |
| 431 | # Each pair denotes a couple (platform, folder) where the platform |
| 432 | # is the platform built for and the folder is the folder where the |
| 433 | # artifacts for this platform are. |
| 434 | # Ouputs: |
| 435 | # RELEASE_EMAIL_RECIPIENT: who to send a mail to |
| 436 | # RELEASE_EMAIL_SUBJECT: the subject of the email to be sent |
| 437 | # RELEASE_EMAIL_CONTENT: the content of the email to be sent |
| 438 | function bazel_release() { |
| 439 | local README=$2/README.md |
Damien Martin-Guillerez | 7e6351a | 2015-09-09 09:45:20 +0000 | [diff] [blame] | 440 | tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX) |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 441 | trap 'rm -fr ${tmpdir}' EXIT |
Yun Peng | 3d8ae22 | 2016-10-11 13:02:42 +0000 | [diff] [blame] | 442 | ensure_gpg_secret_key_imported |
| 443 | |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 444 | while (( $# > 1 )); do |
| 445 | local platform=$1 |
| 446 | local folder=$2 |
| 447 | shift 2 |
| 448 | for file in $folder/*; do |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 449 | local filename=$(basename $file) |
| 450 | if [ "$filename" != README.md ]; then |
Klaus Aehlig | 279a061 | 2016-11-11 09:51:44 +0000 | [diff] [blame] | 451 | if [ "$filename" == "bazel.dsc" ] || [ "$filename" == "bazel.tar.gz" ] \ |
Klaus Aehlig | e626f74 | 2016-11-23 14:18:30 +0000 | [diff] [blame] | 452 | || [[ "$filename" =~ bazel-(.*)-dist\.zip ]] ; then |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 453 | local destfile=${tmpdir}/$filename |
| 454 | elif [[ "$file" =~ /([^/]*)(\.[^\./]+)$ ]]; then |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 455 | local destfile=${tmpdir}/${BASH_REMATCH[1]}-${platform}${BASH_REMATCH[2]} |
| 456 | else |
Yun Peng | 55e042a | 2016-07-26 13:36:42 +0000 | [diff] [blame] | 457 | local destfile=${tmpdir}/$filename-${platform} |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 458 | fi |
Yun Peng | 6a3565e | 2016-10-26 11:54:40 +0000 | [diff] [blame] | 459 | # bazel.tar.gz is duplicated under different platforms |
| 460 | # if the file is already there, skip signing and checksum it again. |
| 461 | if [ ! -f "$destfile" ]; then |
| 462 | mv $file $destfile |
| 463 | checksum $destfile > $destfile.sha256 |
| 464 | gpg --no-tty --detach-sign -u "${APT_GPG_KEY_ID}" "$destfile" |
| 465 | fi |
Damien Martin-Guillerez | f7a3931 | 2015-08-17 08:32:09 +0000 | [diff] [blame] | 466 | fi |
| 467 | done |
| 468 | done |
| 469 | deploy_release $README $(find ${tmpdir} -type f) |
| 470 | |
| 471 | export RELEASE_EMAIL="$(generate_email)" |
| 472 | |
| 473 | export RELEASE_EMAIL_RECIPIENT="$(echo "${RELEASE_EMAIL}" | head -1)" |
| 474 | export RELEASE_EMAIL_SUBJECT="$(echo "${RELEASE_EMAIL}" | head -2 | tail -1)" |
| 475 | export RELEASE_EMAIL_CONTENT="$(echo "${RELEASE_EMAIL}" | tail -n +3)" |
| 476 | } |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 477 | |
| 478 | # Use jekyll build to build the site and then gsutil to copy it to GCS |
| 479 | # Input: $1 tarball to the jekyll site |
| 480 | # $2 name of the bucket to deploy the site to |
| 481 | # It requires to have gsutil installed. You can force the path to gsutil |
| 482 | # by setting the GSUTIL environment variable |
| 483 | function build_and_publish_site() { |
| 484 | tmpdir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX) |
| 485 | trap 'rm -fr ${tmpdir}' EXIT |
| 486 | local gs="$(get_gsutil)" |
| 487 | local site="$1" |
| 488 | local bucket="$2" |
| 489 | |
| 490 | if [ ! -f "${site}" ] || [ -z "${bucket}" ]; then |
| 491 | echo "Usage: build_and_publish_site <site-tarball> <bucket>" >&2 |
| 492 | return 1 |
| 493 | fi |
| 494 | tar xf "${site}" --exclude=CNAME -C "${tmpdir}" |
| 495 | jekyll build -s "${tmpdir}" -d "${tmpdir}/production" |
Damien Martin-Guillerez | d38ee63 | 2016-10-12 11:20:42 +0000 | [diff] [blame] | 496 | # Rsync: |
| 497 | # -r: recursive |
| 498 | # -c: compute checksum even though the input is from the filesystem |
| 499 | "${gs}" rsync -r -c "${tmpdir}/production" "gs://${bucket}" |
Damien Martin-Guillerez | 1164a4f | 2016-05-24 18:22:22 +0000 | [diff] [blame] | 500 | "${gs}" web set -m index.html -e 404.html "gs://${bucket}" |
| 501 | "${gs}" -m acl ch -R -u AllUsers:R "gs://${bucket}" |
| 502 | } |