release: support kick off release in current branch

Currently when triggering release, it always pull remote repo and
checkout main branch. Any changes which are merged into the target
release branch (e.g. release-3.5) will be ignored. It isn't
convenient for test, including in github workflow and local environment.
So we need to support triggering release in current branch.

Note: --current-branch should only be called with DRY_RUN=true

Signed-off-by: Benjamin Wang <wachao@vmware.com>
This commit is contained in:
Benjamin Wang 2022-11-26 19:17:52 +08:00
parent 64599b4072
commit 5d78d6d4b1
4 changed files with 53 additions and 22 deletions

View File

@ -22,4 +22,4 @@ jobs:
Name-Email: github-action@etcd.io Name-Email: github-action@etcd.io
Expire-Date: 0 Expire-Date: 0
EOF EOF
DRY_RUN=true BRANCH=main ./scripts/release.sh --no-upload --no-docker-push 3.6.99 DRY_RUN=true ./scripts/release.sh --no-upload --no-docker-push --in-place 3.6.99

View File

@ -7,7 +7,6 @@ source ./scripts/test_lib.sh
VER=$1 VER=$1
REPOSITORY="${REPOSITORY:-git@github.com:etcd-io/etcd.git}" REPOSITORY="${REPOSITORY:-git@github.com:etcd-io/etcd.git}"
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "Usage: ${0} VERSION" >> /dev/stderr echo "Usage: ${0} VERSION" >> /dev/stderr
exit 255 exit 255
@ -25,9 +24,7 @@ function setup_env {
pushd "${proj}" >/dev/null pushd "${proj}" >/dev/null
run git fetch --all run git fetch --all
git_assert_branch_in_sync || exit 2
run git checkout "${ver}" run git checkout "${ver}"
git_assert_branch_in_sync || exit 2
popd >/dev/null popd >/dev/null
} }

View File

