Simple App to help @jaspermayone make it through COMP1050 with a professor who won't use version control.
1#!/bin/bash
2set -e
3
4# ZipMerge Local Release Script
5# This script builds, signs, notarizes, and releases ZipMerge
6
7# Colors for output
8RED='\033[0;31m'
9GREEN='\033[0;32m'
10YELLOW='\033[1;33m'
11NC='\033[0m' # No Color
12
13# Configuration
14HOMEBREW_TAP_PATH="/Users/jsp/dev/projects/homebrew-tap"
15APPLE_ID="${APPLE_ID:-}" # Set via environment variable or it will prompt
16TEAM_ID="M67B42LX8D"
17
18echo -e "${GREEN}🚀 ZipMerge Release Script${NC}"
19echo ""
20
21# Check for version argument
22if [ -z "$1" ]; then
23 echo -e "${RED}Error: Version number required${NC}"
24 echo "Usage: ./release.sh v1.0.0"
25 exit 1
26fi
27
28VERSION="$1"
29echo -e "Release version: ${YELLOW}${VERSION}${NC}"
30echo ""
31
32# Check if gh CLI is installed
33if ! command -v gh &> /dev/null; then
34 echo -e "${RED}Error: gh CLI not found. Install with: brew install gh${NC}"
35 exit 1
36fi
37
38# Check if logged in to gh
39if ! gh auth status &> /dev/null; then
40 echo -e "${YELLOW}Please login to GitHub CLI:${NC}"
41 gh auth login
42fi
43
44# Prompt for Apple ID if not set
45if [ -z "$APPLE_ID" ]; then
46 echo -e "${YELLOW}Enter your Apple ID email:${NC}"
47 read APPLE_ID
48fi
49
50# Prompt for app-specific password
51echo -e "${YELLOW}Enter your Apple ID app-specific password:${NC}"
52echo "(Create one at: https://appleid.apple.com/account/manage)"
53read -s APPLE_PASSWORD
54echo ""
55
56# Clean previous builds
57echo -e "${GREEN}🧹 Cleaning previous builds...${NC}"
58rm -rf build/
59rm -f ZipMerge.zip
60
61# Build the app
62echo -e "${GREEN}🔨 Building ZipMerge...${NC}"
63xcodebuild -project ZipMerge.xcodeproj \
64 -scheme ZipMerge \
65 -configuration Release \
66 -derivedDataPath ./build \
67 clean build
68
69if [ $? -ne 0 ]; then
70 echo -e "${RED}Build failed!${NC}"
71 exit 1
72fi
73
74APP_PATH="./build/Build/Products/Release/ZipMerge.app"
75
76# Re-sign with Developer ID for distribution
77echo -e "${GREEN}🔏 Signing with Developer ID...${NC}"
78codesign --force --deep --sign "Developer ID Application" \
79 --options runtime \
80 --timestamp \
81 "$APP_PATH"
82
83if [ $? -ne 0 ]; then
84 echo -e "${RED}Code signing failed!${NC}"
85 echo "Make sure you have a valid Developer ID Application certificate."
86 exit 1
87fi
88
89# Verify code signing
90echo -e "${GREEN}✅ Verifying code signature...${NC}"
91codesign -dv --verbose=4 "$APP_PATH"
92
93# Create zip for notarization
94echo -e "${GREEN}📦 Creating archive...${NC}"
95cd build/Build/Products/Release
96zip -r ../../../../ZipMerge.zip ZipMerge.app
97cd ../../../../
98
99# Notarize the app
100echo -e "${GREEN}🔐 Submitting for notarization...${NC}"
101echo "This may take 5-10 minutes..."
102
103xcrun notarytool submit ZipMerge.zip \
104 --apple-id "$APPLE_ID" \
105 --team-id "$TEAM_ID" \
106 --password "$APPLE_PASSWORD" \
107 --wait
108
109if [ $? -ne 0 ]; then
110 echo -e "${RED}Notarization failed!${NC}"
111 exit 1
112fi
113
114# Staple the notarization ticket
115echo -e "${GREEN}📎 Stapling notarization ticket...${NC}"
116unzip -q ZipMerge.zip
117xcrun stapler staple ZipMerge.app
118rm ZipMerge.zip
119zip -r -q ZipMerge.zip ZipMerge.app
120rm -rf ZipMerge.app
121
122# Calculate SHA256
123echo -e "${GREEN}🔢 Calculating SHA256...${NC}"
124SHA256=$(shasum -a 256 ZipMerge.zip | awk '{print $1}')
125echo -e "SHA256: ${YELLOW}${SHA256}${NC}"
126
127# Ensure git tag exists and is pushed
128echo -e "${GREEN}🏷️ Ensuring git tag exists...${NC}"
129if git rev-parse "$VERSION" >/dev/null 2>&1; then
130 echo "Tag $VERSION already exists locally"
131else
132 echo "Creating tag $VERSION"
133 git tag -a "$VERSION" -m "Release $VERSION"
134fi
135
136# Push the tag (force in case it was updated)
137echo "Pushing tag to origin..."
138git push origin "$VERSION" 2>/dev/null || git push --force origin "$VERSION"
139
140# Create GitHub release
141echo -e "${GREEN}📤 Creating GitHub release...${NC}"
142gh release create "$VERSION" ZipMerge.zip \
143 --title "ZipMerge $VERSION" \
144 --notes "## Installation
145
146### Via Homebrew
147\`\`\`bash
148brew tap jaspermayone/tap
149brew install --cask zipmerge
150\`\`\`
151
152### Manual Installation
1531. Download ZipMerge.zip
1542. Unzip and move ZipMerge.app to /Applications
155
156## SHA256 Checksum
157\`\`\`
158$SHA256
159\`\`\`"
160
161if [ $? -ne 0 ]; then
162 echo -e "${RED}GitHub release failed!${NC}"
163 exit 1
164fi
165
166# Update Homebrew cask
167echo -e "${GREEN}🍺 Updating Homebrew cask...${NC}"
168
169CASK_FILE="$HOMEBREW_TAP_PATH/Casks/zipmerge.rb"
170
171if [ ! -f "$CASK_FILE" ]; then
172 echo -e "${RED}Error: Cask file not found at $CASK_FILE${NC}"
173 exit 1
174fi
175
176# Update version and SHA256 in cask file
177sed -i '' "s/version \".*\"/version \"${VERSION#v}\"/" "$CASK_FILE"
178sed -i '' "s/sha256 .*/sha256 \"$SHA256\"/" "$CASK_FILE"
179
180echo -e "${GREEN}✅ Cask file updated${NC}"
181
182# Commit and push cask update
183echo -e "${GREEN}📝 Committing cask update...${NC}"
184cd "$HOMEBREW_TAP_PATH"
185git add Casks/zipmerge.rb
186git commit -m "Update zipmerge to $VERSION"
187git push
188
189echo ""
190echo -e "${GREEN}✨ Release complete!${NC}"
191echo ""
192echo "Users can now install with:"
193echo -e "${YELLOW}brew tap jaspermayone/tap${NC}"
194echo -e "${YELLOW}brew install --cask zipmerge${NC}"
195echo ""
196echo "SHA256: $SHA256"