Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# .githooks/pre-commit
# Pre-commit hook for version validation

set -e

echo "🔍 Pre-commit: Validating version synchronization..."

# Check if validation script exists
if [ ! -f "scripts/validate-github-version-sync.sh" ]; then
echo "⚠️ Version validation script not found, skipping check"
exit 0
fi

# Run version validation (but don't fail the commit if GitHub CLI is unavailable)
if ./scripts/validate-github-version-sync.sh 2>/dev/null; then
echo "✅ Pre-commit: Version validation passed"
else
echo "⚠️ Pre-commit: Version validation failed or GitHub CLI unavailable"
echo "💡 Consider running: ./scripts/sync-version-from-github.sh"
echo "🔄 Continuing with commit (validation not enforced)"
fi

echo "✅ Pre-commit checks complete"
103 changes: 103 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,109 @@ echo 'export CODE_SIGN_IDENTITY="Apple Development: Your Name (TEAM_ID)"' >> ~/.
2. **Avoid concurrency conflicts**: Use proper `@MainActor` isolation without redundant dispatch
3. **Test permission changes**: Always test toggling permissions ON/OFF during development

## Version Management System

ClickIt uses an automated version management system that synchronizes version numbers between the UI, GitHub releases, and build processes.

### Version Architecture

**Single Source of Truth**: GitHub Release tags (e.g., `v1.4.15`)
- **GitHub Release**: Latest published version
- **Info.plist**: `CFBundleShortVersionString` (synced automatically)
- **UI Display**: Reads from `Bundle.main.infoDictionary` at runtime
- **Build Scripts**: Extract version from Info.plist (no hardcoding)

### Version Management Scripts

**Sync version with GitHub releases**:
```bash
./scripts/sync-version-from-github.sh
```
Automatically updates Info.plist to match the latest GitHub release version.

**Validate version synchronization**:
```bash
./scripts/validate-github-version-sync.sh
```
Checks if local version matches GitHub release. Used in build validation.

**Update to new version**:
```bash
./scripts/update-version.sh 1.5.0 # Creates GitHub release automatically
./scripts/update-version.sh 1.5.0 false # Update without GitHub release
```
Complete version update workflow including Info.plist update, git commit, tag creation, and optional GitHub release trigger.

### Fastlane Integration

**Sync with GitHub**:
```bash
fastlane sync_version_with_github
```

**Release new version**:
```bash
fastlane release_with_github version:1.5.0
```

**Validate synchronization**:
```bash
fastlane validate_github_sync
```

### Git Hooks (Optional)

**Install version validation hooks**:
```bash
./scripts/install-git-hooks.sh
```
Adds pre-commit hook that validates version synchronization before commits.

### Build Integration

Build scripts automatically:
- Extract version from Info.plist
- Validate sync with GitHub releases
- Display version warnings if mismatched
- Build with correct version in app bundle

### Troubleshooting Version Issues

**UI shows wrong version**:
```bash
# Sync Info.plist with GitHub release
./scripts/sync-version-from-github.sh

# Rebuild app bundle
./build_app_unified.sh release
```

**Version mismatch detected**:
```bash
# Check current status
./scripts/validate-github-version-sync.sh

# Fix automatically
./scripts/sync-version-from-github.sh
```

**Release new version**:
```bash
# Complete workflow (recommended)
./scripts/update-version.sh 1.5.0

# Or use Fastlane
fastlane release_with_github version:1.5.0
```

### CI/CD Integration

The GitHub Actions release workflow (`.github/workflows/release.yml`) automatically:
- Validates version synchronization
- Auto-fixes version mismatches
- Verifies built app version matches tag
- Creates releases with proper version metadata

## Documentation References

