Skip to content

Commit

Permalink
release: support kick off release in current branch
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ahrtr committed Dec 12, 2022
1 parent 64599b4 commit 5d78d6d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ jobs:
Name-Email: [email protected]
Expire-Date: 0
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
3 changes: 0 additions & 3 deletions scripts/build-binary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ source ./scripts/test_lib.sh
VER=$1
REPOSITORY="${REPOSITORY:-git@github.com:etcd-io/etcd.git}"


if [ -z "$1" ]; then
echo "Usage: ${0} VERSION" >> /dev/stderr
exit 255
Expand All @@ -25,9 +24,7 @@ function setup_env {

pushd "${proj}" >/dev/null
run git fetch --all
git_assert_branch_in_sync || exit 2
run git checkout "${ver}"
git_assert_branch_in_sync || exit 2
popd >/dev/null
}

Expand Down
66 changes: 49 additions & 17 deletions scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ help() {
echo " flags:"
echo " --no-upload: skip gs://etcd binary artifact uploads."
echo " --no-docker-push: skip docker image pushes."
echo " --in-place: build binaries using current branch."
echo ""
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"
Expand All @@ -54,8 +55,15 @@ main() {
fi
RELEASE_VERSION="v${VERSION}"
MINOR_VERSION=$(echo "${VERSION}" | cut -d. -f 1-2)
BRANCH=${BRANCH:-"release-${MINOR_VERSION}"}
REPOSITORY=${REPOSITORY:-"https://github.com/etcd-io/etcd.git"}

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"}
BRANCH=${BRANCH:-"release-${MINOR_VERSION}"}
fi

log_warning "DRY_RUN=${DRY_RUN}"
log_callout "RELEASE_VERSION=${RELEASE_VERSION}"
Expand All @@ -78,19 +86,20 @@ main() {
# Set up release directory.
local reldir="/tmp/etcd-release-${VERSION}"
log_callout "Preparing temporary directory: ${reldir}"
if [ ! -d "${reldir}/etcd" ]; then
if [ ! -d "${reldir}/etcd" ] && [ "${IN_PLACE}" == 0 ]; then
mkdir -p "${reldir}"
cd "${reldir}"
run git clone "${REPOSITORY}" --branch "${BRANCH}"
run cd "${reldir}/etcd" || exit 2
run git checkout "${BRANCH}" || exit 2
run git pull origin

git_assert_branch_in_sync || exit 2
fi
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 pull origin
git_assert_branch_in_sync || exit 2

# If a release version tag already exists, use it.
local remote_tag_exists
remote_tag_exists=$(run git ls-remote origin "refs/tags/${RELEASE_VERSION}" | grep -c "${RELEASE_VERSION}" || true)
Expand All @@ -101,6 +110,7 @@ main() {
fi

# Check go version.
log_callout "Check go version"
local go_version current_go_version
go_version="go$(grep go-version .github/workflows/build.yaml | awk '{print $2}' | tr -d '"')"
current_go_version=$(go version | awk '{ print $3 }')
Expand All @@ -110,6 +120,7 @@ main() {
fi

# 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
# Bump version/version.go to release version.
local source_version
Expand Down Expand Up @@ -148,7 +159,7 @@ main() {
fi

# 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
[[ "${confirm,,}" == "y" ]] || exit 1
maybe_run git push
Expand All @@ -162,15 +173,23 @@ main() {
REMOTE_REPO="origin" push_mod_tags_cmd
fi

# Verify the version tag is on the right branch
# shellcheck disable=SC2155
local branch=$(git for-each-ref --contains "${RELEASE_VERSION}" --format="%(refname)" 'refs/heads' | cut -d '/' -f 3)
if [ "${branch}" != "${BRANCH}" ]; then
log_error "Error: Git tag ${RELEASE_VERSION} should be on branch '${BRANCH}' but is on '${branch}'"
exit 1
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
# shellcheck disable=SC2155
local branch=$(git for-each-ref --contains "${RELEASE_VERSION}" --format="%(refname)" 'refs/heads' | cut -d '/' -f 3)
if [ "${branch}" != "${BRANCH}" ]; then
log_error "Error: Git tag ${RELEASE_VERSION} should be on branch '${BRANCH}' but is on '${branch}'"
exit 1
fi
fi
fi

log_callout "Verify the latest commit has the version tag"
# Verify the latest commit has the version tag
# shellcheck disable=SC2155
local tag="$(git describe --exact-match HEAD)"
Expand All @@ -179,6 +198,7 @@ main() {
exit 1
fi

log_callout "Verify the work space is clean"
# Verify the clean working tree
# shellcheck disable=SC2155
local diff="$(git diff HEAD --stat)"
Expand Down Expand Up @@ -215,7 +235,7 @@ main() {
fi

# 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."
else
read -p "Upload etcd ${RELEASE_VERSION} release artifacts to gs://etcd [y/N]? " -r confirm
Expand All @@ -227,7 +247,7 @@ main() {
fi

# 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."
else
read -p "Publish etcd ${RELEASE_VERSION} docker images to quay.io [y/N]? " -r confirm
Expand Down Expand Up @@ -308,6 +328,7 @@ main() {
POSITIONAL=()
NO_UPLOAD=0
NO_DOCKER_PUSH=0
IN_PLACE=0

while test $# -gt 0; do
case "$1" in
Expand All @@ -316,6 +337,10 @@ while test $# -gt 0; do
help
exit 0
;;
--in-place)
IN_PLACE=1
shift
;;
--no-upload)
NO_UPLOAD=1
shift
Expand All @@ -337,4 +362,11 @@ if [[ ! $# -eq 1 ]]; then
exit 1
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"
4 changes: 3 additions & 1 deletion scripts/test_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,16 @@ function assert_no_git_modifications {
# - no differencing commits in relation to the origin/$branch
function git_assert_branch_in_sync {
local branch
branch=$(run git rev-parse --abbrev-ref HEAD)
# TODO: When git 2.22 popular, change to:
# 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
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)"
return 2
fi
log_callout "Verify the current branch '${branch}' is in sync with the 'origin/${branch}'"
if [ -n "${branch}" ]; then
ref_local=$(run git rev-parse "${branch}")
ref_origin=$(run git rev-parse "origin/${branch}")
Expand Down

0 comments on commit 5d78d6d

Please sign in to comment.