22
33# Release script for CameraCapture
44# This script validates version consistency, checks git history, and creates release tags
5- # Usage: ./release.sh [-n|--dry-run]
5+ # Usage: ./release.sh [-n|--dry-run] [--beta|--alpha|--rc [number]]
66
77set -e
88
@@ -15,15 +15,43 @@ NC='\033[0m' # No Color
1515
1616# Parse command line arguments
1717DRY_RUN=false
18+ PRERELEASE_TYPE=" "
19+ PRERELEASE_NUMBER=" "
20+
1821while [[ $# -gt 0 ]]; do
1922 case $1 in
2023 -n | --dry-run)
2124 DRY_RUN=true
2225 shift
2326 ;;
27+ --beta | --alpha | --rc)
28+ PRERELEASE_TYPE=" ${1# --} "
29+ shift
30+ # Check if next argument is a number
31+ if [[ $# -gt 0 && " $1 " =~ ^[0-9]+$ ]]; then
32+ PRERELEASE_NUMBER=" $1 "
33+ shift
34+ else
35+ PRERELEASE_NUMBER=" 1"
36+ fi
37+ ;;
2438 * )
2539 echo " Unknown option: $1 "
26- echo " Usage: $0 [-n|--dry-run]"
40+ echo " Usage: $0 [-n|--dry-run] [--beta|--alpha|--rc [number]]"
41+ echo " "
42+ echo " Options:"
43+ echo " -n, --dry-run Run without making actual changes"
44+ echo " --beta [number] Create beta release (e.g., v1.0.0-beta.1)"
45+ echo " --alpha [number] Create alpha release (e.g., v1.0.0-alpha.1)"
46+ echo " --rc [number] Create release candidate (e.g., v1.0.0-rc.1)"
47+ echo " "
48+ echo " Examples:"
49+ echo " $0 # Create official release"
50+ echo " $0 --dry-run # Preview release without changes"
51+ echo " $0 --beta # Create beta.1 release"
52+ echo " $0 --beta 2 # Create beta.2 release"
53+ echo " $0 --alpha 3 # Create alpha.3 release"
54+ echo " $0 --rc 1 # Create rc.1 release"
2755 exit 1
2856 ;;
2957 esac
@@ -48,14 +76,15 @@ for branch in "${MAIN_BRANCHES[@]}"; do
4876 fi
4977done
5078
51- # Auto-enable dry-run if not on main branch
79+ # Check if on main branch - REQUIRED for release (no dry-run bypass)
5280if [ " $IS_MAIN_BRANCH " = false ]; then
53- if [ " $DRY_RUN " = false ]; then
54- echo -e " ${YELLOW} ⚠️ Not on main branch (current: $CURRENT_BRANCH )${NC} "
55- echo -e " ${YELLOW} Automatically enabling DRY-RUN mode for safety${NC} "
56- echo " "
57- DRY_RUN=true
58- fi
81+ echo -e " ${RED} ❌ Error: Release can only be executed from the main branch!${NC} "
82+ echo -e " Current branch: ${RED} $CURRENT_BRANCH ${NC} "
83+ echo -e " Required branch: ${GREEN} main${NC} or ${GREEN} master${NC} "
84+ echo " "
85+ echo -e " ${YELLOW} Please switch to the main branch:${NC} "
86+ echo -e " ${GREEN} git checkout main${NC} "
87+ exit 1
5988fi
6089
6190# Helper function to get the appropriate GitHub remote
@@ -93,6 +122,11 @@ echo -e "${BLUE}═════════════════════
93122echo " "
94123echo -e " Current branch: ${GREEN} $CURRENT_BRANCH ${NC} "
95124echo -e " Using remote: ${GREEN} $GITHUB_REMOTE ${NC} ($( git remote get-url " $GITHUB_REMOTE " ) )"
125+ if [ -n " $PRERELEASE_TYPE " ]; then
126+ echo -e " Release type: ${YELLOW} Pre-release ($PRERELEASE_TYPE .$PRERELEASE_NUMBER )${NC} "
127+ else
128+ echo -e " Release type: ${GREEN} Official Release${NC} "
129+ fi
96130echo " "
97131
98132if [ " $DRY_RUN " = true ]; then
@@ -206,6 +240,13 @@ echo ""
206240
207241CURRENT_VERSION=" $HEADER_VERSION "
208242
243+ # Apply pre-release suffix if specified
244+ if [ -n " $PRERELEASE_TYPE " ]; then
245+ CURRENT_VERSION=" ${CURRENT_VERSION} -${PRERELEASE_TYPE} .${PRERELEASE_NUMBER} "
246+ echo -e " ${BLUE} Pre-release version: ${YELLOW} $CURRENT_VERSION ${NC} "
247+ echo " "
248+ fi
249+
209250# ============================================================================
210251# Step 3: Check git repository status
211252# ============================================================================
@@ -226,7 +267,15 @@ if ! git diff-index --quiet HEAD --; then
226267 exit 1
227268fi
228269
229- echo -e " ${GREEN} ✅ Git repository is clean${NC} "
270+ # Check for untracked files (optional warning)
271+ UNTRACKED_FILES=$( git ls-files --others --exclude-standard)
272+ if [ -n " $UNTRACKED_FILES " ]; then
273+ echo -e " ${YELLOW} ⚠️ Warning: Untracked files detected:${NC} "
274+ echo " $UNTRACKED_FILES " | sed ' s/^/ /'
275+ echo " "
276+ fi
277+
278+ echo -e " ${GREEN} ✅ Git repository is clean (all changes committed)${NC} "
230279echo " "
231280
232281# ============================================================================
252301echo " "
253302
254303# ============================================================================
255- # Step 5: Check if current version already exists
304+ # Step 5: Check if version already exists (both locally and remotely)
256305# ============================================================================
257- echo -e " ${BLUE} Step 5: Checking if version already exists in git history ...${NC} "
306+ echo -e " ${BLUE} Step 5: Checking if version already exists...${NC} "
258307echo " "
259308
260309RELEASE_TAG=" v$CURRENT_VERSION "
261310
311+ # Check local tags
262312if git rev-parse " $RELEASE_TAG " > /dev/null 2>&1 ; then
263- echo -e " ${RED} ❌ Error: Release tag already exists!${NC} "
313+ echo -e " ${RED} ❌ Error: Release tag already exists locally !${NC} "
264314 echo -e " Tag: $RELEASE_TAG "
265- echo -e " Please update the version number in include/ccap_config.h "
315+ echo -e " Please update the version number or use a different pre-release suffix "
266316 exit 1
267317fi
268318
269- echo -e " ${GREEN} ✅ Version $CURRENT_VERSION does not exist in git history${NC} "
319+ echo -e " ${GREEN} ✅ Tag does not exist locally${NC} "
320+
321+ # Fetch remote tags to ensure we have the latest
322+ echo -e " Fetching remote tags..."
323+ if ! git fetch " $GITHUB_REMOTE " --tags --quiet 2> /dev/null; then
324+ echo -e " ${YELLOW} ⚠️ Warning: Could not fetch remote tags (continuing anyway)${NC} "
325+ else
326+ echo -e " ${GREEN} ✅ Remote tags fetched${NC} "
327+ fi
328+
329+ # Check remote tags
330+ if git ls-remote --tags " $GITHUB_REMOTE " | grep -q " refs/tags/$RELEASE_TAG $" ; then
331+ echo -e " ${RED} ❌ Error: Release tag already exists on remote!${NC} "
332+ echo -e " Remote: $GITHUB_REMOTE "
333+ echo -e " Tag: $RELEASE_TAG "
334+ echo -e " Please update the version number or use a different pre-release suffix"
335+ exit 1
336+ fi
337+
338+ echo -e " ${GREEN} ✅ Tag does not exist on remote${NC} "
270339echo " "
271340
272341# ============================================================================
@@ -280,6 +349,10 @@ compare_versions() {
280349 local v1=$1
281350 local v2=$2
282351
352+ # Strip any pre-release suffix for comparison (e.g., 1.2.3-beta.1 -> 1.2.3)
353+ v1=$( echo " $v1 " | sed ' s/-.*$//' )
354+ v2=$( echo " $v2 " | sed ' s/-.*$//' )
355+
283356 # Convert versions to comparable format (e.g., 1.2.3 -> 001002003)
284357 local v1_parts=(${v1// ./ } )
285358 local v2_parts=(${v2// ./ } )
@@ -299,19 +372,24 @@ compare_versions() {
299372if [ " $LATEST_TAG " != " 0.0.0" ]; then
300373 COMPARE=$( compare_versions " $CURRENT_VERSION " " $LATEST_TAG " )
301374
302- if [ " $COMPARE " = " equal" ]; then
303- echo -e " ${RED} ❌ Error: Version is not higher than the latest release!${NC} "
304- echo -e " Current: $CURRENT_VERSION , Latest: $LATEST_TAG "
305- exit 1
306- elif [ " $COMPARE " = " less" ]; then
307- echo -e " ${RED} ❌ Error: Version must be higher than existing releases!${NC} "
375+ if [ " $COMPARE " = " less" ]; then
376+ echo -e " ${RED} ❌ Error: Version must be higher than or equal to existing releases!${NC} "
308377 echo -e " Current: $CURRENT_VERSION , Latest: $LATEST_TAG "
309378 exit 1
379+ elif [ " $COMPARE " = " equal" ]; then
380+ # For equal base versions, check if it's a pre-release
381+ if [ -z " $PRERELEASE_TYPE " ]; then
382+ echo -e " ${RED} ❌ Error: Version is not higher than the latest release!${NC} "
383+ echo -e " Current: $CURRENT_VERSION , Latest: $LATEST_TAG "
384+ exit 1
385+ else
386+ echo -e " ${GREEN} ✅ Creating pre-release for version $HEADER_VERSION ${NC} "
387+ fi
388+ else
389+ echo -e " Latest version: $LATEST_TAG "
390+ echo -e " Current version: $CURRENT_VERSION "
391+ echo -e " ${GREEN} ✅ Version is higher than the latest release${NC} "
310392 fi
311-
312- echo -e " Latest version: $LATEST_TAG "
313- echo -e " Current version: $CURRENT_VERSION "
314- echo -e " ${GREEN} ✅ Version is higher than the latest release${NC} "
315393else
316394 echo -e " ${GREEN} ✅ This is the first release (no previous versions found)${NC} "
317395fi
@@ -340,7 +418,12 @@ if [ "$DRY_RUN" = true ]; then
340418fi
341419
342420# Create annotated tag
343- if ! git tag -a " $RELEASE_TAG " -m " Release $CURRENT_VERSION " ; then
421+ TAG_MESSAGE=" Release $CURRENT_VERSION "
422+ if [ -n " $PRERELEASE_TYPE " ]; then
423+ TAG_MESSAGE=" Pre-release $CURRENT_VERSION "
424+ fi
425+
426+ if ! git tag -a " $RELEASE_TAG " -m " $TAG_MESSAGE " ; then
344427 echo -e " ${RED} ❌ Error: Failed to create tag $RELEASE_TAG ${NC} "
345428 exit 1
346429fi
@@ -355,7 +438,7 @@ if ! git push "$GITHUB_REMOTE" "$RELEASE_TAG"; then
355438 exit 1
356439fi
357440
358- echo -e " ${GREEN} ✅ Tag pushed to remote${NC} "
441+ echo -e " ${GREEN} ✅ Tag pushed to remote: $GITHUB_REMOTE ${NC} "
359442echo " "
360443
361444# ============================================================================
@@ -371,23 +454,20 @@ echo ""
371454echo -e " ${BLUE} Next steps:${NC} "
372455if [ " $DRY_RUN " = true ]; then
373456 echo -e " ${YELLOW} This was a DRY-RUN. No actual changes were made.${NC} "
374- if [ " $IS_MAIN_BRANCH " = false ]; then
375- echo " "
376- echo -e " ${YELLOW} ⚠️ IMPORTANT: Release can only be executed from the main branch!${NC} "
377- echo -e " Current branch: ${RED} $CURRENT_BRANCH ${NC} "
378- echo -e " Required branch: ${GREEN} main${NC} or ${GREEN} master${NC} "
379- echo " "
380- echo -e " ${BLUE} To perform an actual release:${NC} "
381- echo -e " 1. Switch to the main branch: ${GREEN} git checkout main${NC} "
382- echo -e " 2. Ensure you have the latest changes: ${GREEN} git pull${NC} "
383- echo -e " 3. Run the release script again: ${GREEN} ./scripts/release.sh${NC} "
384- echo " "
457+ echo " "
458+ echo -e " ${BLUE} To perform an actual release:${NC} "
459+ if [ -n " $PRERELEASE_TYPE " ]; then
460+ echo -e " ${GREEN} ./scripts/release.sh --$PRERELEASE_TYPE $PRERELEASE_NUMBER ${NC} (without --dry-run)"
385461 else
386- echo -e " To perform an actual release: ${GREEN} ./scripts/release.sh${NC} (without --dry-run)"
462+ echo -e " ${GREEN} ./scripts/release.sh${NC} (without --dry-run)"
387463 fi
388464else
389465 echo -e " 1. GitHub Actions will automatically build and create a release"
390466 echo -e " 2. Monitor the workflow at: https://github.com/wysaid/CameraCapture/actions"
391467 echo -e " 3. Verify the release at: https://github.com/wysaid/CameraCapture/releases/tag/$RELEASE_TAG "
468+ if [ -n " $PRERELEASE_TYPE " ]; then
469+ echo " "
470+ echo -e " ${YELLOW} Note: This is a pre-release and will be marked as such on GitHub${NC} "
471+ fi
392472fi
393473echo " "
0 commit comments