@ -41,6 +41,7 @@ help() {
echo " flags:" echo " flags:"
echo " --no-upload: skip gs://etcd binary artifact uploads." echo " --no-upload: skip gs://etcd binary artifact uploads."
echo " --no-docker-push: skip docker image pushes." echo " --no-docker-push: skip docker image pushes."
echo " --in-place: build binaries using current branch."
echo "" echo ""
echo "One can perform a (dry-run) test release from any (uncommitted) branch using:" echo "One can perform a (dry-run) test release from any (uncommitted) branch using:"
echo " DRY_RUN=true REPOSITORY=\`pwd\` BRANCH='local-branch-name' ./scripts/release 3.5.0-foobar.2" echo " DRY_RUN=true REPOSITORY=\`pwd\` BRANCH='local-branch-name' ./scripts/release 3.5.0-foobar.2"
@ -54,8 +55,15 @@ main() {
fi fi
RELEASE_VERSION="v${VERSION}" RELEASE_VERSION="v${VERSION}"
MINOR_VERSION=$(echo "${VERSION}" | cut -d. -f 1-2) MINOR_VERSION=$(echo "${VERSION}" | cut -d. -f 1-2)
BRANCH=${BRANCH:-"release-${MINOR_VERSION}"}
if [ "${IN_PLACE}" == 1 ]; then
# Trigger release in current branch
REPOSITORY=$(pwd)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
else
REPOSITORY=${REPOSITORY:-"https://github.com/etcd-io/etcd.git"} REPOSITORY=${REPOSITORY:-"https://github.com/etcd-io/etcd.git"}
BRANCH=${BRANCH:-"release-${MINOR_VERSION}"}
fi
log_warning "DRY_RUN=${DRY_RUN}" log_warning "DRY_RUN=${DRY_RUN}"
log_callout "RELEASE_VERSION=${RELEASE_VERSION}" log_callout "RELEASE_VERSION=${RELEASE_VERSION}"
@ -78,18 +86,19 @@ main() {
# Set up release directory. # Set up release directory.
local reldir="/tmp/etcd-release-${VERSION}" local reldir="/tmp/etcd-release-${VERSION}"
log_callout "Preparing temporary directory: ${reldir}" log_callout "Preparing temporary directory: ${reldir}"
if [ ! -d "${reldir}/etcd" ]; then if [ ! -d "${reldir}/etcd" ] && [ "${IN_PLACE}" == 0 ]; then
mkdir -p "${reldir}" mkdir -p "${reldir}"
cd "${reldir}" cd "${reldir}"
run git clone "${REPOSITORY}" --branch "${BRANCH}" run git clone "${REPOSITORY}" --branch "${BRANCH}"
fi
run cd "${reldir}/etcd" || exit 2 run cd "${reldir}/etcd" || exit 2
# mark local directory as root for test_lib scripts executions
set_root_dir
run git checkout "${BRANCH}" || exit 2 run git checkout "${BRANCH}" || exit 2
run git pull origin run git pull origin
git_assert_branch_in_sync || exit 2 git_assert_branch_in_sync || exit 2
fi
# mark local directory as root for test_lib scripts executions
set_root_dir
# If a release version tag already exists, use it. # If a release version tag already exists, use it.
local remote_tag_exists local remote_tag_exists
@ -101,6 +110,7 @@ main() {
fi fi
# Check go version. # Check go version.
log_callout "Check go version"
local go_version current_go_version local go_version current_go_version
go_version="go$(grep go-version .github/workflows/build.yaml | awk '{print $2}' | tr -d '"')" go_version="go$(grep go-version .github/workflows/build.yaml | awk '{print $2}' | tr -d '"')"
current_go_version=$(go version | awk '{ print $3 }') current_go_version=$(go version | awk '{ print $3 }')
@ -110,6 +120,7 @@ main() {
fi fi
# If the release tag does not already exist remotely, create it. # If the release tag does not already exist remotely, create it.
log_callout "Create tag if not present"
if [ "${remote_tag_exists}" -eq 0 ]; then if [ "${remote_tag_exists}" -eq 0 ]; then
# Bump version/version.go to release version. # Bump version/version.go to release version.
local source_version local source_version
@ -148,7 +159,7 @@ main() {
fi fi
# Push the version change if it's not already been pushed. # Push the version change if it's not already been pushed.
if [ "$DRY_RUN" != "true" ] && [ "$(git rev-list --count "origin/${BRANCH}..${BRANCH}")" -gt 0 ]; then if [ "${DRY_RUN}" != "true" ] && [ "$(git rev-list --count "origin/${BRANCH}..${BRANCH}")" -gt 0 ]; then
read -p "Push version bump up to ${VERSION} to '$(git remote get-url origin)' [y/N]? " -r confirm read -p "Push version bump up to ${VERSION} to '$(git remote get-url origin)' [y/N]? " -r confirm
[[ "${confirm,,}" == "y" ]] || exit 1 [[ "${confirm,,}" == "y" ]] || exit 1
maybe_run git push maybe_run git push
@ -162,6 +173,12 @@ main() {
REMOTE_REPO="origin" push_mod_tags_cmd REMOTE_REPO="origin" push_mod_tags_cmd
fi fi
if [ "${IN_PLACE}" == 0 ]; then
# Tried with `local branch=$(git branch -a --contains tags/"${RELEASE_VERSION}")`
# so as to work with both current branch and main/release-3.X.
# But got error below on current branch mode,
# Error: Git tag v3.6.99 should be on branch '* (HEAD detached at pull/14860/merge)' but is on '* (HEAD detached from pull/14860/merge)'
#
# Verify the version tag is on the right branch # Verify the version tag is on the right branch
# shellcheck disable=SC2155 # shellcheck disable=SC2155
local branch=$(git for-each-ref --contains "${RELEASE_VERSION}" --format="%(refname)" 'refs/heads' | cut -d '/' -f 3) local branch=$(git for-each-ref --contains "${RELEASE_VERSION}" --format="%(refname)" 'refs/heads' | cut -d '/' -f 3)
@ -170,7 +187,9 @@ main() {
exit 1 exit 1
fi fi
fi fi
fi
log_callout "Verify the latest commit has the version tag"
# Verify the latest commit has the version tag # Verify the latest commit has the version tag
# shellcheck disable=SC2155 # shellcheck disable=SC2155
local tag="$(git describe --exact-match HEAD)" local tag="$(git describe --exact-match HEAD)"
@ -179,6 +198,7 @@ main() {
exit 1 exit 1
fi fi
log_callout "Verify the work space is clean"
# Verify the clean working tree # Verify the clean working tree
# shellcheck disable=SC2155 # shellcheck disable=SC2155
local diff="$(git diff HEAD --stat)" local diff="$(git diff HEAD --stat)"
@ -215,7 +235,7 @@ main() {
fi fi
# Upload artifacts. # Upload artifacts.
if [ "${NO_UPLOAD}" == 1 ]; then if [ "${DRY_RUN}" == "true" ] || [ "${NO_UPLOAD}" == 1 ]; then
log_callout "Skipping artifact upload to gs://etcd. --no-upload flat is set." log_callout "Skipping artifact upload to gs://etcd. --no-upload flat is set."
else else
read -p "Upload etcd ${RELEASE_VERSION} release artifacts to gs://etcd [y/N]? " -r confirm read -p "Upload etcd ${RELEASE_VERSION} release artifacts to gs://etcd [y/N]? " -r confirm
@ -227,7 +247,7 @@ main() {
fi fi
# Push images. # Push images.
if [ "${NO_DOCKER_PUSH}" == 1 ]; then if [ "${DRY_RUN}" == "true" ] || [ "${NO_DOCKER_PUSH}" == 1 ]; then
log_callout "Skipping docker push. --no-docker-push flat is set." log_callout "Skipping docker push. --no-docker-push flat is set."
else else
read -p "Publish etcd ${RELEASE_VERSION} docker images to quay.io [y/N]? " -r confirm read -p "Publish etcd ${RELEASE_VERSION} docker images to quay.io [y/N]? " -r confirm
@ -308,6 +328,7 @@ main() {
POSITIONAL=() POSITIONAL=()
NO_UPLOAD=0 NO_UPLOAD=0
NO_DOCKER_PUSH=0 NO_DOCKER_PUSH=0
IN_PLACE=0
while test $# -gt 0; do while test $# -gt 0; do
case "$1" in case "$1" in
@ -316,6 +337,10 @@ while test $# -gt 0; do
help help
exit 0 exit 0
;; ;;
--in-place)
IN_PLACE=1
shift
;;
--no-upload) --no-upload)
NO_UPLOAD=1 NO_UPLOAD=1
shift shift
@ -337,4 +362,11 @@ if [[ ! $# -eq 1 ]]; then
exit 1 exit 1
fi fi
# Note that we shouldn't upload artifacts in --in-place mode, so it
# must be called with DRY_RUN=true
if [ "${DRY_RUN}" != "true" ] && [ "${IN_PLACE}" == 1 ]; then
log_error "--in-place should only be called with DRY_RUN=true"
exit 1
fi
main "$1" main "$1"

View File

@ -410,14 +410,16 @@ function assert_no_git_modifications {
# - no differencing commits in relation to the origin/$branch # - no differencing commits in relation to the origin/$branch
function git_assert_branch_in_sync { function git_assert_branch_in_sync {
local branch local branch
branch=$(run git rev-parse --abbrev-ref HEAD)
# TODO: When git 2.22 popular, change to: # TODO: When git 2.22 popular, change to:
# branch=$(git branch --show-current) # branch=$(git branch --show-current)
branch=$(run git rev-parse --abbrev-ref HEAD)
log_callout "Verify the current branch '${branch}' is clean"
if [[ $(run git status --porcelain --untracked-files=no) ]]; then if [[ $(run git status --porcelain --untracked-files=no) ]]; then
log_error "The workspace in '$(pwd)' for branch: ${branch} has uncommitted changes" log_error "The workspace in '$(pwd)' for branch: ${branch} has uncommitted changes"
log_error "Consider cleaning up / renaming this directory or (cd $(pwd) && git reset --hard)" log_error "Consider cleaning up / renaming this directory or (cd $(pwd) && git reset --hard)"
return 2 return 2
fi fi
log_callout "Verify the current branch '${branch}' is in sync with the 'origin/${branch}'"
if [ -n "${branch}" ]; then if [ -n "${branch}" ]; then
ref_local=$(run git rev-parse "${branch}") ref_local=$(run git rev-parse "${branch}")
ref_origin=$(run git rev-parse "origin/${branch}") ref_origin=$(run git rev-parse "origin/${branch}")