#!/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"