From 1b72afe5b997875db287a90462993f3e3cd75200 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Mon, 22 Jun 2026 14:32:01 +0700 Subject: [PATCH 1/3] build: sign Debug builds without iCloud for personal teams Point the app's Debug config at TablePro.Debug.entitlements, which omits the iCloud capability and uses a dynamic team prefix. Personal Apple teams can't provision iCloud, so the Debug build now signs with a free account and external contributors can build the app. Release still uses TablePro.entitlements with iCloud, and CI signs it explicitly. Finishes the contributor-build support started in #1028. Claude-Session: https://claude.ai/code/session_01Dtzk7mYAky4LPjp2HxYnMW --- TablePro.xcodeproj/project.pbxproj | 2 +- docs/development/setup.mdx | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/TablePro.xcodeproj/project.pbxproj b/TablePro.xcodeproj/project.pbxproj index 7f7863231..cc02f9ab1 100644 --- a/TablePro.xcodeproj/project.pbxproj +++ b/TablePro.xcodeproj/project.pbxproj @@ -2774,7 +2774,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; AUTOMATION_APPLE_EVENTS = NO; - CODE_SIGN_ENTITLEMENTS = TablePro/TablePro.entitlements; + CODE_SIGN_ENTITLEMENTS = TablePro/TablePro.Debug.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; diff --git a/docs/development/setup.mdx b/docs/development/setup.mdx index 86881ac1a..42b3fc188 100644 --- a/docs/development/setup.mdx +++ b/docs/development/setup.mdx @@ -65,6 +65,11 @@ Optional but recommended: 1. Select the **TablePro** target 2. Go to **Signing & Capabilities** 3. Change **Team** to your Apple Developer account (free account works) + + The Debug build leaves out the iCloud capability, so a free personal team + signs it without a paid Apple Developer Program membership. If you build a + target that still shows a team error (a driver plugin or the MCP server), + set its **Team** the same way. @@ -76,6 +81,15 @@ Optional but recommended: xcodebuild -project TablePro.xcodeproj -scheme TablePro -configuration Debug build -skipPackagePluginValidation ``` + + + The app only loads plugins signed by the same team as the app, so a plugin + you built separately will not install into a release build. To try one in + your local build, add it to the **Copy Plug-Ins** build phase of the + **TablePro** target and run, or set `TABLEPRO_ALLOW_UNSIGNED_PLUGINS=1` in + the scheme's environment to skip the signature check. Once it works, open a + PR so the official CI signs and ships it through the registry. + {/* Screenshot: Xcode with scheme selected */} From b92d476845cc888ffd88c1ca5ab12fe059c067da Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Mon, 22 Jun 2026 14:34:18 +0700 Subject: [PATCH 2/3] Update project.pbxproj --- TablePro.xcodeproj/project.pbxproj | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/TablePro.xcodeproj/project.pbxproj b/TablePro.xcodeproj/project.pbxproj index cc02f9ab1..d448c6291 100644 --- a/TablePro.xcodeproj/project.pbxproj +++ b/TablePro.xcodeproj/project.pbxproj @@ -7,13 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 5A1MPORT000000000000A011 /* TableProImport in Frameworks */ = {isa = PBXBuildFile; productRef = 5A1MPORT000000000000A010 /* TableProImport */; }; 16C74CC07CC30A38ADE1663E /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; }; 267A5C6ECC62401598389396 /* SnowflakeDDLGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DF2F4A15214F2AA1DE95CF /* SnowflakeDDLGenerator.swift */; }; 33E6FF2997594F41AA80EEC8 /* SnowflakeConnectionRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE8D74A27EE24B89A7DC79F9 /* SnowflakeConnectionRegistry.swift */; }; 3DD7311CA07CFCA8A996058F /* SnowflakeAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D129A56E1AB45F7D82AC58 /* SnowflakeAuth.swift */; }; 4355C825A7554BBCB978E1E4 /* SnowflakeSchemaQueries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C399209C2D14499870FBD49 /* SnowflakeSchemaQueries.swift */; }; 4CA0E909166145AAB6B6CDD7 /* SnowflakeHTTPRetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55F1B63541C24A10BF4AF873 /* SnowflakeHTTPRetry.swift */; }; + 5A1MPORT000000000000A011 /* TableProImport in Frameworks */ = {isa = PBXBuildFile; productRef = 5A1MPORT000000000000A010 /* TableProImport */; }; 5A32BBFB2F9D5EAB00BAEB5F /* X509 in Frameworks */ = {isa = PBXBuildFile; productRef = 5A32BBFA2F9D5EAB00BAEB5F /* X509 */; }; 5A32BC0B2F9D659100BAEB5F /* tablepro-mcp in Copy Files */ = {isa = PBXBuildFile; fileRef = 5A32BC002F9D5F1300BAEB5F /* tablepro-mcp */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 5A3BE6FC2F97DB0000611C1F /* TableProPluginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A860000100000000 /* TableProPluginKit.framework */; }; @@ -66,7 +66,6 @@ 5ACE00012F4F000000000005 /* CodeEditLanguages in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000003 /* CodeEditLanguages */; }; 5ACE00012F4F000000000006 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000007 /* CodeEditTextView */; }; 5ACE00012F4F00000000000A /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 5ACE00012F4F000000000009 /* Sparkle */; }; - 5ACE252A2FE4508500357377 /* DuckDBDriver.tableplugin in Copy Plug-Ins (12 items) */ = {isa = PBXBuildFile; fileRef = 5A869000100000000 /* DuckDBDriver.tableplugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5AD1D8C12FB5000000000001 /* TableProMSSQLCore in Frameworks */ = {isa = PBXBuildFile; productRef = 5AD1D8C12FB5000000000002 /* TableProMSSQLCore */; }; 5ADDB00100000000000000A1 /* DynamoDBConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADDB00200000000000000A1 /* DynamoDBConnection.swift */; }; 5ADDB00100000000000000A2 /* DynamoDBItemFlattener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADDB00200000000000000A2 /* DynamoDBItemFlattener.swift */; }; @@ -289,7 +288,6 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 5ACE252A2FE4508500357377 /* DuckDBDriver.tableplugin in Copy Plug-Ins (12 items) */, 5A865000D00000000 /* MySQLDriver.tableplugin in Copy Plug-Ins (12 items) */, 5A868000D00000000 /* PostgreSQLDriver.tableplugin in Copy Plug-Ins (12 items) */, 5A862000D00000000 /* SQLiteDriver.tableplugin in Copy Plug-Ins (12 items) */, @@ -343,7 +341,7 @@ 5A866000100000000 /* MongoDBDriver.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MongoDBDriver.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 5A867000100000000 /* RedisDriver.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RedisDriver.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 5A868000100000000 /* PostgreSQLDriver.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PostgreSQLDriver.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; - 5A869000100000000 /* DuckDBDriver.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DuckDBDriver.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; + 5A869000100000000 /* DuckDBDriver.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = DuckDBDriver.tableplugin; path = /Users/ngoquocdat/Workspaces/TablePro/build/Debug/DuckDBDriver.tableplugin; sourceTree = ""; }; 5A86A000100000000 /* CSVExport.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CSVExport.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 5A86B000100000000 /* JSONExport.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JSONExport.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; 5A86C000100000000 /* SQLExport.tableplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SQLExport.tableplugin; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1122,7 +1120,6 @@ 5A866000100000000 /* MongoDBDriver.tableplugin */, 5A867000100000000 /* RedisDriver.tableplugin */, 5A868000100000000 /* PostgreSQLDriver.tableplugin */, - 5A869000100000000 /* DuckDBDriver.tableplugin */, 5A87A000100000000 /* CassandraDriver.tableplugin */, 5A86A000100000000 /* CSVExport.tableplugin */, 5A86B000100000000 /* JSONExport.tableplugin */, @@ -4788,6 +4785,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 5A1MPORT000000000000A010 /* TableProImport */ = { + isa = XCSwiftPackageProductDependency; + package = 5A0000012F4F000000000102 /* XCLocalSwiftPackageReference "Packages/TableProCore" */; + productName = TableProImport; + }; 5A32BBFA2F9D5EAB00BAEB5F /* X509 */ = { isa = XCSwiftPackageProductDependency; package = 5A32BBF92F9D5EAB00BAEB5F /* XCRemoteSwiftPackageReference "swift-certificates" */; @@ -4824,11 +4826,6 @@ package = 5A0000012F4F000000000102 /* XCLocalSwiftPackageReference "Packages/TableProCore" */; productName = TableProMSSQLCore; }; - 5A1MPORT000000000000A010 /* TableProImport */ = { - isa = XCSwiftPackageProductDependency; - package = 5A0000012F4F000000000102 /* XCLocalSwiftPackageReference "Packages/TableProCore" */; - productName = TableProImport; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 5A1091BF2EF17EDC0055EA7C /* Project object */; From 476c2af53cffa2fab08c835e17b708f91ba9781d Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Mon, 22 Jun 2026 14:34:23 +0700 Subject: [PATCH 3/3] Update Localizable.xcstrings --- TablePro/Resources/Localizable.xcstrings | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/TablePro/Resources/Localizable.xcstrings b/TablePro/Resources/Localizable.xcstrings index 8ddbf50dc..dfc13e86d 100644 --- a/TablePro/Resources/Localizable.xcstrings +++ b/TablePro/Resources/Localizable.xcstrings @@ -12713,6 +12713,7 @@ } }, "CA certificate not found: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -15748,6 +15749,7 @@ } }, "Client certificate not found: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -15917,6 +15919,7 @@ } }, "Client key not found: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -23814,6 +23817,7 @@ } }, "Database type \"%@\" is not installed" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -24435,6 +24439,7 @@ } }, "Decryption failed: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -33109,6 +33114,7 @@ } }, "Failed to encode connection data" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -33908,6 +33914,7 @@ } }, "Failed to parse connection file: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -40070,6 +40077,7 @@ } }, "Incorrect passphrase" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -42158,6 +42166,7 @@ } }, "Jump host key not found: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -73551,6 +73560,7 @@ } }, "SSH private key not found: %@" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -78137,6 +78147,7 @@ } }, "The encrypted file is corrupt or incomplete" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -79316,6 +79327,7 @@ } }, "This file is encrypted and requires a passphrase" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -79344,6 +79356,7 @@ } }, "This file is not a valid TablePro export" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -79372,6 +79385,7 @@ } }, "This file requires a newer version of TablePro (format version %d)" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : { @@ -83440,6 +83454,7 @@ } }, "Unsupported encryption version %d" : { + "extractionState" : "stale", "localizations" : { "tr" : { "stringUnit" : {