@@ -67,35 +67,109 @@ set -o errexit
6767set -o nounset
6868set -o pipefail
6969
70- # used by the client generator: https://github.com/kubernetes-client/gen/blob/729332ad08f0f4d98983b7beb027e2f657236ef9/openapi/openapi-generator/client-generator.sh#L52
71- export USERNAME=kubernetes
70+ # Verify git status
71+ if git_status=$( git status --porcelain --untracked=no 2> /dev/null) && [[ -n " ${git_status} " ]]; then
72+ echo " !!! Dirty tree. Clean up and try again."
73+ exit 1
74+ fi
75+
76+ REPO_ROOT=" $( git rev-parse --show-toplevel) "
77+ declare -r REPO_ROOT
78+ cd " ${REPO_ROOT} "
79+ declare -r REBASEMAGIC=" ${REPO_ROOT} /.git/rebase-apply"
80+ if [[ -e " ${REBASEMAGIC} " ]]; then
81+ echo " !!! 'git rebase' or 'git am' in progress. Clean up and try again."
82+ exit 1
83+ fi
7284
73- repo_root=" $( git rev-parse --show-toplevel) "
74- declare -r repo_root
75- cd " ${repo_root} "
85+ # Set constants used by the client generator.
86+ export USERNAME=kubernetes
7687
88+ # Set up utilities.
7789source scripts/util/changelog.sh
7890source scripts/util/kube_changelog.sh
7991
80- old_client_version=$( python3 " scripts/constants.py" CLIENT_VERSION)
81- old_k8s_api_version=$( util::changelog::get_k8s_api_version " v$old_client_version " )
92+ # Read user inputs or values locally.
8293KUBERNETES_BRANCH=${KUBERNETES_BRANCH:- $(python3 " scripts/constants.py" KUBERNETES_BRANCH)}
8394CLIENT_VERSION=${CLIENT_VERSION:- $(python3 " scripts/constants.py" CLIENT_VERSION)}
8495DEVELOPMENT_STATUS=${DEVELOPMENT_STATUS:- $(python3 " scripts/constants.py" DEVELOPMENT_STATUS)}
8596
86- # get Kubernetes API Version
97+ # Create a local branch
98+ STARTINGBRANCH=$( git symbolic-ref --short HEAD)
99+ declare -r STARTINGBRANCH
100+ gitamcleanup=false
101+ function return_to_kansas {
102+ if [[ " ${gitamcleanup} " == " true" ]]; then
103+ echo
104+ echo " +++ Aborting in-progress git am."
105+ git am --abort > /dev/null 2>&1 || true
106+ fi
107+
108+ echo " +++ Returning you to the ${STARTINGBRANCH} branch and cleaning up."
109+ git checkout -f " ${STARTINGBRANCH} " > /dev/null 2>&1 || true
110+ }
111+ trap return_to_kansas EXIT
112+
113+ remote_branch=upstream/master
114+ if [[ $CLIENT_VERSION != * " snapshot" * ]]; then
115+ remote_branch=upstream/release-" ${CLIENT_VERSION%% .* } " .0
116+ fi
117+ echo " +++ Updating remotes..."
118+ git remote update upstream origin
119+ if ! git log -n1 --format=%H " ${remote_branch} " > /dev/null 2>&1 ; then
120+ echo " !!! '${remote_branch} ' not found."
121+ echo " (In particular, it needs to be a valid, existing remote branch that I can 'git checkout'.)"
122+ exit 1
123+ fi
124+
125+ newbranch=" $( echo " automated-release-of-${CLIENT_VERSION} -${remote_branch} " | sed ' s/\//-/g' ) "
126+ newbranchuniq=" ${newbranch} -$( date +%s) "
127+ declare -r newbranchuniq
128+ echo " +++ Creating local branch ${newbranchuniq} "
129+ git checkout -b " ${newbranchuniq} " " ${remote_branch} "
130+
131+ # Get Kubernetes API versions
132+ old_client_version=$( python3 " scripts/constants.py" CLIENT_VERSION)
133+ old_k8s_api_version=$( util::changelog::get_k8s_api_version " v$old_client_version " )
87134new_k8s_api_version=$( util::kube_changelog::find_latest_patch_version $KUBERNETES_BRANCH )
88135echo " Old Kubernetes API Version: $old_k8s_api_version "
89136echo " New Kubernetes API Version: $new_k8s_api_version "
90137
138+ # If it's an actual release, pull master branch
139+ if [[ $CLIENT_VERSION != * " snapshot" * ]]; then
140+ git pull -X theirs upstream master --no-edit
141+
142+ # Collect release notes from master branch
143+ start_sha=$( git log ${remote_branch} ..upstream/master | grep ^commit | tail -n1 | sed ' s/commit //g' )
144+ end_sha=$( git log ${remote_branch} ..upstream/master | grep ^commit | head -n1 | sed ' s/commit //g' )
145+ output=" /tmp/python-master-relnote.md"
146+ release-notes --dependencies=false --org kubernetes-client --repo python --start-sha $start_sha --end-sha $end_sha --output $output
147+ sed -i ' s/(\[\#/(\[kubernetes-client\/python\#/g' $output
148+
149+ IFS_backup=$IFS
150+ IFS=$' \n '
151+ sections=($( grep " ^### " $output ) )
152+ IFS=$IFS_backup
153+ for section in " ${sections[@]} " ; do
154+ # ignore section titles and empty lines; replace newline with liternal "\n"
155+ master_release_notes=$( sed -n " /$section /,/###/{/###/!p}" $output | sed -n " {/^$/!p}" | sed ' :a;N;$!ba;s/\n/\\n/g' )
156+ util::changelog::write_changelog v$CLIENT_VERSION " $section " " $master_release_notes "
157+ done
158+ git add .
159+ if ! git diff-index --quiet --cached HEAD; then
160+ util::changelog::update_release_api_version $CLIENT_VERSION $CLIENT_VERSION $new_k8s_api_version
161+ git add .
162+ git commit -m " update changelog with release notes from master branch"
163+ fi
164+ fi
165+
166+ # Update version constants
91167sed -i " s/^KUBERNETES_BRANCH =.*$/KUBERNETES_BRANCH = \" $KUBERNETES_BRANCH \" /g" scripts/constants.py
92168sed -i " s/^CLIENT_VERSION =.*$/CLIENT_VERSION = \" $CLIENT_VERSION \" /g" scripts/constants.py
93- sed -i " s/ ^DEVELOPMENT_STATUS =.*$/ DEVELOPMENT_STATUS = \" $DEVELOPMENT_STATUS \" / g" scripts/constants.py
169+ sed -i " s: ^DEVELOPMENT_STATUS =.*$: DEVELOPMENT_STATUS = \" $DEVELOPMENT_STATUS \" : g" scripts/constants.py
94170git commit -am " update version constants for $CLIENT_VERSION release"
95171
96- util::changelog::update_release_api_version $CLIENT_VERSION $old_client_version $new_k8s_api_version
97-
98- # get API change release notes since $old_k8s_api_version.
172+ # Update CHANGELOG with API change release notes since $old_k8s_api_version.
99173# NOTE: $old_k8s_api_version may be one-minor-version behind $KUBERNETES_BRANCH, e.g.
100174# KUBERNETES_BRANCH=release-1.19
101175# old_k8s_api_version=1.18.17
@@ -110,26 +184,30 @@ release_notes=$(util::kube_changelog::get_api_changelog "$KUBERNETES_BRANCH" "$o
110184if [[ -n " $release_notes " ]]; then
111185 util::changelog::write_changelog v$CLIENT_VERSION " ### API Change" " $release_notes "
112186fi
187+ git add .
188+ git diff-index --quiet --cached HEAD || git commit -am " update changelog"
113189
114- git commit -am " update changelog"
115-
116- # run client generator
190+ # Re-generate the client
117191scripts/update-client.sh
118192
193+ # Apply hotfixes
119194rm -r kubernetes/test/
120195git add .
121196git commit -m " temporary generated commit"
122197scripts/apply-hotfixes.sh
123198git reset HEAD~2
124- # custom object API is hosted in gen repo. Commit API change separately for
125- # easier review
199+
200+ # Custom object API is hosted in gen repo. Commit custom object API change
201+ # separately for easier review
126202if [[ -n " $( git diff kubernetes/client/api/custom_objects_api.py) " ]]; then
127203 git add kubernetes/client/api/custom_objects_api.py
128204 git commit -m " generated client change for custom_objects"
129205fi
206+ # Check if there is any API change, then commit
130207git add kubernetes/docs kubernetes/client/api/ kubernetes/client/models/ kubernetes/swagger.json.unprocessed scripts/swagger.json
131- # verify if there are staged changes, then commit
132208git diff-index --quiet --cached HEAD || git commit -m " generated API change"
209+ # Commit everything else
133210git add .
134211git commit -m " generated client change"
135- echo " Release finished successfully."
212+
213+ echo " Release finished successfully. Please create a PR from branch ${newbranchuniq} ."
0 commit comments