1+ #! /bin/bash
2+
3+ # Copyright 2025 The Volcano Authors.
4+ #
5+ # Licensed under the Apache License, Version 2.0 (the "License");
6+ # you may not use this file except in compliance with the License.
7+ # You may obtain a copy of the License at
8+ #
9+ # http://www.apache.org/licenses/LICENSE-2.0
10+ #
11+ # Unless required by applicable law or agreed to in writing, software
12+ # distributed under the License is distributed on an "AS IS" BASIS,
13+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ # See the License for the specific language governing permissions and
15+ # limitations under the License.
16+
17+ set -o errexit
18+ set -o nounset
19+ set -o pipefail
20+
21+ REPO_ROOT=" $( git rev-parse --show-toplevel) "
22+ declare -r REPO_ROOT
23+ cd " ${REPO_ROOT} "
24+
25+ declare -r STARTINGBRANCH=$( git symbolic-ref --short HEAD)
26+ declare -r REBASEMAGIC=" ${REPO_ROOT} /.git/rebase-apply"
27+
28+ RELEASE_VERSION_FILE=" .release-version"
29+ CHART_YAML=" installer/helm/chart/volcano/Chart.yaml"
30+ VALUES_YAML=" installer/helm/chart/volcano/values.yaml"
31+ DRY_RUN=${DRY_RUN:- " " }
32+ UPSTREAM_REMOTE=${UPSTREAM_REMOTE:- upstream}
33+ FORK_REMOTE=${FORK_REMOTE:- origin}
34+ MAIN_REPO_ORG=${MAIN_REPO_ORG:- $(git remote get-url " $UPSTREAM_REMOTE " | awk ' {gsub(/http[s]:\/\/|git@/,"")}1' | awk -F' [@:./]' ' NR==1{print $3}' )}
35+ MAIN_REPO_NAME=${MAIN_REPO_NAME:- $(git remote get-url " $UPSTREAM_REMOTE " | awk ' {gsub(/http[s]:\/\/|git@/,"")}1' | awk -F' [@:./]' ' NR==1{print $4}' )}
36+
37+ # Track if we've successfully completed all operations
38+ SUCCESS_MARKER=" "
39+ cleanbranch=" "
40+
41+ if [[ -z ${GITHUB_USER:- } ]]; then
42+ echo " Please export GITHUB_USER=<your-user> (or GH organization, if that's where your fork lives)"
43+ exit 1
44+ fi
45+
46+ # Check if gh CLI is available
47+ if ! command -v gh > /dev/null; then
48+ echo " Can't find 'gh' tool in PATH, please install from https://github.com/cli/cli"
49+ exit 1
50+ fi
51+
52+ if [[ " $# " -ne 2 ]]; then
53+ echo " ${0} <remote branch> <new-version>: bump version on <remote branch> and create a PR"
54+ echo " "
55+ echo " Checks out <remote branch> and handles the version bump for you."
56+ echo " Examples:"
57+ echo " $0 upstream/master v1.13.0 # Bump to v1.13.0 based on upstream/master"
58+ echo " $0 upstream/release-1.12 v1.12.1 # Bump to v1.12.1 based on upstream/release-1.12"
59+ echo " "
60+ echo " Set the DRY_RUN environment var to skip git push and creating PR."
61+ echo " When DRY_RUN is set the script will leave you in a branch containing the version changes."
62+ echo " "
63+ echo " Set UPSTREAM_REMOTE (default: upstream) and FORK_REMOTE (default: origin)"
64+ echo " To override the default remote names to what you have locally."
65+ exit 1
66+ fi
67+
68+ declare -r BRANCH=" $1 "
69+ declare -r NEW_VERSION=" $2 "
70+
71+ # Validate version format
72+ if [[ ! " ${NEW_VERSION} " =~ ^v[0-9]+\. [0-9]+\. [0-9]+.* $ ]]; then
73+ echo " Error: Version must follow format vX.Y.Z (e.g., v1.12.0, v1.12.1-beta1)"
74+ exit 1
75+ fi
76+
77+ # Checks if you are logged in. Will error/bail if you are not.
78+ gh auth status
79+
80+ if git_status=$( git status --porcelain --untracked=no 2> /dev/null) && [[ -n " ${git_status} " ]]; then
81+ echo " !!! Dirty tree. Clean up and try again."
82+ exit 1
83+ fi
84+
85+ if [[ -e " ${REBASEMAGIC} " ]]; then
86+ echo " !!! 'git rebase' or 'git am' in progress. Clean up and try again."
87+ exit 1
88+ fi
89+
90+ # Extract chart version
91+ CHART_VERSION=${NEW_VERSION# v}
92+
93+ echo " +++ Updating remotes..."
94+ git remote update " ${UPSTREAM_REMOTE} " " ${FORK_REMOTE} "
95+
96+ if ! git log -n1 --format=%H " ${BRANCH} " > /dev/null 2>&1 ; then
97+ echo " !!! '${BRANCH} ' not found. The first argument should be something like ${UPSTREAM_REMOTE} /master or ${UPSTREAM_REMOTE} /release-1.12."
98+ echo " (In particular, it needs to be a valid, existing remote branch that I can 'git checkout'.)"
99+ exit 1
100+ fi
101+
102+ declare -r NEWBRANCHREQ=" automated-version-bump-${NEW_VERSION} "
103+ declare -r NEWBRANCH=" $( echo " ${NEWBRANCHREQ} -${BRANCH} " | sed ' s/\//-/g' ) "
104+ declare -r NEWBRANCHUNIQ=" ${NEWBRANCH} -$( date +%s) "
105+
106+ function return_to_kansas {
107+ # return to the starting branch and clean up
108+ local current_branch
109+ current_branch=$( git symbolic-ref --short HEAD 2> /dev/null || echo " " )
110+
111+ if [[ -n " ${cleanbranch} " && " ${current_branch} " == " ${cleanbranch} " ]]; then
112+ # We're on the temporary branch we created
113+ if [[ -z " ${SUCCESS_MARKER} " ]]; then
114+ echo " "
115+ echo " !!! Script failed during execution. Cleaning up uncommitted changes..."
116+ # Reset any uncommitted changes
117+ git reset --hard HEAD > /dev/null 2>&1 || true
118+ # Clean any untracked files that might have been created
119+ git clean -fd > /dev/null 2>&1 || true
120+
121+ echo " "
122+ echo " +++ Returning you to the ${STARTINGBRANCH} branch and cleaning up."
123+ git checkout -f " ${STARTINGBRANCH} " > /dev/null 2>&1 || true
124+
125+ # Delete the temporary branch
126+ git branch -D " ${cleanbranch} " > /dev/null 2>&1 || true
127+ elif [[ -n " ${DRY_RUN} " ]]; then
128+ # DRY_RUN mode and successful - leave user in the branch to inspect changes
129+ echo " "
130+ echo " !!! DRY_RUN mode: Leaving you in branch ${cleanbranch} to inspect changes."
131+ echo " To return to the branch you were in when you invoked this script:"
132+ echo " "
133+ echo " git checkout ${STARTINGBRANCH} "
134+ echo " "
135+ echo " To delete this branch:"
136+ echo " "
137+ echo " git branch -D ${cleanbranch} "
138+ else
139+ # Non-DRY_RUN mode and successful - normal cleanup
140+ echo " "
141+ echo " +++ Returning you to the ${STARTINGBRANCH} branch and cleaning up."
142+ git checkout -f " ${STARTINGBRANCH} " > /dev/null 2>&1 || true
143+
144+ # Delete the temporary branch
145+ git branch -D " ${cleanbranch} " > /dev/null 2>&1 || true
146+ fi
147+ fi
148+ }
149+ trap return_to_kansas EXIT
150+
151+ function make-a-pr() {
152+ local target_branch=" $( basename " ${BRANCH} " ) "
153+ echo
154+ echo " +++ Creating a pull request on GitHub at ${GITHUB_USER} :${NEWBRANCH} "
155+
156+ local pr_body=" This is an automated version bump created by \` hack/bump-version.sh\` .
157+
158+ **Target branch:** \` ${BRANCH} \`
159+ **New version:** \` ${NEW_VERSION} \`
160+
161+ **Changes:**
162+ - Update \` .release-version\` to \` ${NEW_VERSION} \`
163+ - Update Helm Chart version to \` ${CHART_VERSION} \`
164+ - Update default image tag to \` ${NEW_VERSION} \`
165+ - Update \` volcano.sh/apis\` dependency to \` ${NEW_VERSION} \`
166+ - Update development YAML files (\` volcano-development.yaml\` , \` volcano-agent-development.yaml\` , \` volcano-monitoring.yaml\` )
167+ - Run \` go mod tidy\`
168+
169+ **Next steps after merging:**
170+ 1. Tag the release: \` git tag ${NEW_VERSION} && git push ${UPSTREAM_REMOTE} ${NEW_VERSION} \`
171+ 2. This will trigger automated image and chart publishing"
172+
173+ gh pr create \
174+ --title " Automated: Bump version to ${NEW_VERSION} " \
175+ --body " ${pr_body} " \
176+ --base " ${target_branch} " \
177+ --head " ${GITHUB_USER} :${NEWBRANCH} " \
178+ --repo " ${MAIN_REPO_ORG} /${MAIN_REPO_NAME} "
179+ }
180+
181+ echo " +++ Creating local branch ${NEWBRANCHUNIQ} based on ${BRANCH} "
182+ git checkout -b " ${NEWBRANCHUNIQ} " " ${BRANCH} "
183+ cleanbranch=" ${NEWBRANCHUNIQ} "
184+
185+ echo " "
186+ echo " === Bumping version to ${NEW_VERSION} ==="
187+
188+ # Update .release-version
189+ echo " +++ Updating ${RELEASE_VERSION_FILE} "
190+ echo " ${NEW_VERSION} " > " ${RELEASE_VERSION_FILE} "
191+
192+ # Update Chart.yaml
193+ echo " +++ Updating ${CHART_YAML} "
194+ if [[ -f " ${CHART_YAML} " ]]; then
195+ sed -i.bak " s/^version: .*/version: \" ${CHART_VERSION} \" /" " ${CHART_YAML} "
196+ sed -i.bak " s/^appVersion: .*/appVersion: \" ${NEW_VERSION} \" /" " ${CHART_YAML} "
197+ rm -f " ${CHART_YAML} .bak"
198+ fi
199+
200+ # Update values.yaml
201+ echo " +++ Updating ${VALUES_YAML} "
202+ if [[ -f " ${VALUES_YAML} " ]]; then
203+ sed -i.bak " s/image_tag_version: .*/image_tag_version: \" ${NEW_VERSION} \" /" " ${VALUES_YAML} "
204+ rm -f " ${VALUES_YAML} .bak"
205+ fi
206+
207+ # Update go.mod
208+ echo " +++ Updating go.mod"
209+ if [[ -f " go.mod" ]]; then
210+ sed -i.bak " s|volcano.sh/apis v.*|volcano.sh/apis ${NEW_VERSION} |" go.mod
211+ rm -f go.mod.bak
212+
213+ echo " +++ Running go mod tidy"
214+ go mod tidy
215+ fi
216+
217+ # Update development YAML files
218+ echo " +++ Updating development YAML files"
219+ if [[ -f " Makefile" ]]; then
220+ echo " +++ Running make TAG=${NEW_VERSION} update-development-yaml"
221+ make TAG=" ${NEW_VERSION} " update-development-yaml
222+ fi
223+
224+ echo " "
225+ echo " Files updated successfully!"
226+
227+ if [[ -n " ${DRY_RUN} " ]]; then
228+ echo " !!! Skipping git push and PR creation because you set DRY_RUN."
229+ # Mark successful completion in DRY_RUN mode
230+ SUCCESS_MARKER=" true"
231+ exit 0
232+ fi
233+
234+ # Commit changes
235+ echo " +++ Committing changes"
236+ git add .
237+ git commit -s -m " chore: bump version to ${NEW_VERSION}
238+
239+ - Update .release-version to ${NEW_VERSION}
240+ - Update Chart version to ${CHART_VERSION}
241+ - Update image tag version to ${NEW_VERSION}
242+ - Update volcano.sh/apis dependency to ${NEW_VERSION}
243+ - Update development YAML files"
244+
245+ if git remote -v | grep ^" ${FORK_REMOTE} " | grep " ${MAIN_REPO_ORG} /${MAIN_REPO_NAME} .git" ; then
246+ echo " !!! You have ${FORK_REMOTE} configured as your ${MAIN_REPO_ORG} /${MAIN_REPO_NAME} .git"
247+ echo " This isn't normal. Leaving you with push instructions:"
248+ echo
249+ echo " +++ First manually push the branch this script created:"
250+ echo
251+ echo " git push REMOTE ${NEWBRANCHUNIQ} :${NEWBRANCH} "
252+ echo
253+ echo " where REMOTE is your personal fork (maybe ${UPSTREAM_REMOTE} ? Consider swapping those.)."
254+ echo " OR consider setting UPSTREAM_REMOTE and FORK_REMOTE to different values."
255+ echo
256+ make-a-pr
257+ cleanbranch=" "
258+ exit 0
259+ fi
260+
261+ # Push branch
262+ git push " ${FORK_REMOTE} " " ${NEWBRANCHUNIQ} :${NEWBRANCH} "
263+
264+ make-a-pr
265+
266+ echo " "
267+ echo " ✅ Version bump completed successfully!"
268+
269+ # Mark successful completion
270+ SUCCESS_MARKER=" true"
0 commit comments