diff --git a/gogio/help.go b/gogio/help.go
index 0338344..778a559 100644
--- a/gogio/help.go
+++ b/gogio/help.go
@@ -69,7 +69,8 @@ its deletion.
The -x flag will print all the external commands executed by the gogio tool.
The -signkey flag specifies the path of the keystore, used for signing Android apk/aab files
-or specifies the name of key on Keychain to sign MacOS app.
+or specifies the name of key on Keychain to sign MacOS apps. On iOS and macOS it can be used
+to specify the path of a provisioning profile (.mobileprovision/.provisionprofile).
The -signpass flag specifies the password of the keystore, ignored if -signkey is not provided.
If -signpass is not sepecified it will be read from the environment variable GOGIO_SIGNPASS.
diff --git a/gogio/iosbuild.go b/gogio/iosbuild.go
index 5d1db69..08bca1b 100644
--- a/gogio/iosbuild.go
+++ b/gogio/iosbuild.go
@@ -75,7 +75,29 @@ func buildIOS(tmpDir, target string, bi *buildInfo) error {
if err := exeIOS(tmpDir, target, appDir, bi); err != nil {
return err
}
- if err := signIOS(bi, tmpDir, appDir); err != nil {
+
+ embedded := filepath.Join(appDir, "embedded.mobileprovision")
+
+ var provisions []string
+ if bi.key == "" {
+ if ext := filepath.Ext(bi.key); ext != ".mobileprovision" && ext != ".provisionprofile" {
+ return fmt.Errorf("sign: -signkey specifies an Apple provisioning profile, but %q does not end in .mobileprovision or .provisionprofile", bi.key)
+ }
+ provisions = []string{bi.key}
+ } else {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return err
+ }
+
+ p, err := filepath.Glob(filepath.Join(home, "Library", "MobileDevice", "Provisioning Profiles", "*.mobileprovision"))
+ if err != nil {
+ return err
+ }
+ provisions = p
+ }
+
+ if err := signApple(bi.appID, tmpDir, embedded, appDir, provisions); err != nil {
return err
}
return zipDir(out, tmpDir, "Payload")
@@ -84,16 +106,8 @@ func buildIOS(tmpDir, target string, bi *buildInfo) error {
}
}
-func signIOS(bi *buildInfo, tmpDir, app string) error {
- home, err := os.UserHomeDir()
- if err != nil {
- return err
- }
- provPattern := filepath.Join(home, "Library", "MobileDevice", "Provisioning Profiles", "*.mobileprovision")
- provisions, err := filepath.Glob(provPattern)
- if err != nil {
- return err
- }
+// signApple is shared between iOS and macOS.
+func signApple(appID, tmpDir, embedded, app string, provisions []string) error {
provInfo := filepath.Join(tmpDir, "provision.plist")
var avail []string
for _, prov := range provisions {
@@ -117,17 +131,23 @@ func signIOS(bi *buildInfo, tmpDir, app string) error {
if err != nil {
return err
}
- provAppID, err := runCmd(exec.Command("/usr/libexec/PlistBuddy", "-c", "Print:Entitlements:application-identifier", provInfo))
+
+ // iOS/macOS Catalyst
+ provAppIDSearchKey := "Print:Entitlements:application-identifier"
+ if filepath.Ext(prov) == ".provisionprofile" {
+ // macOS
+ provAppIDSearchKey = "Print:Entitlements:com.apple.application-identifier"
+ }
+ provAppID, err := runCmd(exec.Command("/usr/libexec/PlistBuddy", "-c", provAppIDSearchKey, provInfo))
if err != nil {
return err
}
- expAppID := fmt.Sprintf("%s.%s", appIDPrefix, bi.appID)
+ expAppID := fmt.Sprintf("%s.%s", appIDPrefix, appID)
avail = append(avail, provAppID)
if expAppID != provAppID {
continue
}
// Copy provisioning file.
- embedded := filepath.Join(app, "embedded.mobileprovision")
if err := copyFile(embedded, prov); err != nil {
return err
}
@@ -147,10 +167,18 @@ func signIOS(bi *buildInfo, tmpDir, app string) error {
}
identity := sha1.Sum(certDER)
idHex := hex.EncodeToString(identity[:])
- _, err = runCmd(exec.Command("codesign", "-s", idHex, "-v", "--entitlements", entFile, app))
+ _, err = runCmd(exec.Command(
+ "codesign",
+ "--sign", idHex,
+ "--deep",
+ "--force",
+ "--options", "runtime",
+ "--entitlements",
+ entFile,
+ app))
return err
}
- return fmt.Errorf("sign: no valid provisioning profile found for bundle id %q among %v", bi.appID, avail)
+ return fmt.Errorf("sign: no valid provisioning profile found for bundle id %q among %v", appID, avail)
}
func exeIOS(tmpDir, target, app string, bi *buildInfo) error {
diff --git a/gogio/macosbuild.go b/gogio/macosbuild.go
index b9b79dd..2413b9e 100644
--- a/gogio/macosbuild.go
+++ b/gogio/macosbuild.go
@@ -148,7 +148,7 @@ func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) {
NSHighResolutionCapable
CFBundlePackageType
- APPL
+ BNDL
{{if .Schemes}}
CFBundleURLTypes
@@ -232,6 +232,12 @@ func (b *macBuilder) signProgram(buildInfo *buildInfo, binDest string, name stri
return err
}
+ // If the key is a provisioning profile use the same signing process as iOS
+ if filepath.Ext(buildInfo.key) == ".provisionprofile" {
+ embedded := filepath.Join(binDest, "Contents", "embedded.provisionprofile")
+ return signApple(buildInfo.appID, b.TempDir, embedded, binDest, []string{buildInfo.key})
+ }
+
cmd := exec.Command(
"codesign",
"--deep",
diff --git a/gogio/main.go b/gogio/main.go
index fb730f2..8ef6f89 100644
--- a/gogio/main.go
+++ b/gogio/main.go
@@ -36,7 +36,7 @@ var (
extraLdflags = flag.String("ldflags", "", "extra flags to the Go linker")
extraTags = flag.String("tags", "", "extra tags to the Go tool")
iconPath = flag.String("icon", "", "specify an icon for iOS and Android")
- signKey = flag.String("signkey", "", "specify the path of the keystore to be used to sign Android apk files.")
+ signKey = flag.String("signkey", "", "specify the path of the keystore (Android) or provisioning profile (macOS or iOS) for signing")
signPass = flag.String("signpass", "", "specify the password to decrypt the signkey.")
notaryID = flag.String("notaryid", "", "specify the apple id to use for notarization.")
notaryPass = flag.String("notarypass", "", "specify app-specific password of the Apple ID to be used for notarization.")