diff --git a/tibok/.xcode-ci.yml b/tibok/.xcode-ci.yml index f1780a4..b97f3c4 100644 --- a/tibok/.xcode-ci.yml +++ b/tibok/.xcode-ci.yml @@ -9,11 +9,9 @@ ci: name: "App Store Release" description: "Build and distribute Tibok to Mac App Store" - # Trigger on tags matching version pattern + # Trigger on pushes to apple-store-distro branch trigger: - - branch: main - tag: - - "v*.*.*" + - branch: apple-store-distro # Build configuration build: diff --git a/tibok/XCODE_CLOUD_SETUP.md b/tibok/XCODE_CLOUD_SETUP.md index 6d915d9..5cba660 100644 --- a/tibok/XCODE_CLOUD_SETUP.md +++ b/tibok/XCODE_CLOUD_SETUP.md @@ -2,11 +2,38 @@ Xcode Cloud automates building, testing, and distributing your app to the App Store. -## What I've Created +## Existing CI/CD Setup -✅ **Xcode Cloud Workflow** (`.xcode-ci.yml`) -- **App Store Release workflow**: Triggers on version tags (v1.0.3, v1.0.4, etc.) -- **Development workflow**: Triggers on pushes to development branch +✅ **You already have Xcode Cloud configured!** + +Your existing setup: +- **App Store builds** trigger when you push to the `apple-store-distro` branch +- **Development builds** trigger when you push to the `development` branch +- Automatic code signing is already configured +- TestFlight distribution is enabled + +## Quick Start: Trigger an App Store Build + +**TL;DR - To release to the App Store:** + +```bash +# Merge your changes to apple-store-distro +git checkout apple-store-distro +git pull origin apple-store-distro +git merge main # or development +git push origin apple-store-distro + +# Xcode Cloud will automatically build, sign, and upload to TestFlight +# Check App Store Connect for build status +``` + +That's it! The rest of this document explains the details. + +## Xcode Cloud Workflow (`.xcode-ci.yml`) + +Updated to match your existing setup: +- **App Store Release workflow**: Triggers on pushes to `apple-store-distro` branch +- **Development workflow**: Triggers on pushes to `development` branch - Automatic code signing - TestFlight distribution - App Store submission @@ -118,29 +145,34 @@ git push origin development git push origin main ``` -### Step 7: Trigger a Build +### Step 7: Trigger an App Store Build -**Method 1: Create a Version Tag** +**To trigger an App Store build, merge your changes to the `apple-store-distro` branch:** ```bash -# Create and push a version tag -git tag -a v1.0.3 -m "Release version 1.0.3 - Workspace & Git Enhancements" -git push origin v1.0.3 +# Make sure you're on the branch with your changes (e.g., development or main) +git checkout main # or development + +# Merge to apple-store-distro +git checkout apple-store-distro +git pull origin apple-store-distro # Get latest +git merge main # Merge your changes +git push origin apple-store-distro # Push to trigger build ``` Xcode Cloud will automatically: -1. Detect the tag +1. Detect the push to `apple-store-distro` 2. Start a build 3. Archive the app 4. Sign with App Store certificate 5. Upload to TestFlight 6. Send notification when complete -**Method 2: Manual Trigger** +**Alternative: Manual Trigger** 1. Go to App Store Connect → Xcode Cloud 2. Click **Start Build** -3. Select branch: **main** +3. Select branch: **apple-store-distro** 4. Click **Start** ### Step 8: Monitor Build Progress @@ -176,7 +208,7 @@ Once build completes and uploads to TestFlight: ### App Store Release Workflow -Triggered by: Tags matching `v*.*.*` (e.g., `v1.0.3`, `v2.0.0`) +Triggered by: Pushes to `apple-store-distro` branch Steps: 1. ✅ Clean build @@ -266,9 +298,33 @@ Steps: | **Time** | ~30 minutes | ~15 minutes | | **Reproducibility** | Depends on local env | Guaranteed | +## Quick Reference: Common Commands + +### Trigger App Store Build + +```bash +git checkout apple-store-distro +git pull origin apple-store-distro +git merge main # Merge your latest changes +git push origin apple-store-distro # Triggers build +``` + +### Check Build Status + +- **App Store Connect**: https://appstoreconnect.apple.com → Xcode Cloud → Builds +- **Email**: You'll receive notifications for success/failure + +### Submit to App Store (After Build Completes) + +1. Go to App Store Connect → Your App → App Store tab +2. Click **[+]** next to macOS version +3. Select build from TestFlight +4. Fill in "What's New" and metadata +5. Click **Submit for Review** + ## Next Steps After Setup -1. **Create version tag**: `git tag v1.0.3 && git push origin v1.0.3` +1. **Merge to apple-store-distro**: Follow Quick Reference above 2. **Monitor build**: Check App Store Connect 3. **Test on TestFlight**: Download from TestFlight and verify 4. **Submit for review**: When ready, submit from App Store Connect diff --git a/tibok/tibok.xcodeproj/project.pbxproj b/tibok/tibok.xcodeproj/project.pbxproj index 3060b52..8464ad0 100644 --- a/tibok/tibok.xcodeproj/project.pbxproj +++ b/tibok/tibok.xcodeproj/project.pbxproj @@ -71,6 +71,11 @@ E9C43AA5E1F80A20C575D404 /* FolderScanCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC14559B2BB3A58BDF5546CA /* FolderScanCacheTests.swift */; }; EAF5AD81F0C4684CB2A06AFF /* PluginStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A46F7DB71EFAD51E6F68887F /* PluginStateManager.swift */; }; F0F86904BEAF06BD1C727B20 /* UIStateService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68A522514ED9A6050DF7AB59 /* UIStateService.swift */; }; + 016F03EBC2D9AA8CC1381132 /* GitHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042B77C4CFBE439C1ADE2A4C /* GitHistoryView.swift */; }; + 798329FF6B2DB5F77E21D215 /* GitDiffView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5913E295469E357066FCBFAB /* GitDiffView.swift */; }; + 81A6B2583B68A340F8A74D86 /* KeyboardShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F82FD5C79107BF08DA922DD /* KeyboardShortcuts.swift */; }; + 3AF8932BB0633F049B7FE9C7 /* GitModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B67F7C0CC890305E0955B3 /* GitModels.swift */; }; + 507C1157A4EC3D47A6647EED /* WorkspaceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65A4021FFD848BA7899E2DC /* WorkspaceMonitor.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -146,6 +151,11 @@ FC14559B2BB3A58BDF5546CA /* FolderScanCacheTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderScanCacheTests.swift; sourceTree = ""; }; FCD5C5034F2BC8E6E35DA54E /* WebhookSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebhookSettingsView.swift; sourceTree = ""; }; FF213603A438FA52BA947AA0 /* FolderScanCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderScanCache.swift; sourceTree = ""; }; + 042B77C4CFBE439C1ADE2A4C /* GitHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitHistoryView.swift; sourceTree = ""; }; + 5913E295469E357066FCBFAB /* GitDiffView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitDiffView.swift; sourceTree = ""; }; + 6F82FD5C79107BF08DA922DD /* KeyboardShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardShortcuts.swift; sourceTree = ""; }; + 96B67F7C0CC890305E0955B3 /* GitModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitModels.swift; sourceTree = ""; }; + D65A4021FFD848BA7899E2DC /* WorkspaceMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceMonitor.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -176,6 +186,7 @@ F69D012BEAC8DF582B383B8F /* AppState.swift */, 32B40D864EBAC48D07EE4F8F /* Document.swift */, A45AD517F1F9959BE32288AC /* Frontmatter.swift */, + 96B67F7C0CC890305E0955B3 /* GitModels.swift */, 2B1AA243704EDDCFB8D0FD6E /* WebhookConfig.swift */, 79A01C4222D926E85ED44F95 /* WordPressModels.swift */, ); @@ -214,6 +225,8 @@ children = ( D2FD193BFC908EAE01AC7309 /* EditorView.swift */, 097446BFCA2A23C41B595D1D /* FrontmatterInspectorView.swift */, + 5913E295469E357066FCBFAB /* GitDiffView.swift */, + 042B77C4CFBE439C1ADE2A4C /* GitHistoryView.swift */, 04D5D249B1E0D9522DC31B13 /* GitPanelView.swift */, E299168D4FA7A93C215ADDA5 /* PluginSettingsView.swift */, AB59E47AD0065CA436508F9B /* PreviewView.swift */, @@ -263,11 +276,20 @@ 68A522514ED9A6050DF7AB59 /* UIStateService.swift */, B474561C00E71F6745A5E2EC /* WebhookService.swift */, AF44F644D4838B28FE57CE3C /* WordPressExporter.swift */, + D65A4021FFD848BA7899E2DC /* WorkspaceMonitor.swift */, 98EB81A7AE13FB33CB6E0316 /* WorkspaceService.swift */, ); path = Services; sourceTree = ""; }; + 3C641E81E519D545BE4AD209 /* Extensions */ = { + isa = PBXGroup; + children = ( + 6F82FD5C79107BF08DA922DD /* KeyboardShortcuts.swift */, + ); + path = Extensions; + sourceTree = ""; + }; C6A228CFBAEBF6F88F19607A /* Builtin */ = { isa = PBXGroup; children = ( @@ -283,6 +305,7 @@ children = ( 094819A03A1970C5BC200C3B /* ContentView.swift */, 8702A62F19C796F171937927 /* tibokApp.swift */, + 3C641E81E519D545BE4AD209 /* Extensions */, 349D8CBC23FADDA8D1961AAC /* Helpers */, 23906A9A1E28EF3606172181 /* Models */, EADE2E326047656276251111 /* Plugins */, @@ -438,10 +461,14 @@ 6B0165A1CA6305A63073E566 /* FrontmatterCacheService.swift in Sources */, 91E74C661594AB6B0BDF633B /* FrontmatterInspectorView.swift in Sources */, D4089D15A268F4762C5929AC /* FrontmatterPlugin.swift in Sources */, + 798329FF6B2DB5F77E21D215 /* GitDiffView.swift in Sources */, + 016F03EBC2D9AA8CC1381132 /* GitHistoryView.swift in Sources */, + 3AF8932BB0633F049B7FE9C7 /* GitModels.swift in Sources */, 195D049CF3EA8771778B86D5 /* GitPanelView.swift in Sources */, 119A1904C05393D6CF418195 /* GitService.swift in Sources */, 48F435885AFCC6DE8373453D /* ImageUploadService.swift in Sources */, DDCA4BFC2B5E2400E722098F /* KeychainHelper.swift in Sources */, + 81A6B2583B68A340F8A74D86 /* KeyboardShortcuts.swift in Sources */, B484D880C67F87186B1A3434 /* LogService.swift in Sources */, 802AE4751B1198C8386145B2 /* MarkdownRenderer.swift in Sources */, DF22E3D1605211AEE59F2C62 /* PluginContext.swift in Sources */, @@ -468,6 +495,7 @@ 6F7ACCFE58FD92A9EB3A5B8A /* WordPressExporter.swift in Sources */, 8392AA2E1D6582F2A41870FD /* WordPressModels.swift in Sources */, 42EDB2CEB271EDF7F062092D /* WordPressSettingsView.swift in Sources */, + 507C1157A4EC3D47A6647EED /* WorkspaceMonitor.swift in Sources */, B8A4AF9C33BE8D0F23CC04F0 /* WorkspaceService.swift in Sources */, DBDDCE5AD045625C90EA6E17 /* tibokApp.swift in Sources */, ); diff --git a/tibok/tibok/Views/EditorView.swift b/tibok/tibok/Views/EditorView.swift index 193725a..500faf0 100644 --- a/tibok/tibok/Views/EditorView.swift +++ b/tibok/tibok/Views/EditorView.swift @@ -650,9 +650,14 @@ struct FindableTextEditor: NSViewRepresentable { // Find the current paragraph range let currentParagraphRange = nsString.paragraphRange(for: NSRange(location: min(cursorLocation, nsString.length - 1), length: 0)) + // Determine alpha based on appearance (dark mode needs higher opacity for visibility) + let appearance = NSApp.effectiveAppearance + let isDarkMode = appearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua + let dimmedAlpha: CGFloat = isDarkMode ? 0.5 : 0.3 + // Dim all text first let fullRange = NSRange(location: 0, length: textStorage.length) - textStorage.addAttribute(.foregroundColor, value: NSColor.labelColor.withAlphaComponent(0.3), range: fullRange) + textStorage.addAttribute(.foregroundColor, value: NSColor.labelColor.withAlphaComponent(dimmedAlpha), range: fullRange) // Restore full opacity for current paragraph if currentParagraphRange.location != NSNotFound && currentParagraphRange.length > 0 {