1+ #! /bin/bash
2+
3+ set -e
4+
5+ REPO_NAME=" cloudsmith-api-go"
6+ REPO_URL=" https://github.com/cloudsmith-io/cloudsmith-api-go"
7+ BRANCH_PREFIX=" update-bindings"
8+ GENERATE_SCRIPT=" bin/generate"
9+
10+ RED=' \033[0;31m'
11+ GREEN=' \033[0;32m'
12+ YELLOW=' \033[1;33m'
13+ BLUE=' \033[0;34m'
14+ NC=' \033[0m'
15+
16+ log_info () {
17+ echo -e " ${BLUE} [INFO]${NC} $1 "
18+ }
19+
20+ log_success () {
21+ echo -e " ${GREEN} [SUCCESS]${NC} $1 "
22+ }
23+
24+ log_warning () {
25+ echo -e " ${YELLOW} [WARNING]${NC} $1 "
26+ }
27+
28+ log_error () {
29+ echo -e " ${RED} [ERROR]${NC} $1 "
30+ }
31+
32+ check_dependencies () {
33+ log_info " Checking dependencies..."
34+
35+ local missing_deps=()
36+
37+ if ! command -v git & > /dev/null; then
38+ missing_deps+=(" git" )
39+ fi
40+
41+ if [ ${# missing_deps[@]} -ne 0 ]; then
42+ log_error " Missing dependencies: ${missing_deps[*]} "
43+ log_error " Please install the missing dependencies and try again."
44+ exit 1
45+ fi
46+
47+ log_success " All dependencies are installed"
48+ }
49+
50+ validate_version () {
51+ local version=" $1 "
52+ if [[ ! $version =~ ^[0-9]+\. [0-9]+\. [0-9]+$ ]]; then
53+ log_error " Invalid version format: $version "
54+ log_error " Version should be in format: X.Y.Z (e.g., 1.2.3)"
55+ exit 1
56+ fi
57+ }
58+
59+ get_current_version () {
60+ if [ ! -f " $GENERATE_SCRIPT " ]; then
61+ log_error " File $GENERATE_SCRIPT not found"
62+ exit 1
63+ fi
64+
65+ local current_version=$( grep -E " ^PKG_VERSION=" " $GENERATE_SCRIPT " | cut -d' =' -f2 | tr -d ' "' | tr -d " '" )
66+
67+ # Handle cases where the version might be a parameter expansion like ${1:-"0.0.46"}
68+ if [[ $current_version =~ ^\$\{ .* :-\" ? ([0-9]+\. [0-9]+\. [0-9]+)\" ? \} ]]; then
69+ current_version=" ${BASH_REMATCH[1]} "
70+ fi
71+
72+ echo " $current_version "
73+ }
74+
75+ increment_patch_version () {
76+ local version=" $1 "
77+ local major minor patch
78+
79+ IFS=' .' read -r major minor patch <<< " $version"
80+ patch=$(( patch + 1 ))
81+ echo " ${major} .${minor} .${patch} "
82+ }
83+
84+ get_api_version () {
85+ local api_url=" https://api.cloudsmith.io/"
86+ log_info " Fetching current API version from Cloudsmith..." >&2
87+
88+ local api_version=$( curl -s " ${api_url} status/check/basic/" 2> /dev/null | jq -r ' .version' 2> /dev/null)
89+
90+ if [ " $api_version " = " null" ] || [ -z " $api_version " ]; then
91+ log_warning " Could not fetch API version from Cloudsmith API" >&2
92+ return 1
93+ fi
94+
95+ echo " $api_version "
96+ }
97+
98+ update_version () {
99+ local new_version=" $1 "
100+ local current_version=$( get_current_version)
101+
102+ log_info " Updating version from $current_version to $new_version "
103+
104+ log_info " Current PKG_VERSION line:"
105+ grep " PKG_VERSION" " $GENERATE_SCRIPT " || {
106+ log_error " No PKG_VERSION line found in $GENERATE_SCRIPT "
107+ exit 1
108+ }
109+
110+ cp " $GENERATE_SCRIPT " " $GENERATE_SCRIPT .backup"
111+
112+ # Update the parameter expansion to use the new version as the default
113+ sed -i.bak " s/PKG_VERSION=\$ {1:-\" [^\" ]*\" }/PKG_VERSION=\$ {1:-\" $new_version \" }/" " $GENERATE_SCRIPT "
114+
115+ updated_version=$( get_current_version)
116+ if [ " $updated_version " != " $new_version " ]; then
117+ log_error " Failed to update version in $GENERATE_SCRIPT "
118+ log_error " Expected: $new_version , Got: $updated_version "
119+
120+ log_error " Updated PKG_VERSION line:"
121+ grep " PKG_VERSION" " $GENERATE_SCRIPT " || log_error " No PKG_VERSION line found"
122+
123+ mv " $GENERATE_SCRIPT .backup" " $GENERATE_SCRIPT "
124+ exit 1
125+ fi
126+
127+ rm " $GENERATE_SCRIPT .backup" " $GENERATE_SCRIPT .bak" 2> /dev/null || true
128+ log_success " Version updated successfully"
129+ }
130+
131+ generate_bindings () {
132+ log_info " Generating Go bindings..."
133+
134+ if [ ! -x " $GENERATE_SCRIPT " ]; then
135+ log_warning " Making $GENERATE_SCRIPT executable"
136+ chmod +x " $GENERATE_SCRIPT "
137+ fi
138+
139+ if ./" $GENERATE_SCRIPT " ; then
140+ log_success " Go bindings generated successfully"
141+ else
142+ log_error " Failed to generate Go bindings"
143+ exit 1
144+ fi
145+ }
146+
147+ create_and_push_branch () {
148+ local version=" $1 "
149+ local api_version=" $2 "
150+ local branch_name=" ${BRANCH_PREFIX} -v${version} "
151+
152+ log_info " Creating branch: $branch_name "
153+
154+ if git show-ref --verify --quiet " refs/heads/$branch_name " ; then
155+ log_warning " Branch $branch_name already exists locally. Deleting it."
156+ git branch -D " $branch_name "
157+ fi
158+
159+ if git ls-remote --heads origin " $branch_name " | grep -q " $branch_name " ; then
160+ log_warning " Branch $branch_name already exists on remote."
161+ read -p " Do you want to delete the remote branch and create a new one? (y/N): " -n 1 -r
162+ echo
163+ if [[ $REPLY =~ ^[Yy]$ ]]; then
164+ log_info " Deleting remote branch $branch_name ..."
165+ git push origin --delete " $branch_name " || {
166+ log_warning " Could not delete remote branch (it might not exist or you might not have permissions)"
167+ }
168+ else
169+ local timestamp=$( date +" %Y%m%d-%H%M%S" )
170+ branch_name=" ${BRANCH_PREFIX} -v${version} -${timestamp} "
171+ log_info " Using unique branch name: $branch_name "
172+ fi
173+ fi
174+
175+ git checkout -b " $branch_name "
176+ git add .
177+
178+ if git diff --staged --quiet; then
179+ log_warning " No changes to commit. The bindings might already be up to date."
180+ return 1
181+ fi
182+
183+ git commit -m " Update Go API bindings to version $version
184+
185+ Binding version: $version
186+ Cloudsmith API version: $api_version
187+
188+ - Updated PKG_VERSION in bin/generate
189+ - Regenerated Go bindings
190+ - Ready for tagging and release"
191+
192+ log_info " Pushing branch to origin..."
193+ if ! git push origin " $branch_name " ; then
194+ log_warning " Normal push failed, trying force push..."
195+ git push origin " $branch_name " --force-with-lease || {
196+ log_error " Failed to push branch even with force. Check your permissions."
197+ exit 1
198+ }
199+ fi
200+
201+ log_success " Branch created and pushed successfully"
202+ echo " $branch_name "
203+ }
204+
205+ create_tag_and_release_instructions () {
206+ local version=" $1 "
207+ local tag_name=" v${version} "
208+
209+ echo " "
210+ log_info " After the PR is merged, create a git tag and release:"
211+ echo " "
212+ echo " 1. Switch to master and pull latest changes:"
213+ echo " git checkout master"
214+ echo " git pull"
215+ echo " "
216+ echo " 2. Create and push the tag:"
217+ echo " git tag -a $tag_name -m \" Release version $version \" "
218+ echo " git push origin $tag_name "
219+ echo " "
220+ echo " 3. Go to GitHub releases page and create a new release:"
221+ echo " - Select tag: $tag_name "
222+ echo " - Release title: Release $version "
223+ echo " - Add release notes as needed"
224+ echo " "
225+ }
226+
227+ usage () {
228+ echo " Usage: $0 [OPTIONS]"
229+ echo " "
230+ echo " Preferred usage (no arguments - auto-increments patch version):"
231+ echo " $0 # Auto-increment patch version and fetch latest API version"
232+ echo " "
233+ echo " Options:"
234+ echo " -v, --version VERSION Specific binding version (optional)"
235+ echo " -h, --help Show this help message"
236+ echo " "
237+ echo " Examples:"
238+ echo " $0 # Preferred: auto-increment patch version"
239+ echo " $0 -v 1.3.0 # Specify custom version (e.g. minor/major bump)"
240+ echo " $0 --version 1.2.5 # Long form"
241+ echo " "
242+ echo " Note:"
243+ echo " - When run without arguments, the script will:"
244+ echo " * Auto-increment the patch version (e.g. 1.2.3 -> 1.2.4)"
245+ echo " * Auto-fetch the latest Cloudsmith API version"
246+ echo " - Use -v only for larger version increments (minor/major bumps)"
247+ echo " - After PR is merged, you'll need to create a git tag and GitHub release"
248+ }
249+
250+ main () {
251+ local new_version=" "
252+ local auto_increment=true
253+
254+ while [[ $# -gt 0 ]]; do
255+ case $1 in
256+ -v|--version)
257+ new_version=" $2 "
258+ auto_increment=false
259+ shift 2
260+ ;;
261+ -h|--help)
262+ usage
263+ exit 0
264+ ;;
265+ * )
266+ log_error " Unknown option: $1 "
267+ usage
268+ exit 1
269+ ;;
270+ esac
271+ done
272+
273+ check_dependencies
274+
275+ local current_version=$( get_current_version)
276+ log_info " Current version: $current_version "
277+
278+ if [ " $auto_increment " = true ]; then
279+ new_version=$( increment_patch_version " $current_version " )
280+ log_info " Auto-incrementing patch version to: $new_version "
281+ else
282+ validate_version " $new_version "
283+ log_info " Using specified version: $new_version "
284+ fi
285+
286+ local api_version
287+ if api_version=$( get_api_version) ; then
288+ log_info " Auto-fetched API version: $api_version "
289+ else
290+ log_error " Failed to auto-fetch API version"
291+ log_error " Please check your internet connection and try again"
292+ exit 1
293+ fi
294+
295+ validate_version " $new_version "
296+ validate_version " $api_version "
297+
298+ log_info " Starting Cloudsmith Go API bindings update process..."
299+ log_info " New binding version: $new_version "
300+ log_info " API version: $api_version "
301+
302+ if [ " $current_version " = " $new_version " ]; then
303+ log_warning " Version $new_version is the same as current version"
304+ read -p " Do you want to continue anyway? (y/N): " -n 1 -r
305+ echo
306+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
307+ log_info " Operation cancelled"
308+ exit 0
309+ fi
310+ fi
311+
312+ local current_branch=$( git branch --show-current)
313+ log_info " Current branch: $current_branch "
314+
315+ if [[ " $current_branch " == " main" || " $current_branch " == " master" ]]; then
316+ log_info " Already on main branch ($current_branch )"
317+ else
318+ if ! git diff-index --quiet HEAD --; then
319+ log_error " You have uncommitted changes. Please commit or stash them first:"
320+ git status --short
321+ exit 1
322+ fi
323+
324+ log_info " Switching to main branch..."
325+
326+ if git show-ref --verify --quiet refs/heads/main; then
327+ git checkout main || {
328+ log_error " Could not switch to main branch"
329+ exit 1
330+ }
331+ elif git show-ref --verify --quiet refs/heads/master; then
332+ git checkout master || {
333+ log_error " Could not switch to master branch"
334+ exit 1
335+ }
336+ else
337+ log_error " Neither 'main' nor 'master' branch found"
338+ log_error " Available branches:"
339+ git branch -a
340+ exit 1
341+ fi
342+ fi
343+
344+ log_info " Pulling latest changes..."
345+ git pull origin $( git branch --show-current)
346+
347+ update_version " $new_version "
348+ generate_bindings
349+
350+ local branch_name
351+ if branch_name=$( create_and_push_branch " $new_version " " $api_version " ) ; then
352+ log_success " Automation completed successfully!"
353+ create_tag_and_release_instructions " $new_version "
354+ else
355+ log_warning " No changes detected. The bindings may already be up to date."
356+ fi
357+ }
358+
359+ main " $@ "
0 commit comments