- Full product requirements: `docs/clickit_autoclicker_prd.md`
Expand Down
98 changes: 47 additions & 51 deletions ClickIt/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,51 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>ClickIt</string>
<key>CFBundleExecutable</key>
<string>ClickIt</string>
<key>CFBundleIdentifier</key>
<string>com.jsonify.ClickIt</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ClickIt</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSMinimumSystemVersion</key>
<string>14.0</string>
<key>LSUIElement</key>
<false/>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<!-- CRITICAL: Permission usage descriptions -->
<key>NSAppleEventsUsageDescription</key>
<string>ClickIt needs to send Apple Events to simulate mouse clicks in target applications.</string>
<key>NSSystemAdministrationUsageDescription</key>
<string>ClickIt requires accessibility access to simulate mouse clicks and detect window information.</string>
<!-- Additional privacy entries for comprehensive permissions -->
<key>NSAccessibilityUsageDescription</key>
<string>ClickIt needs accessibility access to control mouse clicks and interact with other applications.</string>
<key>NSScreenCaptureUsageDescription</key>
<string>ClickIt needs screen recording access to detect windows and provide visual feedback overlays.</string>
<!-- App icon reference -->
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<!-- Sparkle auto-update configuration -->
<key>SUFeedURL</key>
<string>https://jsonify.github.io/ClickIt/appcast.xml</string>
<key>SUPublicEDKey</key>
<string>auto-generated-when-needed</string>
<key>SUAutomaticallyUpdate</key>
<false/>
<key>SUEnableAutomaticChecks</key>
<true/>
<key>SUCheckAtStartup</key>
<true/>
<key>CFBundleDisplayName</key>
<string>ClickIt</string>
<key>CFBundleExecutable</key>
<string>ClickIt</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<key>CFBundleIdentifier</key>
<string>com.jsonify.ClickIt</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ClickIt</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.4.15</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSMinimumSystemVersion</key>
<string>14.0</string>
<key>LSUIElement</key>
<false/>
<key>NSAccessibilityUsageDescription</key>
<string>ClickIt needs accessibility access to control mouse clicks and interact with other applications.</string>
<key>NSAppleEventsUsageDescription</key>
<string>ClickIt needs to send Apple Events to simulate mouse clicks in target applications.</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSScreenCaptureUsageDescription</key>
<string>ClickIt needs screen recording access to detect windows and provide visual feedback overlays.</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>NSSystemAdministrationUsageDescription</key>
<string>ClickIt requires accessibility access to simulate mouse clicks and detect window information.</string>
<key>SUAutomaticallyUpdate</key>
<false/>
<key>SUCheckAtStartup</key>
<true/>
<key>SUEnableAutomaticChecks</key>
<true/>
<key>SUFeedURL</key>
<string>https://jsonify.github.io/ClickIt/appcast.xml</string>
<key>SUPublicEDKey</key>
<string>auto-generated-when-needed</string>
</dict>
</plist>
</plist>
24 changes: 23 additions & 1 deletion build_app_unified.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,32 @@ BUILD_SYSTEM="${2:-auto}" # auto, spm, xcode
DIST_DIR="dist"
APP_NAME="ClickIt"
BUNDLE_ID="com.jsonify.clickit"
VERSION="1.0.0"
# Get version from Info.plist (synced with GitHub releases)
get_version_from_plist() {
/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ClickIt/Info.plist 2>/dev/null || echo "1.0.0"
}

VERSION=$(get_version_from_plist)
BUILD_NUMBER=$(date +%Y%m%d%H%M)

echo "🔨 Building $APP_NAME app bundle ($BUILD_MODE mode)..."
echo "📦 Version: $VERSION (from Info.plist, synced with GitHub releases)"

# Validate version is synchronized with GitHub (optional validation)
if command -v gh > /dev/null 2>&1; then
GITHUB_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null || git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$GITHUB_TAG" ]; then
GITHUB_VERSION=${GITHUB_TAG#v}
if [ "$VERSION" != "$GITHUB_VERSION" ]; then
echo "⚠️ Warning: Version mismatch detected!"
echo " Building: v$VERSION"
echo " GitHub: $GITHUB_TAG"
echo " Run './scripts/sync-version-from-github.sh' to sync versions"
else
echo "✅ Version synchronized with GitHub release $GITHUB_TAG"
fi
fi
fi

# Detect build system
detect_build_system() {
Expand Down
Loading
Loading