1+ #! /bin/bash
2+
3+ set -e
4+
5+ # Colors for output
6+ RED=' \033[0;31m'
7+ GREEN=' \033[0;32m'
8+ YELLOW=' \033[1;33m'
9+ BLUE=' \033[0;34m'
10+ NC=' \033[0m' # No Color
11+
12+ # Helper functions
13+ info () {
14+ echo -e " ${BLUE} ℹ️ $1 ${NC} "
15+ }
16+
17+ success () {
18+ echo -e " ${GREEN} ✅ $1 ${NC} "
19+ }
20+
21+ warning () {
22+ echo -e " ${YELLOW} ⚠️ $1 ${NC} "
23+ }
24+
25+ error () {
26+ echo -e " ${RED} ❌ $1 ${NC} "
27+ exit 1
28+ }
29+
30+ # Check if git repo is clean (only tracked files)
31+ check_git_status () {
32+ # Check for modified, staged, or deleted tracked files
33+ if [ -n " $( git status --porcelain | grep -E ' ^[MADR]' ) " ]; then
34+ error " Git working directory has uncommitted changes to tracked files. Please commit or stash your changes."
35+ fi
36+
37+ # Show untracked files as info (but don't block)
38+ untracked=$( git status --porcelain | grep ' ^??' )
39+ if [ -n " $untracked " ]; then
40+ warning " Untracked files present (will be ignored):"
41+ echo " $untracked " | sed ' s/^?? / - /'
42+ echo " "
43+ fi
44+ }
45+
46+ # Check if we're on main branch
47+ check_main_branch () {
48+ current_branch=$( git branch --show-current)
49+ if [ " $current_branch " != " main" ]; then
50+ error " You must be on the main branch to create a release. Current branch: $current_branch "
51+ fi
52+ }
53+
54+ # Get current version from version.json
55+ get_current_version () {
56+ if [ ! -f " version.json" ]; then
57+ error " version.json not found"
58+ fi
59+
60+ current_version=$( jq -r ' .version' version.json)
61+ if [ " $current_version " = " null" ]; then
62+ error " Could not read version from version.json"
63+ fi
64+ echo " $current_version "
65+ }
66+
67+ # Bump version based on type (patch, minor, major)
68+ bump_version () {
69+ local current=$1
70+ local type=$2
71+
72+ IFS=' .' read -ra ADDR <<< " $current"
73+ major=${ADDR[0]}
74+ minor=${ADDR[1]}
75+ patch=${ADDR[2]}
76+
77+ case $type in
78+ " patch" )
79+ patch=$(( patch + 1 ))
80+ ;;
81+ " minor" )
82+ minor=$(( minor + 1 ))
83+ patch=0
84+ ;;
85+ " major" )
86+ major=$(( major + 1 ))
87+ minor=0
88+ patch=0
89+ ;;
90+ * )
91+ error " Invalid bump type: $type . Use patch, minor, or major"
92+ ;;
93+ esac
94+
95+ echo " $major .$minor .$patch "
96+ }
97+
98+ # Update version.json with new version
99+ update_version_file () {
100+ local new_version=$1
101+
102+ jq --arg version " $new_version " '
103+ .version = $version |
104+ .components.backend = $version |
105+ .components.sync = $version
106+ ' version.json > version.json.tmp && mv version.json.tmp version.json
107+ }
108+
109+ # Show usage
110+ usage () {
111+ echo " Usage: $0 [patch|minor|major]"
112+ echo " "
113+ echo " Bump version, commit, tag and push for release"
114+ echo " "
115+ echo " Options:"
116+ echo " patch Bump patch version (0.0.1 -> 0.0.2)"
117+ echo " minor Bump minor version (0.0.1 -> 0.1.0)"
118+ echo " major Bump major version (0.0.1 -> 1.0.0)"
119+ echo " "
120+ echo " Examples:"
121+ echo " $0 patch # For bug fixes"
122+ echo " $0 minor # For new features"
123+ echo " $0 major # For breaking changes"
124+ exit 1
125+ }
126+
127+ # Main function
128+ main () {
129+ # Check for jq dependency
130+ if ! command -v jq & > /dev/null; then
131+ error " jq is required but not installed. Install it with: brew install jq"
132+ fi
133+
134+ # Parse arguments
135+ if [ $# -eq 0 ]; then
136+ usage
137+ fi
138+
139+ bump_type=$1
140+
141+ if [[ ! " $bump_type " =~ ^(patch| minor| major)$ ]]; then
142+ usage
143+ fi
144+
145+ info " Starting release process..."
146+
147+ # Pre-flight checks
148+ check_git_status
149+ check_main_branch
150+
151+ # Get current version and calculate new version
152+ current_version=$( get_current_version)
153+ new_version=$( bump_version " $current_version " " $bump_type " )
154+
155+ info " Current version: $current_version "
156+ info " New version: $new_version "
157+
158+ # Confirm with user
159+ echo " "
160+ read -p " Do you want to create release v$new_version ? [y/N] " -n 1 -r
161+ echo " "
162+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
163+ warning " Release cancelled"
164+ exit 0
165+ fi
166+
167+ # Update version file
168+ info " Updating version.json..."
169+ update_version_file " $new_version "
170+
171+ # Commit changes
172+ info " Creating commit..."
173+ git add version.json
174+ git commit -m " release: bump version to v$new_version "
175+
176+ # Create tag
177+ info " Creating tag v$new_version ..."
178+ git tag -a " v$new_version " -m " Release v$new_version "
179+
180+ # Push to remote
181+ info " Pushing to remote..."
182+ git push origin main
183+ git push origin " v$new_version "
184+
185+ success " Release v$new_version created successfully!"
186+ success " GitHub Actions will now build and publish the release."
187+
188+ # Show useful links
189+ echo " "
190+ info " Useful links:"
191+ info " - Actions: https://github.com/$( git config remote.origin.url | sed ' s/.*://g' | sed ' s/.git$//g' ) /actions"
192+ info " - Releases: https://github.com/$( git config remote.origin.url | sed ' s/.*://g' | sed ' s/.git$//g' ) /releases"
193+ }
194+
195+ # Run main function
196+ main " $@ "
0 commit comments