Skip to content

Commit b87ee92

Browse files
committed
Enhance release.sh script with comprehensive pre-release support
- Add support for --beta, --alpha, --rc parameters with optional version numbers - Enforce main branch requirement (remove auto dry-run fallback) - Add remote tag existence check to prevent duplicate releases - Improve version comparison logic for pre-release versions - Add untracked files warning in git status check - Update help message with detailed usage examples - Enhance error messages and user feedback Fixes all requirements: 1. Version consistency check (already implemented) 2. Branch and repository status validation (strengthened) 3. Pre-release version parameter support (NEW) 4. Remote tag existence verification (NEW) 5. Tag creation and push with error handling (improved)
1 parent 4781b0a commit b87ee92

1 file changed

Lines changed: 119 additions & 39 deletions

File tree

scripts/release.sh

Lines changed: 119 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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

77
set -e
88

@@ -15,15 +15,43 @@ NC='\033[0m' # No Color
1515

1616
# Parse command line arguments
1717
DRY_RUN=false
18+
PRERELEASE_TYPE=""
19+
PRERELEASE_NUMBER=""
20+
1821
while [[ $# -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
4977
done
5078

51-
# Auto-enable dry-run if not on main branch
79+
# Check if on main branch - REQUIRED for release (no dry-run bypass)
5280
if [ "$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
5988
fi
6089

6190
# Helper function to get the appropriate GitHub remote
@@ -93,6 +122,11 @@ echo -e "${BLUE}═════════════════════
93122
echo ""
94123
echo -e " Current branch: ${GREEN}$CURRENT_BRANCH${NC}"
95124
echo -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
96130
echo ""
97131

98132
if [ "$DRY_RUN" = true ]; then
@@ -206,6 +240,13 @@ echo ""
206240

207241
CURRENT_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
227268
fi
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}"
230279
echo ""
231280

232281
# ============================================================================
@@ -252,21 +301,41 @@ fi
252301
echo ""
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}"
258307
echo ""
259308

260309
RELEASE_TAG="v$CURRENT_VERSION"
261310

311+
# Check local tags
262312
if 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
267317
fi
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}"
270339
echo ""
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() {
299372
if [ "$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}"
315393
else
316394
echo -e "${GREEN}✅ This is the first release (no previous versions found)${NC}"
317395
fi
@@ -340,7 +418,12 @@ if [ "$DRY_RUN" = true ]; then
340418
fi
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
346429
fi
@@ -355,7 +438,7 @@ if ! git push "$GITHUB_REMOTE" "$RELEASE_TAG"; then
355438
exit 1
356439
fi
357440

358-
echo -e "${GREEN}✅ Tag pushed to remote${NC}"
441+
echo -e "${GREEN}✅ Tag pushed to remote: $GITHUB_REMOTE${NC}"
359442
echo ""
360443

361444
# ============================================================================
@@ -371,23 +454,20 @@ echo ""
371454
echo -e "${BLUE}Next steps:${NC}"
372455
if [ "$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
388464
else
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
392472
fi
393473
echo ""

0 commit comments

Comments
 (0)