From 5fabb43c4b5682616f8c9a7a5cc74f1ff6198c6e Mon Sep 17 00:00:00 2001 From: Philipp Wollermann Date: Tue, 27 Mar 2018 04:37:23 -0700 Subject: Simplify the release scripts in preparation of rewriting them in Python These are the scripts I'm currently using for the Bazel 0.12.0 release. Closes #4908. PiperOrigin-RevId: 190598268 --- scripts/ci/build.sh | 265 +++++++++-------- scripts/ci/windows/compile_windows.sh | 57 ---- scripts/release/BUILD | 44 --- scripts/release/common.sh | 99 ++----- scripts/release/release.sh | 264 +++++++++-------- scripts/release/release_test.sh | 528 ---------------------------------- scripts/release/relnotes.sh | 27 +- scripts/release/relnotes_test.sh | 267 ----------------- scripts/release/testenv.sh | 43 --- 9 files changed, 311 insertions(+), 1283 deletions(-) delete mode 100755 scripts/ci/windows/compile_windows.sh delete mode 100755 scripts/release/release_test.sh delete mode 100755 scripts/release/relnotes_test.sh delete mode 100755 scripts/release/testenv.sh (limited to 'scripts') diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index ffcd0ed3b3..a2e45130c7 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -24,22 +24,47 @@ set -eu # Also prepare an email for announcing the release. # Load common.sh -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -source $(dirname ${SCRIPT_DIR})/release/common.sh - -: ${GIT_REPOSITORY_URL:=https://github.com/bazelbuild/bazel} - -: ${GCS_BASE_URL:=https://storage.googleapis.com} -: ${GCS_BUCKET:=bucket-o-bazel} -: ${GCS_APT_BUCKET:=bazel-apt} - -: ${EMAIL_TEMPLATE_RC:=${SCRIPT_DIR}/rc_email.txt} -: ${EMAIL_TEMPLATE_RELEASE:=${SCRIPT_DIR}/release_email.txt} - -: ${RELEASE_CANDIDATE_URL:="https://releases.bazel.build/%release_name%/rc%rc%/index.html"} -: ${RELEASE_URL="${GIT_REPOSITORY_URL}/releases/tag/%release_name%"} - -: ${BOOTSTRAP_BAZEL:=bazel} +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$(dirname ${SCRIPT_DIR})/release/common.sh" + +if ! command -v gsutil &>/dev/null; then + echo "Required tool 'gsutil' not found. Please install it:" + echo "See https://cloud.google.com/sdk/downloads for instructions." + exit 1 +fi +if ! command -v github-release &>/dev/null; then + echo "Required tool 'github-release' not found. Download it from here:" + echo "https://github.com/c4milo/github-release/releases" + echo "Just extract the archive and put the binary on your PATH." + exit 1 +fi +if ! command -v debsign &>/dev/null; then + echo "Required tool 'debsign' not found. Please install it via apt-get:" + echo "apt-get install devscripts" + exit 1 +fi +if ! command -v reprepro &>/dev/null; then + echo "Required tool 'reprepro' not found. Please install it via apt-get:" + echo "apt-get install reprepro" + exit 1 +fi +if ! command -v gpg &>/dev/null; then + echo "Required tool 'gpg' not found. Please install it via apt-get:" + echo "apt-get install gnupg" + exit 1 +fi +if ! command -v pandoc &>/dev/null; then + echo "Required tool 'pandoc' not found. Please install it via apt-get:" + echo "apt-get install pandoc" + exit 1 +fi +# if ! command -v ssmtp &>/dev/null; then +# echo "Required tool 'ssmtp' not found. Please install it via apt-get:" +# echo "apt-get install ssmtp" +# exit 1 +# fi + +export APT_GPG_KEY_ID=$(gsutil cat gs://bazel-encrypted-secrets/release-key.gpg.id) # Generate a string from a template and a list of substitutions. # The first parameter is the template name and each subsequent parameter @@ -60,6 +85,9 @@ function generate_from_template() { # the mail subjects and the subsequent lines the mail, its content. # If no planed release, then this function output will be empty. function generate_email() { + RELEASE_CANDIDATE_URL="https://releases.bazel.build/%release_name%/rc%rc%/index.html" + RELEASE_URL="https://github.com/bazelbuild/bazel/releases/tag/%release_name%" + local release_name=$(get_release_name) local rc=$(get_release_candidate) local args=( @@ -69,16 +97,17 @@ function generate_email() { ) if [ -n "${rc}" ]; then args+=( - "%url%" - "$(generate_from_template "${RELEASE_CANDIDATE_URL}" "${args[@]}")" + "%url%" "$(generate_from_template "${RELEASE_CANDIDATE_URL}" "${args[@]}")" ) - generate_from_template "$(cat ${EMAIL_TEMPLATE_RC})" "${args[@]}" + generate_from_template \ + "$(cat "${SCRIPT_DIR}/rc_email.txt")" \ + "${args[@]}" elif [ -n "${release_name}" ]; then args+=( - "%url%" - "$(generate_from_template "${RELEASE_URL}" "${args[@]}")" + "%url%" "$(generate_from_template "${RELEASE_URL}" "${args[@]}")" ) - generate_from_template "$(cat ${EMAIL_TEMPLATE_RELEASE})" "${args[@]}" + generate_from_template \ + "$(cat "${SCRIPT_DIR}/release_email.txt")" "${args[@]}" fi } @@ -105,40 +134,25 @@ _Security_: All our binaries are signed with our # https://github.com/c4milo/github-release # This methods expects the following arguments: # $1..$n files generated by package_build (should not contains the README file) -# Please set GITHUB_TOKEN to talk to the Github API and GITHUB_RELEASE -# for the path to the https://github.com/c4milo/github-release tool. -# This method is also affected by GIT_REPOSITORY_URL which should be the -# URL to the github repository (defaulted to https://github.com/bazelbuild/bazel). +# Please set GITHUB_TOKEN to talk to the Github API. function release_to_github() { - local url="${GIT_REPOSITORY_URL}" + local artifact_dir="$1" + local release_name=$(get_release_name) local rc=$(get_release_candidate) - local release_tool="${GITHUB_RELEASE:-$(which github-release 2>/dev/null || echo release-tool-not-found)}" - if [ "${release_tool}" = "release-tool-not-found" ]; then - echo "Please set GITHUB_RELEASE to the path to the github-release binary." >&2 - echo "This probably means you haven't installed https://github.com/c4milo/github-release " >&2 - echo "on this machine." >&2 - return 1 - fi - local github_repo="$(echo "$url" | sed -E 's|https?://github.com/([^/]*/[^/]*).*$|\1|')" if [ -n "${release_name}" ] && [ -z "${rc}" ]; then - mkdir -p "${tmpdir}/to-github" - cp "${@}" "${tmpdir}/to-github" - "${release_tool}" "${github_repo}" "${release_name}" "" "$(get_release_page)" "${tmpdir}/to-github/"'*' + local github_token="$(gsutil cat gs://bazel-encrypted-secrets/github-token.enc | \ + gcloud kms decrypt --location global --keyring buildkite --key github-token --ciphertext-file - --plaintext-file -)" + + GITHUB_TOKEN=${github_token} github-release "bazelbuild/bazel" "${release_name}" "" "$(get_release_page)" "${artifact_dir}/*" fi } -# Creates an index of the files contained in folder $1 in mardown format +# Creates an index of the files contained in folder $1 in Markdown format. function create_index_md() { # First, add the release notes get_release_page - # Build log - if [ -f $1/build.log ]; then - echo - echo " [Build log](build.log)" - echo - fi # Then, add the list of files echo echo "## Index of files" @@ -149,74 +163,49 @@ function create_index_md() { done } -# Creates an index of the files contained in folder $1 in HTML format -# It supposes hoedown (https://github.com/hoedown/hoedown) is on the path, -# if not, set the HOEDOWN environment variable to the good path. +# Creates an index of the files contained in folder $1 in HTML format. function create_index_html() { - local hoedown="${HOEDOWN:-$(which hoedown 2>/dev/null || true)}" - # Second line is to trick hoedown to behave as Github - create_index_md "${@}" \ - | sed -E 's/^(Baseline.*)$/\1\ -/' | sed 's/^ + / - /' | sed 's/_/\\_/g' \ - | "${hoedown}" -} - -function get_gsutil() { - local gs="${GSUTIL:-$(which gsutil 2>/dev/null || true) -m}" - if [ ! -x "${gs}" ]; then - echo "Please set GSUTIL to the path the gsutil binary." >&2 - echo "gsutil (https://cloud.google.com/storage/docs/gsutil/) is the" >&2 - echo "command-line interface to google cloud." >&2 - exit 1 - fi - echo "${gs}" + create_index_md "${@}" | pandoc -f markdown -t html } # Deploy a release candidate to Google Cloud Storage. # It requires to have gsutil installed. You can force the path to gsutil -# by setting the GSUTIL environment variable. The GCS_BUCKET should be the -# name of the Google cloud bucket to deploy to. +# by setting the GSUTIL environment variable. # This methods expects the following arguments: # $1..$n files generated by package_build function release_to_gcs() { - local gs="$(get_gsutil)" + local artifact_dir="$1" + local release_name="$(get_release_name)" local rc="$(get_release_candidate)" - if [ -z "${GCS_BUCKET-}" ]; then - echo "Please set GCS_BUCKET to the name of your Google Cloud Storage bucket." >&2 - return 1 - fi + if [ -n "${release_name}" ]; then local release_path="${release_name}/release" if [ -n "${rc}" ]; then release_path="${release_name}/rc${rc}" fi - # Make a temporary folder with the desired structure - local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)" - local prev_dir="$PWD" - trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT - mkdir -p "${dir}/${release_path}" - cp "${@}" "${dir}/${release_path}" - # Add a index.html file: - create_index_html "${dir}/${release_path}" \ - >"${dir}/${release_path}"/index.html - cd ${dir} - "${gs}" -m cp -a public-read -r . "gs://${GCS_BUCKET}" - cd "${prev_dir}" - rm -fr "${dir}" - trap - EXIT + create_index_html "${artifact_dir}" > "${artifact_dir}/index.html" + gsutil -m cp -a public-read "${artifact_dir}/**" "gs://bazel/${release_path}" fi } function ensure_gpg_secret_key_imported() { - (gpg --list-secret-keys | grep "${APT_GPG_KEY_ID}" > /dev/null) || \ - gpg --allow-secret-key-import --import "${APT_GPG_KEY_PATH}" + if ! gpg --list-secret-keys | grep "${APT_GPG_KEY_ID}" > /dev/null; then + keyfile=$(mktemp --tmpdir) + chmod 0600 "${keyfile}" + gsutil cat "gs://bazel-encrypted-secrets/release-key.gpg.enc" | \ + gcloud kms decrypt --location "global" --keyring "buildkite" --key "bazel-release-key" --plaintext-file "-" --ciphertext-file "${keyfile}" + gpg --allow-secret-key-import --import "${keyfile}" + rm -f "${keyfile}" + fi + # Make sure we use stronger digest algorithm。 # We use reprepro to generate the debian repository, # but there's no way to pass flags to gpg using reprepro, so writting it into # ~/.gnupg/gpg.conf - (grep "digest-algo sha256" ~/.gnupg/gpg.conf > /dev/null) || \ - echo "digest-algo sha256" >> ~/.gnupg/gpg.conf + if ! grep "digest-algo sha256" ~/.gnupg/gpg.conf > /dev/null; then + echo "digest-algo sha256" >> ~/.gnupg/gpg.conf + fi } function create_apt_repository() { @@ -262,71 +251,79 @@ EOF ensure_gpg_secret_key_imported local distribution="$1" - local deb_pkg_name_jdk8="$2" + local deb_pkg_name="$2" local deb_dsc_name="$3" - debsign -k ${APT_GPG_KEY_ID} "${deb_dsc_name}" + debsign -k "${APT_GPG_KEY_ID}" "${deb_dsc_name}" - reprepro -C jdk1.8 includedeb "${distribution}" "${deb_pkg_name_jdk8}" + reprepro -C jdk1.8 includedeb "${distribution}" "${deb_pkg_name}" reprepro -C jdk1.8 includedsc "${distribution}" "${deb_dsc_name}" - "${gs}" -m cp -a public-read -r dists "gs://${GCS_APT_BUCKET}/" - "${gs}" -m cp -a public-read -r pool "gs://${GCS_APT_BUCKET}/" + gsutil -m cp -a public-read -r dists pool "gs://bazel-apt" } function release_to_apt() { - local gs="$(get_gsutil)" + local artifact_dir="$1" + local release_name="$(get_release_name)" local rc="$(get_release_candidate)" - if [ -z "${GCS_APT_BUCKET-}" ]; then - echo "Please set GCS_APT_BUCKET to the name of your GCS bucket for apt repository." >&2 - return 1 - fi - if [ -z "${APT_GPG_KEY_ID-}" ]; then - echo "Please set APT_GPG_KEY_ID for apt repository." >&2 - return 1 - fi + if [ -n "${release_name}" ]; then - # Make a temporary folder with the desired structure - local dir="$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXX)" - local prev_dir="$PWD" - trap "{ cd ${prev_dir}; rm -fr ${dir}; }" EXIT - mkdir -p "${dir}/${release_name}" local release_label="$(get_full_release_name)" - local deb_pkg_name_jdk8="${release_name}/bazel_${release_label}-linux-x86_64.deb" + local deb_pkg_name="${release_name}/bazel_${release_label}-linux-x86_64.deb" local deb_dsc_name="${release_name}/bazel_${release_label}.dsc" local deb_tar_name="${release_name}/bazel_${release_label}.tar.gz" - cp "${tmpdir}/bazel_${release_label}-linux-x86_64.deb" "${dir}/${deb_pkg_name_jdk8}" - cp "${tmpdir}/bazel.dsc" "${dir}/${deb_dsc_name}" - cp "${tmpdir}/bazel.tar.gz" "${dir}/${deb_tar_name}" - cd "${dir}" + + pushd "${artifact_dir}" if [ -n "${rc}" ]; then - create_apt_repository testing "${deb_pkg_name_jdk8}" "${deb_dsc_name}" + create_apt_repository testing "${deb_pkg_name}" "${deb_dsc_name}" else - create_apt_repository stable "${deb_pkg_name_jdk8}" "${deb_dsc_name}" + create_apt_repository stable "${deb_pkg_name}" "${deb_dsc_name}" fi - cd "${prev_dir}" - rm -fr "${dir}" - trap - EXIT + popd fi } # A wrapper around the release deployment methods. function deploy_release() { - local github_args=() - for i in "$@"; do - if ! ( [[ "$i" =~ build.log ]] || [[ "$i" =~ bazel.dsc ]] || [[ "$i" =~ bazel.tar.gz ]] || [[ "$i" =~ .nobuild$ ]] ) ; then - github_args+=("$i") - fi - done - local gcs_args=() - # Filters out perf.bazel.*.nobuild - for i in "$@"; do - if ! [[ "$i" =~ .nobuild$ ]] ; then - gcs_args+=("$i") - fi + local release_label="$(get_full_release_name)" + local release_name="$(get_release_name)" + + if [[ ! -d $1 ]]; then + echo "Usage: deploy_release ARTIFACT_DIR" + exit 1 + fi + artifact_dir="$1" + + if [[ -z $release_name ]]; then + echo "Could not get the release name - are you in a release branch directory?" + exit 1 + fi + + ensure_gpg_secret_key_imported + + rm -f "${artifact_dir}"/*.{sha256,sig} + for file in "${artifact_dir}"/*; do + (cd "${artifact_dir}" && sha256sum "$(basename "${file}")" > "${file}.sha256") + gpg --no-tty --detach-sign -u "${APT_GPG_KEY_ID}" "${file}" done - release_to_github "${github_args[@]}" - release_to_gcs "${gcs_args[@]}" - release_to_apt + + apt_working_dir="$(mktemp -d --tmpdir)" + echo "apt_working_dir = ${apt_working_dir}" + mkdir "${apt_working_dir}/${release_name}" + cp "${artifact_dir}/bazel_${release_label}-linux-x86_64.deb" "${apt_working_dir}/${release_name}" + cp "${artifact_dir}/bazel_${release_label}.dsc" "${apt_working_dir}/${release_name}" + cp "${artifact_dir}/bazel_${release_label}.tar.gz" "${apt_working_dir}/${release_name}" + release_to_apt "${apt_working_dir}" + + gcs_working_dir="$(mktemp -d --tmpdir)" + echo "gcs_working_dir = ${gcs_working_dir}" + cp "${artifact_dir}"/* "${gcs_working_dir}" + release_to_gcs "${gcs_working_dir}" + + github_working_dir="$(mktemp -d --tmpdir)" + echo "github_working_dir = ${github_working_dir}" + cp "${artifact_dir}"/* "${github_working_dir}" + rm -f "${github_working_dir}/bazel_${release_label}"*.{deb,dsc,tar.gz} + release_to_github "${github_working_dir}" } diff --git a/scripts/ci/windows/compile_windows.sh b/scripts/ci/windows/compile_windows.sh deleted file mode 100755 index ca2817a695..0000000000 --- a/scripts/ci/windows/compile_windows.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Ideally we would call directly script/ci/build.sh just like we do -# for the linux script but we are not there yet. - -# Ensure we are in the root directory -cd $(dirname $0)/../../.. - -# Even though there are no quotes around $* in the .bat file, arguments -# containing spaces seem to be passed properly. -source ./scripts/ci/build.sh - -# Bazel still needs to know where bash is, take it from cygpath. -export BAZEL_SH="$(cygpath --windows /bin/bash)" -# Make sure JAVA_HOME is in Windows path style. -export JAVA_HOME="$(cygpath --windows "${JAVA_HOME}")" - -# TODO(bazel-team): we should replace ./compile.sh by the same script we use -# for other platform -release_label="$(get_full_release_name)" - -if [ -n "${release_label}" ]; then - export EMBED_LABEL="${release_label}" -fi - -export MSYS_NO_PATHCONV=1 -export MSYS2_ARG_CONV_EXCL="*" - -echo "BOOTSTRAP_BAZEL version:" -${BOOTSTRAP_BAZEL} --bazelrc=${BAZELRC:-/dev/null} --nomaster_bazelrc version - -${BOOTSTRAP_BAZEL} --bazelrc=${BAZELRC:-/dev/null} --nomaster_bazelrc build \ - --embed_label=${release_label} --stamp \ - //src:bazel //src:bazel_with_jdk - -# Copy the resulting artifacts. -mkdir -p output/ci -cp bazel-bin/src/bazel output/ci/bazel-$(get_full_release_name)-without-jdk.exe -cp bazel-bin/src/bazel_with_jdk output/ci/bazel-$(get_full_release_name).exe -cp bazel-bin/src/bazel output/bazel.exe -zip -j output/ci/bazel-$(get_full_release_name)-without-jdk.zip output/bazel.exe -cp -f bazel-bin/src/bazel_with_jdk output/bazel.exe -zip -j output/ci/bazel-$(get_full_release_name).zip output/bazel.exe diff --git a/scripts/release/BUILD b/scripts/release/BUILD index d14dd24c97..e7fa5c6751 100644 --- a/scripts/release/BUILD +++ b/scripts/release/BUILD @@ -6,47 +6,3 @@ filegroup( srcs = glob(["**"]), visibility = ["//scripts:__pkg__"], ) - -sh_library( - name = "relnotes", - srcs = [ - "common.sh", - "relnotes.sh", - ], -) - -sh_test( - name = "relnotes_test", - srcs = ["relnotes_test.sh"], - data = [ - "testenv.sh", - "//:git", - "//src/test/shell:bashunit", - ], - shard_count = 2, - tags = ["need_git"], - deps = [ - ":relnotes", - ], -) - -sh_library( - name = "release", - srcs = [ - "release.sh", - ], - deps = [":relnotes"], -) - -sh_test( - name = "release_test", - srcs = ["release_test.sh"], - data = [ - "testenv.sh", - "//:git", - "//src/test/shell:bashunit", - ], - shard_count = 2, - tags = ["need_git"], - deps = [":release"], -) diff --git a/scripts/release/common.sh b/scripts/release/common.sh index 1b1a441bf1..6563b2eac9 100755 --- a/scripts/release/common.sh +++ b/scripts/release/common.sh @@ -29,6 +29,16 @@ set -eu # To follow tracks and to support how CI systems fetch the refs, we # store two commit notes: the release name and the candidate number. +# Get the short hash of a commit +function __git_commit_hash() { + git rev-parse "${1}" +} + +# Get the subject (first line of the commit message) of a commit +function __git_commit_subject() { + git show -s --pretty=format:%s "$@" +} + # Returns the branch name of the current git repository function git_get_branch() { git symbolic-ref --short HEAD @@ -49,16 +59,6 @@ function get_release_name() { git notes --ref=release show "$@" 2>/dev/null || true } -# Get the short hash of a commit -function git_commit_hash() { - git rev-parse "${1}" -} - -# Get the subject (first line of the commit message) of a commit -function git_commit_subject() { - git show -s --pretty=format:%s "$@" -} - # Get the list of commit hashes between two revisions function git_log_hash() { local baseline="$1" @@ -110,8 +110,8 @@ function wrap_text() { # + CHERRY_PICK1: commit message summary of the CHERRY_PICK1. This # message will be wrapped into 70 columns. # + CHERRY_PICK2: commit message summary of the CHERRY_PICK2. -function create_revision_information() { - echo "Baseline: $(git_commit_hash "${1}")" +function __create_revision_information() { + echo "Baseline: $(__git_commit_hash "${1}")" local first=1 shift while [ -n "${1-}" ]; do @@ -119,8 +119,8 @@ function create_revision_information() { echo -e "\nCherry picks:" first=0 fi - local hash="$(git_commit_hash "${1}")" - local subject="$(git_commit_subject $hash)" + local hash="$(__git_commit_hash "${1}")" + local subject="$(__git_commit_subject $hash)" local lines=$(echo "$subject" | wrap_text 65) # 5 leading spaces. echo " + $hash:" echo "$lines" | sed 's/^/ /' @@ -128,35 +128,11 @@ function create_revision_information() { done } -# Get the master commit -# Some machine might not have a "master" branch, use "origin/master" in that case -function get_master_ref() { - git rev-parse --verify master 2>/dev/null || git rev-parse --verify origin/master -} - # Get the baseline of master. -# Args: $1: release branch, default to HEAD +# Args: $1: release branch (or HEAD) +# TODO(philwo) this gives the wrong baseline when HEAD == release == master. function get_release_baseline() { - git merge-base $(get_master_ref) "${1:-HEAD}" -} - -# Returns the list of (commit hash, patch-id) from $1..$2 -# Args: -# $1: the first commit in the list (excluded) -# $2: the last commit in the list -function get_patch_ids() { - git_log_hash "$1" "$2" | xargs git show | git patch-id -} - -# Returns the original commit a commit was cherry-picked from master -# Args: -# $1: the commit to find -# $2: the baseline from which to look for (up to master) -# $3: master ref (optional, default master) -# $4: The list of master changes as returned by get_patch_ids (optional) -function get_cherrypick_origin() { - local master=${3:-$(get_master_ref)} - local master_changes="${4-$(get_patch_ids "${2}" "${master}")}" + git merge-base master "$1" } # Get the list of cherry-picks since master @@ -165,12 +141,11 @@ function get_cherrypick_origin() { # $2: baseline change, default to $(get_release_baseline $1) function get_cherrypicks() { local branch="${1:-HEAD}" - local master=$(get_master_ref) local baseline="${2:-$(get_release_baseline "${branch}")}" # List of changes since the baseline on the release branch local changes="$(git_log_hash "${baseline}" "${branch}" --reverse)" # List of changes since the baseline on the master branch, and their patch-id - local master_changes="$(git_log_hash "${baseline}" "${master}" | xargs git show | git patch-id)" + local master_changes="$(git_log_hash "${baseline}" master | xargs git show | git patch-id)" # Now for each changes on the release branch for i in ${changes}; do local hash=$(git notes --ref=cherrypick show "$i" 2>/dev/null || true) @@ -213,7 +188,7 @@ function generate_release_message() { if [ -n "${delimiter}" ]; then echo "${delimiter}" fi - create_revision_information $baseline $cherrypicks + __create_revision_information $baseline $cherrypicks if [ -n "${delimiter}" ]; then echo "${delimiter}" fi @@ -236,39 +211,3 @@ function get_full_release_notes() { git_commit_msg "$@" fi } - -# Merge three release notes using branch $1 as a base -# Args: -# $1 the branch name to use to play on -# $2 the new generated release notes -# $3 the last generated release notes -# $4 the last edited release notes -function merge_release_notes() { - local branch_name="$1" - local relnotes="$2" - local last_relnotes="$3" - local last_savedrelnotes="$4" - if [ "${last_relnotes}" == "${last_savedrelnotes}" ]; then - echo "${relnotes}" - else - # Merge the three release notes, use git merge for it - git checkout -q -b "${branch_name}-merge-notes-1" - echo "${last_relnotes}" >.relnotes - git add .relnotes - git commit -q -m "last_relnotes" --allow-empty - echo "${last_savedrelnotes}" >.relnotes - git add .relnotes - git commit -q -m "last_savedrelnotes" --allow-empty - git checkout -q -b "${branch_name}-merge-notes-2" HEAD~ - echo "${relnotes}" >.relnotes - git add .relnotes - git commit -q -m "relnotes" --allow-empty - git merge -q --no-commit "${branch_name}-merge-notes-1" &>/dev/null || true - cat .relnotes - - # Clean-up - git merge --abort || true &>/dev/null - git checkout -q "${branch_name}" - git branch -D ${branch_name}-merge-notes-{1,2} >/dev/null - fi -} diff --git a/scripts/release/release.sh b/scripts/release/release.sh index 3b18fd80c2..1e8cbfeb90 100755 --- a/scripts/release/release.sh +++ b/scripts/release/release.sh @@ -18,42 +18,73 @@ set -eu # Generate the release branches and handle the release tags. -# Repositories to push the release branch and the release tag. -: ${RELEASE_REPOSITORIES:="git@github.com:bazelbuild/bazel"} +# Name of the default editor. +: ${EDITOR=vi} -# Repositories to push the master branch -: ${MASTER_REPOSITORIES:="https://bazel.googlesource.com/bazel"} +# Repositories to push the release branch and the release tag. +RELEASE_REPOSITORY="git@github.com:bazelbuild/bazel" -# Name of the default editor -: ${EDITOR=vi} +# Repositories to push the master branch. +MASTER_REPOSITORY="https://bazel.googlesource.com/bazel" -# Author of the release commits -: ${RELEASE_AUTHOR="Bazel Release System "} +# Author of the release commits. +RELEASE_AUTHOR="Bazel Release System " -# Load relnotes.sh +# Load relnotes.sh. SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) source ${SCRIPT_DIR}/relnotes.sh -# Load common.sh +# Load common.sh. source ${SCRIPT_DIR}/common.sh -# Editing release notes info for the user +# Editing release notes info for the user. RELEASE_NOTE_MESSAGE='# Editing release notes # Modify the release notes to make them suitable for the release. # Every line starting with a # will be removed as well as every # empty line at the start and at the end. ' -# Fetch everything from remote repositories to avoid conflicts -function fetch() { - for i in ${RELEASE_REPOSITORIES}; do - git fetch -f $i &>/dev/null || true - git fetch -f $i refs/notes/*:refs/notes/* &>/dev/null || true - done +# Merge three release notes using branch $1 as a base. +# Args: +# $1 the branch name to use to play on +# $2 the new generated release notes +# $3 the last generated release notes +# $4 the last edited release notes +function __merge_release_notes() { + local branch_name="$1" + local relnotes="$2" + local last_relnotes="$3" + local last_savedrelnotes="$4" + if [ "${last_relnotes}" == "${last_savedrelnotes}" ]; then + echo "${relnotes}" + else + # Merge the three release notes using "git merge". + git checkout -q -b "${branch_name}-merge-notes-1" + echo "${last_relnotes}" >.relnotes + git add .relnotes + git commit -q -m "last_relnotes" --allow-empty + + echo "${last_savedrelnotes}" >.relnotes + git add .relnotes + git commit -q -m "last_savedrelnotes" --allow-empty + git checkout -q -b "${branch_name}-merge-notes-2" HEAD~ + + echo "${relnotes}" >.relnotes + git add .relnotes + git commit -q -m "relnotes" --allow-empty + + git merge -q --no-commit "${branch_name}-merge-notes-1" &>/dev/null || true + cat .relnotes + + # Clean-up + git merge --abort || true &>/dev/null + git checkout -q "${branch_name}" + git branch -D ${branch_name}-merge-notes-{1,2} >/dev/null + fi } -# Set the release name $1 (and eventually the candidate number $2). -function set_release_name() { +# Set the release name to $1 (and eventually the candidate number to $2). +function __set_release_name() { git notes --ref=release remove 2>/dev/null || true git notes --ref=release-candidate remove 2>/dev/null || true git notes --ref=release append -m "$1" @@ -63,63 +94,59 @@ function set_release_name() { } # Trim empty lines at the beginning and the end of the buffer. -function trim_empty_lines() { - local f="$(echo $'\f')" # linefeed because OSX sed does not support \f +function __trim_empty_lines() { # Replace all new line by a linefeed, then using sed, remove the leading # and trailing linefeeds and convert them back to newline - tr '\n' '\f' | sed -e "s/^$f*//" -e "s/$f*$//" | tr '\f' '\n' + tr '\n' '\f' | sed -e "s/^\f*//" -e "s/\f*$//" | tr '\f' '\n' } -# Launch the editor and return the edited release notes -function release_note_editor() { +# Launch the editor and return the edited release notes. +function __release_note_editor() { local tmpfile="$1" local branch_name="${2-}" + $EDITOR ${tmpfile} || { echo "Editor failed, cancelling release creation..." >&2 return 1 } - # Stripping the release notes - local relnotes="$(cat ${tmpfile} | grep -v '^#' | trim_empty_lines)" + + # Strip the release notes. + local relnotes="$(cat ${tmpfile} | grep -v '^#' | __trim_empty_lines)" if [ -z "${relnotes}" ]; then echo "Release notes are empty, cancelling release creation..." >&2 return 1 fi - echo "${relnotes}" >${tmpfile} + + echo "${relnotes}" > "${tmpfile}" } # Create the release commit by changing the CHANGELOG file -function create_release_commit() { +function __create_release_commit() { local infos=$(generate_release_message "${1}" HEAD '```') local changelog_path="$PWD/CHANGELOG.md" - local master=$(get_master_ref) - # Get the changelog from master to avoid missing release notes - # from release that were in-between - git checkout -q ${master} CHANGELOG.md || true + # Get the CHANGELOG.md from master to avoid missing release notes from release + # that were in-between. + git checkout master CHANGELOG.md # CHANGELOG.md - local tmpfile="$(mktemp ${TMPDIR:-/tmp}/relnotes-XXXXXXXX)" - trap "rm -f ${tmpfile}" EXIT - echo -n "## ${infos}" >${tmpfile} - if [ -f "${changelog_path}" ]; then - { - echo - echo - cat "${changelog_path}" - echo - } >> ${tmpfile} - fi - cat "${tmpfile}" > ${changelog_path} - git add ${changelog_path} - rm -f "${tmpfile}" - trap - EXIT + local tmpfile="$(mktemp --tmpdir relnotes-XXXXXXXX)" + { + echo -n "## ${infos}" + echo + echo + cat "${changelog_path}" + echo + } >> ${tmpfile} + mv "${tmpfile}" "${changelog_path}" + git add "${changelog_path}" # Commit infos="$(echo "${infos}" | grep -Ev '^```$')" git commit --no-verify -m "${infos}" --no-edit --author "${RELEASE_AUTHOR}" } -function apply_cherry_picks() { +function __apply_cherry_picks() { echo "Applying cherry-picks" # Apply cherry-picks for commit in "$@"; do @@ -142,10 +169,9 @@ function apply_cherry_picks() { return 0 } -# Find out the last release since the fork between "${1:-HEAD}" from master. -function find_last_release() { - local branch="${1:-HEAD}" - local baseline="${2:-$(get_release_baseline "${branch}")}" +# Find out the last release since the fork between HEAD from master. +function __find_last_release() { + local baseline="${1:-$(get_release_baseline "HEAD")}" local changes="$(git log --pretty=format:%H "${baseline}~".."${branch}")" for change in ${changes}; do if git notes --ref=release show ${change} &>/dev/null; then @@ -157,7 +183,7 @@ function find_last_release() { # Execute the create command: # Create a new release named "$1" with "$2" as the baseline commit. -function create_release() { +function __create_release() { local force_rc= if [[ "$1" =~ ^--force_rc=([0-9]*)$ ]]; then force_rc=${BASH_REMATCH[1]} @@ -166,23 +192,24 @@ function create_release() { local release_name="$1" local baseline="$2" shift 2 - local origin_branch=$(git_get_branch) local branch_name="release-${release_name}" - fetch + # Fetch everything from remote repositories to avoid conflicts + git fetch -f "${RELEASE_REPOSITORY}" + git fetch -f "${RELEASE_REPOSITORY}" 'refs/notes/*:refs/notes/*' local last_release="$(git rev-parse --verify "${branch_name}" 2>/dev/null || true)" echo "Creating new release branch ${branch_name} for release ${release_name}" git checkout -B ${branch_name} ${baseline} - apply_cherry_picks $@ || { - git checkout ${origin_branch} + __apply_cherry_picks $@ || { + git checkout master git branch -D ${branch_name} exit 1 } - setup_git_notes "${force_rc}" "${release_name}" "${last_release}" || { - git checkout ${origin_branch} + __setup_git_notes "${force_rc}" "${release_name}" "${last_release}" || { + git checkout master git branch -D ${branch_name} exit 1 } @@ -203,16 +230,16 @@ function create_release() { # last release candidate or the branch name, e.g. if the branch # name is release-v1, then the name will be 'v1'). # $3: (optional) Specify the commit for last release. -function setup_git_notes() { +function __setup_git_notes() { local force_rc="$1" local branch_name="$(git_get_branch)" # Figure out where we are in release: find the rc, the baseline, cherrypicks # and release name. local rc=${force_rc:-1} - local baseline="$(get_release_baseline)" + local baseline="$(get_release_baseline "HEAD")" local cherrypicks="$(get_cherrypicks "HEAD" "${baseline}")" - local last_release="${3-$(find_last_release "HEAD" "${baseline}")}" + local last_release="${3-$(__find_last_release "${baseline}")}" local release_name="${2-}" if [ -n "${last_release}" ]; then if [ -z "${force_rc}" ]; then @@ -232,13 +259,14 @@ function setup_git_notes() { fi # Edit the release notes - local tmpfile=$(mktemp ${TMPDIR:-/tmp}/relnotes-XXXXXXXX) + local tmpfile=$(mktemp --tmpdir relnotes-XXXXXXXX) trap "rm -f ${tmpfile}" EXIT echo "Creating release notes" # Save the changelog so we compute the relnotes against HEAD. - git show master:CHANGELOG.md >${tmpfile} 2>/dev/null || echo >${tmpfile} + git show master:CHANGELOG.md > "${tmpfile}" + # Compute the new release notes local relnotes="$(create_release_notes "${tmpfile}" "${baseline}" ${cherrypicks})" @@ -250,66 +278,63 @@ function setup_git_notes() { local last_relnotes="$(create_release_notes "${tmpfile}")" git checkout -q "${branch_name}" local last_savedrelnotes="$(get_release_notes "${last_release}")" - relnotes="$(merge_release_notes "${branch_name}" "${relnotes}" \ + relnotes="$(__merge_release_notes "${branch_name}" "${relnotes}" \ "${last_relnotes}" "${last_savedrelnotes}")" fi - echo "${RELEASE_NOTE_MESSAGE}" > ${tmpfile} - echo "# $(get_release_title "${release_name}rc${rc}")" >> ${tmpfile} - echo >> ${tmpfile} - echo "${relnotes}" >>"${tmpfile}" - release_note_editor ${tmpfile} "${branch_name}" || return 1 + + echo "${RELEASE_NOTE_MESSAGE}" > "${tmpfile}" + echo "# $(get_release_title "${release_name}rc${rc}")" >> "${tmpfile}" + echo >> "${tmpfile}" + echo "${relnotes}" >> "${tmpfile}" + + __release_note_editor "${tmpfile}" "${branch_name}" || return 1 relnotes="$(cat ${tmpfile})" - # Add the git notes - set_release_name "${release_name}" "${rc}" + # Add the git notes. + git notes --ref=release add -f -m "${release_name}" + git notes --ref=release-candidate add -f -m "${rc}" git notes --ref=release-notes add -f -m "${relnotes}" - # Clean-up - rm -f ${tmpfile} + # Clean-up. + rm -f "${tmpfile}" trap - EXIT } # Force push a ref $2 to repo $1 if exists -function push_if_exists() { +function __push_if_exists() { if git show-ref -q "${2}"; then git push -f "${1}" "+${2}" fi } # Push release notes refs but also a given ref -function push_notes_and_ref() { +function __push_notes_and_ref() { local ref="$1" - for repo in ${RELEASE_REPOSITORIES}; do - push_if_exists "${repo}" "${ref}" - push_if_exists "${repo}" "refs/notes/release" - push_if_exists "${repo}" "refs/notes/release-candidate" - push_if_exists "${repo}" "refs/notes/release-notes" - push_if_exists "${repo}" "refs/notes/cherrypick" - done + __push_if_exists "${RELEASE_REPOSITORY}" "${ref}" + __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release" + __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release-candidate" + __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release-notes" + __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/cherrypick" } # Push the release branch to the release repositories so a release # candidate can be created. -function push_release_candidate() { - push_notes_and_ref "$(get_release_branch)" +function __push_release_candidate() { + __push_notes_and_ref "$(get_release_branch)" } # Deletes the release branch after a release or abandoning the release -function cleanup_branches() { +function __cleanup_branches() { local tag_name=$1 - local i echo "Destroying the release branches for release ${tag_name}" - # Destroy branch, ignoring if it doesn't exist. - git branch -D release-${tag_name} &>/dev/null || true - for i in $RELEASE_REPOSITORIES; do - git push -f $i :release-${tag_name} &>/dev/null || true - done + git branch -D "release-${tag_name}" &>/dev/null || true + git push -f "${RELEASE_REPOSITORY}" ":release-${tag_name}" &>/dev/null || true } # Releases the current release branch, creating the necessary tag, # destroying the release branch, updating the master's CHANGELOG.md # and pushing everything to GitHub. -function do_release() { +function __do_release() { local branch=$(get_release_branch) local tag_name=$(get_release_name) @@ -317,52 +342,55 @@ function do_release() { read answer if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then echo "Creating the release commit" - create_release_commit "${tag_name}" - set_release_name "${tag_name}" + __create_release_commit "${tag_name}" + __set_release_name "${tag_name}" + git notes --ref=release add -f -m "${tag_name}" + git notes --ref=release-candidate remove || true + echo "Creating the tag" git tag ${tag_name} echo "Cherry-picking CHANGELOG.md modification into master" git checkout master + # Ensuring we are up to date for master - git pull --rebase $(echo "$MASTER_REPOSITORIES" | cut -d " " -f 1) master + git pull --rebase "$MASTER_REPOSITORY" master + # We do not cherry-pick because we might have conflict if the baseline # does not contains the latest CHANGELOG.md file, so trick it. local changelog_path="$PWD/CHANGELOG.md" - git show ${branch}:CHANGELOG.md >${changelog_path} - local tmpfile=$(mktemp ${TMPDIR:-/tmp}/relnotes-XXXXXXXX) + git show "${branch}:CHANGELOG.md" > "${changelog_path}" + local tmpfile=$(mktemp --tmpdir relnotes-XXXXXXXX) trap 'rm -f ${tmpfile}' EXIT - git_commit_msg ${branch} >${tmpfile} - git add ${changelog_path} - git commit --no-verify -F ${tmpfile} --no-edit --author "${RELEASE_AUTHOR}" - rm -f ${tmpfile} + git_commit_msg "${branch}" > "${tmpfile}" + git add "${changelog_path}" + git commit --no-verify -F "${tmpfile}" --no-edit --author "${RELEASE_AUTHOR}" + rm -f "${tmpfile}" trap - EXIT echo "Pushing the change to remote repositories" - for i in $MASTER_REPOSITORIES; do - git push $i +master - done - push_notes_and_ref "refs/tags/${tag_name}" - cleanup_branches ${tag_name} + git push "${MASTER_REPOSITORY}" +master + __push_notes_and_ref "refs/tags/${tag_name}" + __cleanup_branches "${tag_name}" fi } # Abandon the current release, deleting the branch on the local # repository and on GitHub, discarding all changes -function abandon_release() { +function __abandon_release() { local branch_info=$(get_release_branch) local tag_name=$(get_release_name) echo -n "You are about to abandon release ${tag_name}, confirm? [y/N] " read answer if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then - git notes --ref=release remove 2>/dev/null || true - git notes --ref=release-candidate remove 2>/dev/null || true + git notes --ref=release remove || true + git notes --ref=release-candidate remove || true git checkout -q master >/dev/null - cleanup_branches ${tag_name} + __cleanup_branches ${tag_name} fi } -function usage() { +function __usage() { cat >&2 <= 2 )) || usage $progname - create_release "$@" + __create_release "$@" ;; push) - push_release_candidate + __push_release_candidate ;; release) - do_release + __do_release ;; generate-rc) force_rc= @@ -432,12 +460,12 @@ case $cmd in force_rc=${BASH_REMATCH[1]} shift 1 fi - setup_git_notes "${force_rc}" + __setup_git_notes "${force_rc}" ;; abandon) - abandon_release + __abandon_release ;; *) - usage $progname + __usage $progname ;; esac diff --git a/scripts/release/release_test.sh b/scripts/release/release_test.sh deleted file mode 100755 index dfa9fe856c..0000000000 --- a/scripts/release/release_test.sh +++ /dev/null @@ -1,528 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Tests release notes generation (relnotes.sh) -set -eu - -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -source ${SCRIPT_DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; } - -source ${SCRIPT_DIR}/common.sh || { echo "common.sh not found!" >&2; exit 1; } - -RELEASE_SCRIPT=${SCRIPT_DIR}/release.sh - -GERRIT_ROOT=${TEST_TMPDIR}/git/gerrit -GITHUB_ROOT=${TEST_TMPDIR}/git/github -WORKSPACE=${TEST_TMPDIR}/git/workspace -export RELEASE_REPOSITORIES="${GITHUB_ROOT}" -export MASTER_REPOSITORIES="${GITHUB_ROOT} ${GERRIT_ROOT}" - -setup_git_repository - -function set_up() { - # Clean previous clones - rm -fr ${GERRIT_ROOT} ${GITHUB_ROOT} ${WORKSPACE} - # Now creates the clones - git clone -l --bare -q ${MASTER_ROOT} ${GERRIT_ROOT} - git clone -l --bare -q ${MASTER_ROOT} ${GITHUB_ROOT} - # And the working copy - git clone -l -q ${GERRIT_ROOT} ${WORKSPACE} - cd ${WORKSPACE} - # Avoid committer message - cat >>.git/config < $TEST_log \ - || fail "Failed to cut release $name at commit $commit" - local new_branch=$(git_get_branch) - assert_equals "release-$name" "$new_branch" - assert_contains "Created $name.* on branch release-$name." $TEST_log - get_full_release_notes "release-$name" >$TEST_log -} - -function push() { - local branch="release-$1" - git checkout "$branch" - ${RELEASE_SCRIPT} push || fail "Failed to push release branch $branch" - git --git-dir=${GITHUB_ROOT} branch >$TEST_log - expect_log "$branch" - git --git-dir=${GERRIT_ROOT} branch >$TEST_log - expect_not_log "$branch" - assert_equals "$(git show -s --pretty=format:%B $branch)" \ - "$(git --git-dir=${GITHUB_ROOT} show -s --pretty=format:%B $branch)" -} - -function release() { - local tag=$1 - local branch=$(git_get_branch) - echo y | ${RELEASE_SCRIPT} release || fail "Failed to release ${branch}" - assert_equals master "$(git_get_branch)" - git tag >$TEST_log - expect_log $tag - git --git-dir=${GITHUB_ROOT} tag >$TEST_log - expect_log $tag - git --git-dir=${GERRIT_ROOT} tag >$TEST_log - expect_not_log $tag - # Test commit is everywhere - local commit="$(git show -s --pretty=format:%B $tag)" - assert_equals "$commit" "$(git show -s --pretty=format:%B master)" - assert_equals "$commit" \ - "$(git --git-dir=${GITHUB_ROOT} show -s --pretty=format:%B $tag)" - assert_equals "$commit" \ - "$(git --git-dir=${GITHUB_ROOT} show -s --pretty=format:%B master)" - assert_equals "$commit" \ - "$(git --git-dir=${GERRIT_ROOT} show -s --pretty=format:%B master)" - - # Now test for CHANGELOG.md file in master branch - local changelog="$(git show $tag:CHANGELOG.md)" - assert_equals "$changelog" "$(git show master:CHANGELOG.md)" - assert_equals "$changelog" \ - "$(git --git-dir=${GITHUB_ROOT} show $tag:CHANGELOG.md)" - assert_equals "$changelog" \ - "$(git --git-dir=${GITHUB_ROOT} show master:CHANGELOG.md)" - assert_equals "$changelog" \ - "$(git --git-dir=${GERRIT_ROOT} show master:CHANGELOG.md)" - -} - -function abandon() { - local tag="$1" - local branch="release-$tag" - git checkout "$branch" - local changelog="$(git show master:CHANGELOG.md || true)" - local master_sha1=$(git rev-parse master) - echo y | ${RELEASE_SCRIPT} abandon || fail "Failed to abandon release ${branch}" - assert_equals master "$(git_get_branch)" - - # test release was not tagged - git tag >$TEST_log - expect_not_log $tag - git --git-dir=${GITHUB_ROOT} tag >$TEST_log - expect_not_log $tag - git --git-dir=${GERRIT_ROOT} tag >$TEST_log - expect_not_log $tag - - # Test branch was deleted - git branch >$TEST_log - expect_not_log $branch - git --git-dir=${GITHUB_ROOT} branch >$TEST_log - expect_not_log $branch - - # Test the master branch commit hasn't changed - assert_equals "$(git rev-parse master)" "${master_sha1}" - - # Now test for CHANGELOG.md file in master branch hasn't changed - assert_equals "$changelog" "$(git show master:CHANGELOG.md)" - assert_equals "$changelog" \ - "$(git --git-dir=${GITHUB_ROOT} show master:CHANGELOG.md)" - assert_equals "$changelog" \ - "$(git --git-dir=${GERRIT_ROOT} show master:CHANGELOG.md)" - -} - -function test_merge_release_notes() { - local RELNOTES='Incompatible changes: - - - Remove deprecated "make var" INCDIR - -Important changes: - - - Use a default implementation of a progress message, rather than - defaulting to null for all SpawnActions.' - local NEW_RELNOTES="${RELNOTES}"' - - Attribute error messages related to Android resources are easier - to understand now.' - local REPLACEMENT="Test replacement." - - assert_equals '<<<<<<< HEAD -Incompatible changes: - - - Remove deprecated "make var" INCDIR - -Important changes: - - - Use a default implementation of a progress message, rather than - defaulting to null for all SpawnActions. - - Attribute error messages related to Android resources are easier - to understand now. -======= -Test replacement. ->>>>>>> master-merge-notes-1' "$(merge_release_notes master "${NEW_RELNOTES}" "${RELNOTES}" "${REPLACEMENT}")" - - assert_equals "${NEW_RELNOTES}" \ - "$(merge_release_notes master "${NEW_RELNOTES}" "${RELNOTES}" "${RELNOTES}")" - - assert_equals "${RELNOTES}"' -<<<<<<< HEAD - - Attribute error messages related to Android resources are easier - to understand now. -======= - - Merge conflict. ->>>>>>> master-merge-notes-1' "$(merge_release_notes master "${NEW_RELNOTES}" "${RELNOTES}" "${RELNOTES} - - Merge conflict.")" - -} - -function test_release_workflow() { - export EDITOR=true - # Initial release - create v0 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - expect_log "Release v0rc1" - expect_log "Initial release" - # Push the release branch - push v0 - # Do the initial release - release v0 - - CHANGELOG='## Release v0 ('$(date +%Y-%m-%d)') - -``` -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e -``` - -Initial release.' - assert_equals "${CHANGELOG}" "$(${TEST_TMPDIR}/expected.log <${TEST_TMPDIR}/replacement.log - - cat >${EDITOR} <&2 - cat ${TEST_TMPDIR}/expected.log >&2 - echo "Got:" >&2 - cat \$1 >&2 - exit 1 -fi - -# 2. write the replacement in the input file -cat ${TEST_TMPDIR}/replacement.log >\$1 -EOF - chmod +x ${EDITOR} - create v1 1170dc6055ed0d669275efb1ab1906d2715ad1c3 \ - 0540fdefe2c27605516a772c2a224d579db0a74d - local header='Release v1rc1 ('$(date +%Y-%m-%d)') - -Baseline: 1170dc6055ed0d669275efb1ab1906d2715ad1c3 - -Cherry picks: - + 0540fdefe2c27605516a772c2a224d579db0a74d: - Extract version numbers that look like "..._1.2.3_..." from - BUILD_EMBED_LABEL into Info.plist. - -' - assert_equals "${header}Test replacement" "$(cat ${TEST_log})" - assert_equals "Test replacement" "$(get_release_notes release-v1)" - assert_equals 1 "$(get_release_candidate release-v1)" - push v1 - - # Test creating a second candidate - RELNOTES="${RELNOTES}"' - - Attribute error messages related to Android resources are easier - to understand now.' - - # There should be a merge conflict - cat >${TEST_TMPDIR}/expected.log <>>>>>> release-v1-merge-notes-1 -EOF - echo "${RELNOTES}" >${TEST_TMPDIR}/replacement.log - - create v1 1170dc6055ed0d669275efb1ab1906d2715ad1c3 \ - 0540fdefe2c27605516a772c2a224d579db0a74d \ - cef25c44bc6c2ae8e5bd649228a9a9c39f057576 - title='Release v1rc2 ('$(date +%Y-%m-%d)')' - revision_info='Baseline: 1170dc6055ed0d669275efb1ab1906d2715ad1c3 - -Cherry picks: - + 0540fdefe2c27605516a772c2a224d579db0a74d: - Extract version numbers that look like "..._1.2.3_..." from - BUILD_EMBED_LABEL into Info.plist. - + cef25c44bc6c2ae8e5bd649228a9a9c39f057576: - RELNOTES: Attribute error messages related to Android resources - are easier to understand now.' - header="${title} - -${revision_info} - -" - assert_equals "${header}${RELNOTES}" "$(cat ${TEST_log})" - assert_equals "${RELNOTES}" "$(get_release_notes release-v1)" - assert_equals 2 "$(get_release_candidate release-v1)" - - # Push the release - push v1 - release v1 - title='Release v1 ('$(date +%Y-%m-%d)')' - CHANGELOG='## '"${title}"' - -``` -'"${revision_info}"' -``` - -'"${RELNOTES}"' - -'"${CHANGELOG}" - assert_equals "${CHANGELOG}" "$(${EDITOR} <\$1 -EOF - # Create release - create --force_rc=2 v2 2464526 - expect_log "Release v2rc2" - expect_log "Baseline: 2464526" - assert_equals 2 "$(get_release_candidate release-v2)" - # Abandon it - abandon v2 - # Add a commit hook to test if it is ignored - cat <<'EOF' >.git/hooks/commit-msg -echo HOOK-SHOULD-BE-IGNORED >>$1 -EOF - chmod +x .git/hooks/commit-msg - # Re-create release - create v2 2464526 - expect_log "Release v2rc1" - expect_log "Baseline: 2464526" - expect_not_log "HOOK-SHOULD-BE-IGNORED" - # Push - push v2 - # Abandon it - abandon v2 -} - -function generate_rc() { - local force_rc= - if [[ "$1" =~ ^--force_rc=[0-9]+$ ]]; then - force_rc="$1" - shift - fi - local name="$1" - shift - if (git rev-parse --verify "release-$name" &>/dev/null); then - git checkout release-"$name" - else - git checkout -b release-"$name" $1 - shift - fi - for i in "$@"; do - git cherry-pick $i - done - ${RELEASE_SCRIPT} generate-rc $force_rc &> $TEST_log \ - || fail "Failed to cut release $name" - get_full_release_notes "release-$name" >$TEST_log - git checkout master -} - -# Same test as before with the workflow for the git user -function test_git_release_workflow() { - export EDITOR=true - # Initial release - generate_rc v0 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - - expect_log "Release v0rc1" - expect_log "Initial release" - # Push the release branch - push v0 - # Do the initial release - release v0 - - # Second release. - - # First we need to edit the logs - export EDITOR=${TEST_TMPDIR}/editor.sh - local RELNOTES='Incompatible changes: - - - Remove deprecated "make var" INCDIR - -Important changes: - - - Use a default implementation of a progress message, rather than - defaulting to null for all SpawnActions.' - - cat >${TEST_TMPDIR}/expected.log <${TEST_TMPDIR}/replacement.log - - cat >${EDITOR} <&2 - cat ${TEST_TMPDIR}/expected.log >&2 - echo "Got:" >&2 - cat \$1 >&2 - exit 1 -fi - -# 2. write the replacement in the input file -cat ${TEST_TMPDIR}/replacement.log >\$1 -EOF - chmod +x ${EDITOR} - generate_rc v1 1170dc6055ed0d669275efb1ab1906d2715ad1c3 \ - 0540fdefe2c27605516a772c2a224d579db0a74d - local header='Release v1rc1 ('$(date +%Y-%m-%d)') - -Baseline: 1170dc6055ed0d669275efb1ab1906d2715ad1c3 - -Cherry picks: - + 0540fdefe2c27605516a772c2a224d579db0a74d: - Extract version numbers that look like "..._1.2.3_..." from - BUILD_EMBED_LABEL into Info.plist. - -' - assert_equals "${header}Test replacement" "$(cat ${TEST_log})" - assert_equals "Test replacement" "$(get_release_notes release-v1)" - assert_equals 1 "$(get_release_candidate release-v1)" - push v1 - - # Test creating a second candidate - RELNOTES="${RELNOTES}"' - - Attribute error messages related to Android resources are easier - to understand now.' - - # There should be a merge conflict - cat >${TEST_TMPDIR}/expected.log <>>>>>> release-v1-merge-notes-1 -EOF - echo "${RELNOTES}" >${TEST_TMPDIR}/replacement.log - - generate_rc v1 cef25c44bc6c2ae8e5bd649228a9a9c39f057576 - header='Release v1rc2 ('$(date +%Y-%m-%d)') - -Baseline: 1170dc6055ed0d669275efb1ab1906d2715ad1c3 - -Cherry picks: - + 0540fdefe2c27605516a772c2a224d579db0a74d: - Extract version numbers that look like "..._1.2.3_..." from - BUILD_EMBED_LABEL into Info.plist. - + cef25c44bc6c2ae8e5bd649228a9a9c39f057576: - RELNOTES: Attribute error messages related to Android resources - are easier to understand now. - -' - assert_equals "${header}${RELNOTES}" "$(cat ${TEST_log})" - assert_equals "${RELNOTES}" "$(get_release_notes release-v1)" - assert_equals 2 "$(get_release_candidate release-v1)" - - # Push the release - push v1 - release v1 - - # Third release to test abandon - cat >${EDITOR} <\$1 -EOF - # Create release - generate_rc --force_rc=2 v2 2464526 - expect_log "Release v2rc2" - expect_log "Baseline: 2464526" - assert_equals 2 "$(get_release_candidate release-v2)" - # Abandon it - abandon v2 - # Add a commit hook to test if it is ignored - cat <<'EOF' >.git/hooks/commit-msg -echo HOOK-SHOULD-BE-IGNORED >>$1 -EOF - chmod +x .git/hooks/commit-msg - # Re-create release - generate_rc v2 2464526 - expect_log "Release v2rc1" - expect_log "Baseline: 2464526" - expect_not_log "HOOK-SHOULD-BE-IGNORED" - # Push - push v2 - # Abandon it - abandon v2 -} - -run_suite "Release tests" diff --git a/scripts/release/relnotes.sh b/scripts/release/relnotes.sh index d88ef46a2f..c1598c6f50 100755 --- a/scripts/release/relnotes.sh +++ b/scripts/release/relnotes.sh @@ -18,6 +18,9 @@ set -eu # Generate the release notes from the git history. +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +source ${SCRIPT_DIR}/common.sh + # It uses the RELNOTES tag in the history to knows the important changes to # report: # RELNOTES: indicates a change important the user. @@ -34,7 +37,7 @@ RELNOTES_DESC=("Incompatible changes" "New features" "Important changes") # BASELINE is the hash of the baseline commit of the latest release # CHERRYPICKS is the list of hash of cherry-picked commits of the latest release # return 1 if there is no initial release -function get_last_release() { +function __get_last_release() { local changelog=$1 [ -f "$changelog" ] || return 1 # No changelog = initial release local BASELINE_LINE=$(grep -m 1 -n '^Baseline: ' "$changelog") || return 1 @@ -56,7 +59,7 @@ function get_last_release() { # Now get the list of commit with a RELNOTES since latest release baseline ($1) # discarding cherry_picks ($2..) and rollbacks. The returned list of commits is # from the oldest to the newest -function get_release_notes_commits() { +function __get_release_notes_commits() { local baseline=$1 shift local cherry_picks="$@" @@ -76,7 +79,7 @@ function get_release_notes_commits() { # RELNOTES_INC for incompatible changes # RELNOTES_NEW for new features changes # RELNOTES for other changes -function extract_release_note() { +function __extract_release_note() { local find_relnote_awk_script=" BEGIN { in_relnote = 0 } /^$/ { in_relnote = 0 } @@ -96,19 +99,19 @@ function extract_release_note() { # Build release notes arrays from a list of commits ($@) and return the release # note in an array of array. -function generate_release_notes() { +function __generate_release_notes() { for i in "${RELNOTES_TYPES[@]}"; do eval "RELNOTES_${i}=()" done for commit in $@; do - extract_release_note "${commit}" + __extract_release_note "${commit}" done } # Returns the list of release notes in arguments into a list of points in # a markdown list. The release notes are wrapped to 70 characters so it # displays nicely in a git history. -function format_release_notes() { +function __format_release_notes() { local i for (( i=1; $i <= $#; i=$i+1 )); do local relnote="${!i}" @@ -120,11 +123,11 @@ function format_release_notes() { # Create the release notes since commit $1 ($2...${[#]} are the cherry-picks, # so the commits to ignore. -function release_notes() { +function __release_notes() { local i - local commits=$(get_release_notes_commits $@) + local commits=$(__get_release_notes_commits $@) local length="${#RELNOTES_TYPES[@]}" - generate_release_notes "$commits" + __generate_release_notes "$commits" for (( i=0; $i < $length; i=$i+1 )); do local relnotes_title="${RELNOTES_DESC[$i]}" local relnotes_type=${RELNOTES_TYPES[$i]} @@ -133,7 +136,7 @@ function release_notes() { if (( "${nb_relnotes}" > 0 )); then echo "${relnotes_title}:" echo - format_release_notes "${!relnotes}" + __format_release_notes "${!relnotes}" echo fi done @@ -142,8 +145,8 @@ function release_notes() { # A wrapper around all the previous function, using the CHANGELOG.md # file in $1 to compute the last release commit hash. function create_release_notes() { - local last_release=$(get_last_release "$1") || \ + local last_release=$(__get_last_release "$1") || \ { echo "Initial release."; return 0; } [ -n "${last_release}" ] || { echo "Initial release."; return 0; } - release_notes ${last_release} + __release_notes ${last_release} } diff --git a/scripts/release/relnotes_test.sh b/scripts/release/relnotes_test.sh deleted file mode 100755 index 22fbb1382a..0000000000 --- a/scripts/release/relnotes_test.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/bash - -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Tests release notes generation (relnotes.sh) -set -eu - -SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -source ${SCRIPT_DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; } - -### Setup a git repository -setup_git_repository - -### Load the relnotes script -source ${SCRIPT_DIR}/common.sh || { echo "common.sh not found!" >&2; exit 1; } -source ${SCRIPT_DIR}/relnotes.sh || { echo "relnotes.sh not found!" >&2; exit 1; } - -### Tests method - -function set_up() { - cd ${MASTER_ROOT} - git checkout -q master -} - -function test_format_release_notes() { - local expected=' - Lorem ipsus I do not know more of latin than that but I need to - type random text that spans multiple line so we can test that the - wrapping of lines works as intended. - - Another thing I must type. - - Yet another test that spans across multiple lines so I must type - some random stuff to test wrapping.' - local input=("Lorem ipsus I do not know more of latin \ -than that but I need to type random text that spans multiple line so we \ -can test that the wrapping of lines works as intended." -"Another thing I must type." -"Yet another test that spans across multiple lines so I must type \ -some random stuff to test wrapping.") - assert_equals "${expected}" "$(format_release_notes "${input[@]}")" -} - -function test_get_release_notes_commits() { - # Generated with git log --grep RELNOTES. - # Only 6d98f6c 53c0748 are removed (rollback). - commits='01889715e70b55b9d197e546593878f16cdc0f26 957934c40f73e96a4414c6a9efbc165367459b4b 7a99c7f47705bbb4ff8617f4876bc0298093a556 b5ba24a3f3ee0e7da718bf8becac96d691ae2074 c9041bf6f629b1441b6131ca495d8e6d0fb84f42 8232d9ba85b26cb4d10588a39d7a7adafeb5c4af 422c731fbefb098962813b3e0914a9192c72e549 e9029d4613d98c17e05236a0058164bb8787f94b cc44636d2d538bc91e7291ed4607f2bdce356827 06b09ce978eb984bee3a83ed446aab2dce60fa43 29b05c8e6c48b4028a06cd788d833506cce090eb 67944d866d4b74b9c4af51d5097a51fed5a6c30e e8f664780e3089b0af8b267effdec0f3242843ad 6d9fb360b79ec040e423b20b72a9cc3c4bac5b54 f7c992263610c9246a2c81b4e015b9c7f216fd50 5c0e4b2c64e9c9ccf80607ce4d8855ad032c302f 9e387ddc2fbeb6c88400e8b9fcf4e1d1fc600be7 98c92744557330d844ff5c38a28e5419d153ed1f db4d8619023693c97e5afb467737084ccd30b311 a689f2900911039d2c10e6de7d41fbf1bdf31f44 db487ce72207a340589182bbd85b84d1a9375bd1 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e bb59d88448d3365ff3ec168c1431cd86c5a5f02c d3461dba46b50719e238939946048cd1ca12755a cef25c44bc6c2ae8e5bd649228a9a9c39f057576 14d905b5cce9a1bbc2911331809b03679b23dad1' - assert_equals "$commits" "$(get_release_notes_commits 00d7223 | xargs)" - assert_equals "$(echo "$commits" | sed 's/957934c[0-9a-f]* //')" \ - "$(get_release_notes_commits 00d7223 957934c | xargs)" -} - -TEST_INC_CHANGE='Incompatible changes: - - - Remove deprecated "make var" INCDIR - -' -TEST_NEW_CHANGE='New features: - - - added --with_aspect_deps to blaze query, that prints additional - information about aspects of target when --output is set to {xml, - proto, record}. - -' -TEST_CHANGE='Important changes: - - - Use a default implementation of a progress message, rather than - defaulting to null for all SpawnActions. - - Attribute error messages related to Android resources are easier - to understand now.' - -function test_release_notes() { - assert_equals "$TEST_INC_CHANGE$(echo)$TEST_NEW_CHANGE$(echo)$TEST_CHANGE" \ - "$(release_notes 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e)" - assert_equals "$TEST_NEW_CHANGE$(echo)$TEST_CHANGE" \ - "$(release_notes 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e \ - bb59d88)" -} - -function test_get_last_release() { - rm -f ${TEST_TMPDIR}/CHANGELOG.md - if (get_last_release "${TEST_TMPDIR}/CHANGELOG.md"); then - fail "Should have returned false for initial release" - fi - cat <${TEST_TMPDIR}/CHANGELOG.md -## No release -EOF - if (get_last_release "${TEST_TMPDIR}/CHANGELOG.md"); then - fail "Should have returned false when no release exists" - fi - cat <${TEST_TMPDIR}/CHANGELOG.md -## New release - -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Initial release without cherry-picks - -EOF - assert_equals "965c392ab1d68d5bc23fdef3d86d635ec9d2da8e" \ - "$(get_last_release "${TEST_TMPDIR}/CHANGELOG.md")" - - - mv ${TEST_TMPDIR}/CHANGELOG.md ${TEST_TMPDIR}/CHANGELOG.md.bak - cat <${TEST_TMPDIR}/CHANGELOG.md -## Cherry-picking bb59d88448d3365ff3ec168c1431cd86c5a5f02c - -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Cherry picks: - + bb59d88448d3365ff3ec168c1431cd86c5a5f02c: RELNOTES[INC]: Remove deprecated "make var" INCDIR - -$TEST_INC_CHANGE -EOF - cat ${TEST_TMPDIR}/CHANGELOG.md.bak >>${TEST_TMPDIR}/CHANGELOG.md - rm ${TEST_TMPDIR}/CHANGELOG.md.bak - assert_equals "965c392ab1d68d5bc23fdef3d86d635ec9d2da8e bb59d88448d3365ff3ec168c1431cd86c5a5f02c" \ - "$(get_last_release "${TEST_TMPDIR}/CHANGELOG.md")" - - mv ${TEST_TMPDIR}/CHANGELOG.md ${TEST_TMPDIR}/CHANGELOG.md.bak - cat <${TEST_TMPDIR}/CHANGELOG.md -## Cherry-picking bb59d88448d3365ff3ec168c1431cd86c5a5f02c and -## 14d905b5cce9a1bbc2911331809b03679b23dad1: - -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Cherry picks: - + bb59d88448d3365ff3ec168c1431cd86c5a5f02c: - RELNOTES[INC]: Remove deprecated "make var" INCDIR - + 14d905b5cce9a1bbc2911331809b03679b23dad1: - Add --with_aspect_deps flag to blaze query. This flag should - produce additional information about aspect dependencies when - --output is set to {xml, proto}. - -$TEST_INC_CHANGE -$TEST_NEW_CHANGE -EOF - cat ${TEST_TMPDIR}/CHANGELOG.md.bak >>${TEST_TMPDIR}/CHANGELOG.md - rm ${TEST_TMPDIR}/CHANGELOG.md.bak - assert_equals \ - "965c392ab1d68d5bc23fdef3d86d635ec9d2da8e bb59d88448d3365ff3ec168c1431cd86c5a5f02c 14d905b5cce9a1bbc2911331809b03679b23dad1" \ - "$(get_last_release "${TEST_TMPDIR}/CHANGELOG.md")" - -} - -function test_create_release_notes() { - cat <${TEST_TMPDIR}/CHANGELOG.md -## New release - -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Initial release without cherry-picks - -EOF - assert_equals "$TEST_INC_CHANGE$(echo)$TEST_NEW_CHANGE$(echo)$TEST_CHANGE" \ - "$(create_release_notes ${TEST_TMPDIR}/CHANGELOG.md)" - - cat <<'EOF' >${TEST_TMPDIR}/CHANGELOG.md -## Cherry-picking bb59d88448d3365ff3ec168c1431cd86c5a5f02c - -``` -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Cherry picks: - + bb59d88448d3365ff3ec168c1431cd86c5a5f02c: - RELNOTES[INC]: Remove deprecated "make var" INCDIR -``` - -EOF - cat <>${TEST_TMPDIR}/CHANGELOG.md -$TEST_INC_CHANGE -EOF - assert_equals "$TEST_NEW_CHANGE$(echo)$TEST_CHANGE" \ - "$(create_release_notes ${TEST_TMPDIR}/CHANGELOG.md)" - assert_equals "965c392ab1d68d5bc23fdef3d86d635ec9d2da8e bb59d88448d3365ff3ec168c1431cd86c5a5f02c" \ - "$(get_last_release "${TEST_TMPDIR}/CHANGELOG.md")" - - cat <<'EOF' >${TEST_TMPDIR}/CHANGELOG.md -## Cherry-picking bb59d88448d3365ff3ec168c1431cd86c5a5f02c and -## 14d905b5cce9a1bbc2911331809b03679b23dad1: - -``` -Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Cherry picks: - + bb59d88448d3365ff3ec168c1431cd86c5a5f02c: - RELNOTES[INC]: Remove deprecated "make var" INCDIR - + 14d905b5cce9a1bbc2911331809b03679b23dad1: - Add --with_aspect_deps flag to blaze query. This flag should - produce additional information about aspect dependencies when - --output is set to {xml, proto}. -``` - -EOF - cat <>${TEST_TMPDIR}/CHANGELOG.md -$TEST_INC_CHANGE -$TEST_NEW_CHANGE -EOF - assert_equals "$TEST_CHANGE" \ - "$(create_release_notes ${TEST_TMPDIR}/CHANGELOG.md)" -} - -function test_create_revision_information() { - expected='Baseline: 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e - -Cherry picks: - + bb59d88448d3365ff3ec168c1431cd86c5a5f02c: - RELNOTES[INC]: Remove deprecated "make var" INCDIR - + 14d905b5cce9a1bbc2911331809b03679b23dad1: - Add --with_aspect_deps flag to blaze query. This flag should - produce additional information about aspect dependencies when - --output is set to {xml, proto}.' - actual="$(create_revision_information \ - 965c392ab1d68d5bc23fdef3d86d635ec9d2da8e \ - bb59d88448d3365ff3ec168c1431cd86c5a5f02c \ - 14d905b5cce9a1bbc2911331809b03679b23dad1)" - assert_equals "$expected" "$actual" -} - -function test_extract_release_note_for_pre_copybara_commits() { - local expected='added --with_aspect_deps to blaze query, that prints additional information about aspects of target when --output is set to {xml, proto, record}.' - extract_release_note 14d905b5cce9a1bbc2911331809b03679b23dad1 - local actual=$(printf "%s\n" "${RELNOTES_NEW[@]}") - assert_equals "${expected}" "${actual}" -} - -function test_extract_release_note_for_post_copybara_commits() { - local expected="'output_groups' and 'instrumented_files' cannot be specified in DefaultInfo." - extract_release_note e788964a6ebc2c4966456ac74044f4f44a126fe5 - local actual=$(printf "%s\n" "${RELNOTES_[@]}") - assert_equals "${expected}" "${actual}" -} - -function test_commit_list_no_rollback() { - git checkout -q 2ea4fa26281175c316651ec50784b820a9f409cf - local expected='7c672ac643dd59bf4b3e284c6ad019c54545492f -0257c29f496719bb8414d012334155de6bbefa11 -a9c46e5907be66248b6218ae70e0a1d999c696d5 -78927792c77a6468607e215034c22b0641553f77 -8882192897fa3453d51fe907d19f948215a581af -2ea4fa26281175c316651ec50784b820a9f409cf' - local actual="$(get_release_notes_commits 7c605cf6ea9755a06e5abb16a631faac8ebe2937)" - assert_equals "${expected}" "${actual}" -} - -function test_nonone_relnotes() { - git checkout -q 2ea4fa26281175c316651ec50784b820a9f409cf - local expected='Incompatible changes: - - - --javabase= and --host_javabase= - are not supported anymore. If you need this functionality - java_runtime_suite(name="suite", default=":runtime") - java_runtime(name="runtime", java_home=) is an - alternative.' - local actual="$(release_notes 7c605cf6ea9755a06e5abb16a631faac8ebe2937)" - assert_equals "${expected}" "${actual}" -} - -run_suite "Release notes generation tests" diff --git a/scripts/release/testenv.sh b/scripts/release/testenv.sh deleted file mode 100755 index f11c8ab771..0000000000 --- a/scripts/release/testenv.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Setting up the environment for Bazel release scripts test. - -[ -z "$TEST_SRCDIR" ] && { echo "TEST_SRCDIR not set!" >&2; exit 1; } - -# Load the unit-testing framework -source "${TEST_SRCDIR}/io_bazel/src/test/shell/unittest.bash" || \ - { echo "Failed to source unittest.bash" >&2; exit 1; } - -# Commit at which we cut the master to do the test so we always take the git -# repository in a consistent state. -: ${MASTER_COMMIT:=7d41d7417fc34f7fa8aac7130a0588b8557e4b57} - -# Set-up a copy of the git repository in ${MASTER_ROOT}, pointing master -# to ${MASTER_COMMIT}. -function setup_git_repository() { - local origin_git_root=${TEST_SRCDIR}/io_bazel - MASTER_ROOT=${TEST_TMPDIR}/git/root - local orig_dir=${PWD} - # Create a new origin with the good starting point - mkdir -p ${MASTER_ROOT} - cd ${MASTER_ROOT} - cp -RL ${origin_git_root}/.git .git - rm -f .git/hooks/* # Do not keep custom hooks - git reset -q --hard HEAD - git checkout -q -B master ${MASTER_COMMIT} - cd ${orig_dir} -} -- cgit v1.2.3