From b422c0de77e427d3ba6ce6c16fe8d83d6cfb7a94 Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 16:02:54 -0700 Subject: [PATCH 1/7] Update comments to make the code more readable --- scripts/release.sh | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 07c4018cb..db4839b19 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -67,9 +67,10 @@ set -o errexit set -o nounset set -o pipefail -# used by the client generator: https://github.com/kubernetes-client/gen/blob/729332ad08f0f4d98983b7beb027e2f657236ef9/openapi/openapi-generator/client-generator.sh#L52 +# Set constants used by the client generator. export USERNAME=kubernetes +# Set up utilities. repo_root="$(git rev-parse --show-toplevel)" declare -r repo_root cd "${repo_root}" @@ -77,25 +78,25 @@ cd "${repo_root}" source scripts/util/changelog.sh source scripts/util/kube_changelog.sh -old_client_version=$(python3 "scripts/constants.py" CLIENT_VERSION) -old_k8s_api_version=$(util::changelog::get_k8s_api_version "v$old_client_version") +# Read user inputs or values locally. KUBERNETES_BRANCH=${KUBERNETES_BRANCH:-$(python3 "scripts/constants.py" KUBERNETES_BRANCH)} CLIENT_VERSION=${CLIENT_VERSION:-$(python3 "scripts/constants.py" CLIENT_VERSION)} DEVELOPMENT_STATUS=${DEVELOPMENT_STATUS:-$(python3 "scripts/constants.py" DEVELOPMENT_STATUS)} -# get Kubernetes API Version +# Get Kubernetes API versions +old_client_version=$(python3 "scripts/constants.py" CLIENT_VERSION) +old_k8s_api_version=$(util::changelog::get_k8s_api_version "v$old_client_version") new_k8s_api_version=$(util::kube_changelog::find_latest_patch_version $KUBERNETES_BRANCH) echo "Old Kubernetes API Version: $old_k8s_api_version" echo "New Kubernetes API Version: $new_k8s_api_version" +# Update version constants sed -i "s/^KUBERNETES_BRANCH =.*$/KUBERNETES_BRANCH = \"$KUBERNETES_BRANCH\"/g" scripts/constants.py sed -i "s/^CLIENT_VERSION =.*$/CLIENT_VERSION = \"$CLIENT_VERSION\"/g" scripts/constants.py sed -i "s/^DEVELOPMENT_STATUS =.*$/DEVELOPMENT_STATUS = \"$DEVELOPMENT_STATUS\"/g" scripts/constants.py git commit -am "update version constants for $CLIENT_VERSION release" -util::changelog::update_release_api_version $CLIENT_VERSION $old_client_version $new_k8s_api_version - -# get API change release notes since $old_k8s_api_version. +# Update CHANGELOG with API change release notes since $old_k8s_api_version. # NOTE: $old_k8s_api_version may be one-minor-version behind $KUBERNETES_BRANCH, e.g. # KUBERNETES_BRANCH=release-1.19 # old_k8s_api_version=1.18.17 @@ -106,30 +107,34 @@ util::changelog::update_release_api_version $CLIENT_VERSION $old_client_version # TODO(roycaihw): not all Kubernetes API changes modify the OpenAPI spec. # Download the patch and skip if the spec is not modified. Also we want to # look at other k/k sections like "deprecation" +util::changelog::update_release_api_version $CLIENT_VERSION $old_client_version $new_k8s_api_version release_notes=$(util::kube_changelog::get_api_changelog "$KUBERNETES_BRANCH" "$old_k8s_api_version") if [[ -n "$release_notes" ]]; then util::changelog::write_changelog v$CLIENT_VERSION "### API Change" "$release_notes" fi - git commit -am "update changelog" -# run client generator +# Re-generate the client scripts/update-client.sh +# Apply hotfixes rm -r kubernetes/test/ git add . git commit -m "temporary generated commit" scripts/apply-hotfixes.sh git reset HEAD~2 -# custom object API is hosted in gen repo. Commit API change separately for -# easier review + +# Custom object API is hosted in gen repo. Commit custom object API change +# separately for easier review if [[ -n "$(git diff kubernetes/client/api/custom_objects_api.py)" ]]; then git add kubernetes/client/api/custom_objects_api.py git commit -m "generated client change for custom_objects" fi +# Check if there is any API change, then commit git add kubernetes/docs kubernetes/client/api/ kubernetes/client/models/ kubernetes/swagger.json.unprocessed scripts/swagger.json -# verify if there are staged changes, then commit git diff-index --quiet --cached HEAD || git commit -m "generated API change" +# Commit everything else git add . git commit -m "generated client change" + echo "Release finished successfully." From 96cc50e58e841bdbf7ff274e3c0910afb2aebeed Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 16:03:44 -0700 Subject: [PATCH 2/7] Checkout a local branch, pull a remote branch --- scripts/release.sh | 58 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index db4839b19..1edc060d1 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -67,14 +67,25 @@ set -o errexit set -o nounset set -o pipefail +# Verify git status +if git_status=$(git status --porcelain --untracked=no 2>/dev/null) && [[ -n "${git_status}" ]]; then + echo "!!! Dirty tree. Clean up and try again." + exit 1 +fi + +REPO_ROOT="$(git rev-parse --show-toplevel)" +declare -r REPO_ROOT +cd "${REPO_ROOT}" +declare -r REBASEMAGIC="${REPO_ROOT}/.git/rebase-apply" +if [[ -e "${REBASEMAGIC}" ]]; then + echo "!!! 'git rebase' or 'git am' in progress. Clean up and try again." + exit 1 +fi + # Set constants used by the client generator. export USERNAME=kubernetes # Set up utilities. -repo_root="$(git rev-parse --show-toplevel)" -declare -r repo_root -cd "${repo_root}" - source scripts/util/changelog.sh source scripts/util/kube_changelog.sh @@ -83,6 +94,45 @@ KUBERNETES_BRANCH=${KUBERNETES_BRANCH:-$(python3 "scripts/constants.py" KUBERNET CLIENT_VERSION=${CLIENT_VERSION:-$(python3 "scripts/constants.py" CLIENT_VERSION)} DEVELOPMENT_STATUS=${DEVELOPMENT_STATUS:-$(python3 "scripts/constants.py" DEVELOPMENT_STATUS)} +# Create a local branch +STARTINGBRANCH=$(git symbolic-ref --short HEAD) +declare -r STARTINGBRANCH +gitamcleanup=false +function return_to_kansas { + if [[ "${gitamcleanup}" == "true" ]]; then + echo + echo "+++ Aborting in-progress git am." + git am --abort >/dev/null 2>&1 || true + fi + + echo "+++ Returning you to the ${STARTINGBRANCH} branch and cleaning up." + git checkout -f "${STARTINGBRANCH}" >/dev/null 2>&1 || true +} +trap return_to_kansas EXIT + +remote_branch=upstream/master +if [[ $CLIENT_VERSION != *"snapshot"* ]]; then + remote_branch=upstream/release-"${CLIENT_VERSION%%.*}".0 +fi +echo "+++ Updating remotes..." +git remote update upstream origin +if ! git log -n1 --format=%H "${remote_branch}" >/dev/null 2>&1; then + echo "!!! '${remote_branch}' not found." + echo " (In particular, it needs to be a valid, existing remote branch that I can 'git checkout'.)" + exit 1 +fi + +newbranch="$(echo "automated-release-of-${CLIENT_VERSION}-${remote_branch}" | sed 's/\//-/g')" +newbranchuniq="${newbranch}-$(date +%s)" +declare -r newbranchuniq +echo "+++ Creating local branch ${newbranchuniq}" +git checkout -b "${newbranchuniq}" "${remote_branch}" + +# If it's an actual release, pull master branch +if [[ $CLIENT_VERSION != *"snapshot"* ]]; then + git pull -X theirs upstream master +fi + # Get Kubernetes API versions old_client_version=$(python3 "scripts/constants.py" CLIENT_VERSION) old_k8s_api_version=$(util::changelog::get_k8s_api_version "v$old_client_version") From 6ec81ea5137f0a6b45a320d60d3598b59002dc8f Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 19:47:37 -0700 Subject: [PATCH 3/7] DEVELOPMENT_STATUS may contain slash. Use colon as delimiter instead --- scripts/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release.sh b/scripts/release.sh index 1edc060d1..285b25440 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -143,7 +143,7 @@ echo "New Kubernetes API Version: $new_k8s_api_version" # Update version constants sed -i "s/^KUBERNETES_BRANCH =.*$/KUBERNETES_BRANCH = \"$KUBERNETES_BRANCH\"/g" scripts/constants.py sed -i "s/^CLIENT_VERSION =.*$/CLIENT_VERSION = \"$CLIENT_VERSION\"/g" scripts/constants.py -sed -i "s/^DEVELOPMENT_STATUS =.*$/DEVELOPMENT_STATUS = \"$DEVELOPMENT_STATUS\"/g" scripts/constants.py +sed -i "s:^DEVELOPMENT_STATUS =.*$:DEVELOPMENT_STATUS = \"$DEVELOPMENT_STATUS\":g" scripts/constants.py git commit -am "update version constants for $CLIENT_VERSION release" # Update CHANGELOG with API change release notes since $old_k8s_api_version. From b8b3accc4b7d08a7ffc2585fa95a712714701a97 Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 20:23:50 -0700 Subject: [PATCH 4/7] Collect release notes from master branch --- scripts/release.sh | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 285b25440..08251e8d5 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -128,11 +128,6 @@ declare -r newbranchuniq echo "+++ Creating local branch ${newbranchuniq}" git checkout -b "${newbranchuniq}" "${remote_branch}" -# If it's an actual release, pull master branch -if [[ $CLIENT_VERSION != *"snapshot"* ]]; then - git pull -X theirs upstream master -fi - # Get Kubernetes API versions old_client_version=$(python3 "scripts/constants.py" CLIENT_VERSION) old_k8s_api_version=$(util::changelog::get_k8s_api_version "v$old_client_version") @@ -140,6 +135,34 @@ new_k8s_api_version=$(util::kube_changelog::find_latest_patch_version $KUBERNETE echo "Old Kubernetes API Version: $old_k8s_api_version" echo "New Kubernetes API Version: $new_k8s_api_version" +# If it's an actual release, pull master branch +if [[ $CLIENT_VERSION != *"snapshot"* ]]; then + git pull -X theirs upstream master + + # Collect release notes from master branch + start_sha=$(git log upstream/release-19.0..upstream/master | grep ^commit | tail -n1 | sed 's/commit //g') + end_sha=$(git log upstream/release-19.0..upstream/master | grep ^commit | head -n1 | sed 's/commit //g') + output="/tmp/python-master-relnote.md" + release-notes --dependencies=false --org kubernetes-client --repo python --start-sha $start_sha --end-sha $end_sha --output $output + sed -i 's/(\[\#/(\[kubernetes-client\/python\#/g' $output + + IFS_backup=$IFS + IFS=$'\n' + sections=($(grep "^### " $output)) + IFS=$IFS_backup + for section in "${sections[@]}"; do + # ignore section titles and empty lines; replace newline with liternal "\n" + master_release_notes=$(sed -n "/$section/,/###/{/###/!p}" $output | sed -n "{/^$/!p}" | sed ':a;N;$!ba;s/\n/\\n/g') + util::changelog::write_changelog v$CLIENT_VERSION "$section" "$master_release_notes" + done + git add . + if ! git diff-index --quiet --cached HEAD; then + util::changelog::update_release_api_version $CLIENT_VERSION $CLIENT_VERSION $new_k8s_api_version + git add . + git commit -m "update changelog with release notes from master branch" + fi +fi + # Update version constants sed -i "s/^KUBERNETES_BRANCH =.*$/KUBERNETES_BRANCH = \"$KUBERNETES_BRANCH\"/g" scripts/constants.py sed -i "s/^CLIENT_VERSION =.*$/CLIENT_VERSION = \"$CLIENT_VERSION\"/g" scripts/constants.py From 606b64e45449352bf1015f3b2cf80b3b48646cde Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 20:51:46 -0700 Subject: [PATCH 5/7] Accept the automatically generated merge commit message --- scripts/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release.sh b/scripts/release.sh index 08251e8d5..d19dc6a11 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -137,7 +137,7 @@ echo "New Kubernetes API Version: $new_k8s_api_version" # If it's an actual release, pull master branch if [[ $CLIENT_VERSION != *"snapshot"* ]]; then - git pull -X theirs upstream master + git pull -X theirs upstream master --no-edit # Collect release notes from master branch start_sha=$(git log upstream/release-19.0..upstream/master | grep ^commit | tail -n1 | sed 's/commit //g') From a9085a80554477e340507237fca641be001c98bb Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Sun, 24 Oct 2021 20:57:09 -0700 Subject: [PATCH 6/7] Skip unnecessary changelog update. Update print message. --- scripts/release.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index d19dc6a11..778e15628 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -180,12 +180,12 @@ git commit -am "update version constants for $CLIENT_VERSION release" # TODO(roycaihw): not all Kubernetes API changes modify the OpenAPI spec. # Download the patch and skip if the spec is not modified. Also we want to # look at other k/k sections like "deprecation" -util::changelog::update_release_api_version $CLIENT_VERSION $old_client_version $new_k8s_api_version release_notes=$(util::kube_changelog::get_api_changelog "$KUBERNETES_BRANCH" "$old_k8s_api_version") if [[ -n "$release_notes" ]]; then util::changelog::write_changelog v$CLIENT_VERSION "### API Change" "$release_notes" fi -git commit -am "update changelog" +git add . +git diff-index --quiet --cached HEAD || git commit -am "update changelog" # Re-generate the client scripts/update-client.sh @@ -210,4 +210,4 @@ git diff-index --quiet --cached HEAD || git commit -m "generated API change" git add . git commit -m "generated client change" -echo "Release finished successfully." +echo "Release finished successfully. Please create a PR from branch ${newbranchuniq}." From cedbcf304fc282ee512de2139657e66e951ddf3b Mon Sep 17 00:00:00 2001 From: Haowei Cai Date: Mon, 25 Oct 2021 10:54:08 -0700 Subject: [PATCH 7/7] fixup! Collect release notes from master branch --- scripts/release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index 778e15628..e2c3da6e7 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -140,8 +140,8 @@ if [[ $CLIENT_VERSION != *"snapshot"* ]]; then git pull -X theirs upstream master --no-edit # Collect release notes from master branch - start_sha=$(git log upstream/release-19.0..upstream/master | grep ^commit | tail -n1 | sed 's/commit //g') - end_sha=$(git log upstream/release-19.0..upstream/master | grep ^commit | head -n1 | sed 's/commit //g') + start_sha=$(git log ${remote_branch}..upstream/master | grep ^commit | tail -n1 | sed 's/commit //g') + end_sha=$(git log ${remote_branch}..upstream/master | grep ^commit | head -n1 | sed 's/commit //g') output="/tmp/python-master-relnote.md" release-notes --dependencies=false --org kubernetes-client --repo python --start-sha $start_sha --end-sha $end_sha --output $output sed -i 's/(\[\#/(\[kubernetes-client\/python\#/g' $output