From bf700e42ccb640677b73f5d7c6bde4b65dd7ce8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Tue, 8 Oct 2024 13:55:47 +0200 Subject: [PATCH 1/6] Reorganise export options generator and add support for automatic signing style --- exportoptionsgenerator/certificates.go | 21 + .../exportoptionsgenerator.go | 445 +++++++----------- .../exportoptionsgenerator_test.go | 163 ++++++- exportoptionsgenerator/profiles.go | 73 +++ exportoptionsgenerator/targets.go | 75 +++ 5 files changed, 497 insertions(+), 280 deletions(-) create mode 100644 exportoptionsgenerator/certificates.go create mode 100644 exportoptionsgenerator/profiles.go create mode 100644 exportoptionsgenerator/targets.go diff --git a/exportoptionsgenerator/certificates.go b/exportoptionsgenerator/certificates.go new file mode 100644 index 00000000..d916ce54 --- /dev/null +++ b/exportoptionsgenerator/certificates.go @@ -0,0 +1,21 @@ +package exportoptionsgenerator + +import "github.com/bitrise-io/go-xcode/certificateutil" + +// CodesignIdentityProvider can list certificate infos. +type CodesignIdentityProvider interface { + ListCodesignIdentities() ([]certificateutil.CertificateInfoModel, error) +} + +// LocalCodesignIdentityProvider ... +type LocalCodesignIdentityProvider struct{} + +// ListCodesignIdentities ... +func (p LocalCodesignIdentityProvider) ListCodesignIdentities() ([]certificateutil.CertificateInfoModel, error) { + certs, err := certificateutil.InstalledCodesigningCertificateInfos() + if err != nil { + return nil, err + } + certInfo := certificateutil.FilterValidCertificateInfos(certs) + return append(certInfo.ValidCertificates, certInfo.DuplicatedCertificates...), nil +} diff --git a/exportoptionsgenerator/exportoptionsgenerator.go b/exportoptionsgenerator/exportoptionsgenerator.go index 108d3e57..e82b67a2 100644 --- a/exportoptionsgenerator/exportoptionsgenerator.go +++ b/exportoptionsgenerator/exportoptionsgenerator.go @@ -2,15 +2,8 @@ package exportoptionsgenerator import ( "fmt" - "io" - "net/http" - "os" - "path/filepath" - - "github.com/bitrise-io/go-utils/pathutil" "github.com/bitrise-io/go-utils/sliceutil" "github.com/bitrise-io/go-utils/v2/log" - "github.com/bitrise-io/go-xcode/certificateutil" "github.com/bitrise-io/go-xcode/export" "github.com/bitrise-io/go-xcode/exportoptions" "github.com/bitrise-io/go-xcode/plistutil" @@ -18,12 +11,18 @@ import ( "github.com/bitrise-io/go-xcode/xcodeproject/serialized" "github.com/bitrise-io/go-xcode/xcodeproject/xcodeproj" "github.com/bitrise-io/go-xcode/xcodeproject/xcscheme" + "os" ) -// const for AppClipProductType and manualSigningStyle const ( AppClipProductType = "com.apple.product-type.application.on-demand-install-capable" - manualSigningStyle = "manual" +) + +type SigningStyle string + +const ( + ManualSigningStyle = "manual" + AutomaticSigningStyle = "automatic" ) // ExportOptionsGenerator generates an exportOptions.plist file. @@ -53,14 +52,60 @@ func New(xcodeProj *xcodeproj.XcodeProj, scheme *xcscheme.Scheme, configuration } // GenerateApplicationExportOptions generates exportOptions for an application export. -func (g ExportOptionsGenerator) GenerateApplicationExportOptions(exportMethod exportoptions.Method, containerEnvironment string, teamID string, uploadBitcode bool, compileBitcode bool, xcodeManaged bool, - xcodeMajorVersion int64) (exportoptions.ExportOptions, error) { +func (g ExportOptionsGenerator) GenerateApplicationExportOptions( + exportMethod exportoptions.Method, + containerEnvironment string, + teamID string, + uploadBitcode bool, + compileBitcode bool, + archivedWithXcodeManagedProfiles bool, + codeSigningStyle SigningStyle, + xcodeMajorVersion int64, +) (exportoptions.ExportOptions, error) { + mainTargetBundleID, entitlementsByBundleID, err := g.applicationTargetsAndEntitlements(exportMethod) + if err != nil { + return nil, err + } + + iCloudContainerEnvironment, err := determineIcloudContainerEnvironment(containerEnvironment, entitlementsByBundleID, exportMethod, xcodeMajorVersion) + if err != nil { + return nil, err + } + + exportOpts := generateBaseExportOptions(exportMethod, uploadBitcode, compileBitcode, iCloudContainerEnvironment) + if xcodeMajorVersion >= 12 { + exportOpts = addDistributionBundleIdentifierFromXcode12(exportOpts, mainTargetBundleID) + } + if xcodeMajorVersion >= 13 { + exportOpts = disableManagedBuildNumberFromXcode13(exportOpts) + } - g.logger.TDebugf("Generating application export options for: %s", exportMethod) + if xcodeMajorVersion >= 15 { + exportOpts = addSigningStyle(exportOpts, codeSigningStyle) + exportOpts = addDestinationExport(exportOpts) + } + + if codeSigningStyle == AutomaticSigningStyle { + exportOpts = addTeamID(exportOpts, teamID) + } else { + codeSignGroup, err := g.determineCodesignGroup(entitlementsByBundleID, exportMethod, teamID, archivedWithXcodeManagedProfiles) + if err != nil { + return nil, err + } + if codeSignGroup == nil { + return exportOpts, nil + } + exportOpts = addManualSigningFields(exportOpts, codeSignGroup, archivedWithXcodeManagedProfiles, g.logger) + } + + return exportOpts, nil +} + +func (g ExportOptionsGenerator) applicationTargetsAndEntitlements(exportMethod exportoptions.Method) (string, map[string]plistutil.PlistData, error) { mainTarget, err := ArchivableApplicationTarget(g.xcodeProj, g.scheme) if err != nil { - return nil, err + return "", nil, err } dependentTargets := filterApplicationBundleTargets( @@ -74,12 +119,12 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions(exportMethod ex for i, target := range targets { bundleID, err := g.targetInfoProvider.TargetBundleID(target.Name, g.configuration) if err != nil { - return nil, fmt.Errorf("failed to get target (%s) bundle id: %s", target.Name, err) + return "", nil, fmt.Errorf("failed to get target (%s) bundle id: %s", target.Name, err) } entitlements, err := g.targetInfoProvider.TargetCodeSignEntitlements(target.Name, g.configuration) if err != nil && !serialized.IsKeyNotFoundError(err) { - return nil, fmt.Errorf("failed to get target (%s) bundle id: %s", target.Name, err) + return "", nil, fmt.Errorf("failed to get target (%s) bundle id: %s", target.Name, err) } entitlementsByBundleID[bundleID] = plistutil.PlistData(entitlements) @@ -89,177 +134,7 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions(exportMethod ex } } - g.logger.TDebugf("Generated application export options plist for: %s", exportMethod) - - return g.generateExportOptions(exportMethod, containerEnvironment, teamID, uploadBitcode, compileBitcode, - xcodeManaged, entitlementsByBundleID, xcodeMajorVersion, mainTargetBundleID) -} - -// TargetInfoProvider can determine a target's bundle id and codesign entitlements. -type TargetInfoProvider interface { - TargetBundleID(target, configuration string) (string, error) - TargetCodeSignEntitlements(target, configuration string) (serialized.Object, error) -} - -// XcodebuildTargetInfoProvider implements TargetInfoProvider. -type XcodebuildTargetInfoProvider struct { - xcodeProj *xcodeproj.XcodeProj -} - -// TargetBundleID ... -func (b XcodebuildTargetInfoProvider) TargetBundleID(target, configuration string) (string, error) { - return b.xcodeProj.TargetBundleID(target, configuration) -} - -// TargetCodeSignEntitlements ... -func (b XcodebuildTargetInfoProvider) TargetCodeSignEntitlements(target, configuration string) (serialized.Object, error) { - return b.xcodeProj.TargetCodeSignEntitlements(target, configuration) -} - -// ArchivableApplicationTarget locate archivable app target from a given project and scheme -func ArchivableApplicationTarget(xcodeProj *xcodeproj.XcodeProj, scheme *xcscheme.Scheme) (*xcodeproj.Target, error) { - archiveEntry, ok := scheme.AppBuildActionEntry() - if !ok { - return nil, fmt.Errorf("archivable entry not found in project: %s for scheme: %s", xcodeProj.Path, scheme.Name) - } - - mainTarget, ok := xcodeProj.Proj.Target(archiveEntry.BuildableReference.BlueprintIdentifier) - if !ok { - return nil, fmt.Errorf("target not found: %s", archiveEntry.BuildableReference.BlueprintIdentifier) - } - - return &mainTarget, nil -} - -func filterApplicationBundleTargets(targets []xcodeproj.Target, exportMethod exportoptions.Method) (filteredTargets []xcodeproj.Target) { - fmt.Printf("Filtering %v application bundle targets", len(targets)) - - for _, target := range targets { - if !target.IsExecutableProduct() { - continue - } - - // App store exports contain App Clip too. App Clip provisioning profile has to be included in export options: - // .. - // provisioningProfiles - // - // io.bundle.id - // Development Application Profile - // io.bundle.id.AppClipID - // Development App Clip Profile - // - // .., - if exportMethod != exportoptions.MethodAppStore && target.IsAppClipProduct() { - continue - } - - filteredTargets = append(filteredTargets, target) - } - - fmt.Printf("Found %v application bundle targets", len(filteredTargets)) - - return -} - -// projectUsesCloudKit determines whether the project uses any CloudKit capability or not. -func projectUsesCloudKit(bundleIDEntitlementsMap map[string]plistutil.PlistData) bool { - fmt.Printf("Checking if project uses CloudKit") - - for _, entitlements := range bundleIDEntitlementsMap { - if entitlements == nil { - continue - } - - services, ok := entitlements.GetStringArray("com.apple.developer.icloud-services") - if !ok { - continue - } - - if sliceutil.IsStringInSlice("CloudKit", services) || sliceutil.IsStringInSlice("CloudDocuments", services) { - fmt.Printf("Project uses CloudKit") - - return true - } - } - return false -} - -// determineIcloudContainerEnvironment calculates the value of iCloudContainerEnvironment. -func determineIcloudContainerEnvironment(desiredIcloudContainerEnvironment string, bundleIDEntitlementsMap map[string]plistutil.PlistData, exportMethod exportoptions.Method, xcodeMajorVersion int64) (string, error) { - // iCloudContainerEnvironment: If the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. - // Available options vary depending on the type of provisioning profile used, but may include: Development and Production. - usesCloudKit := projectUsesCloudKit(bundleIDEntitlementsMap) - if !usesCloudKit { - return "", nil - } - - // From Xcode 9 iCloudContainerEnvironment is required for every export method, before that version only for non app-store exports. - if xcodeMajorVersion < 9 && exportMethod == exportoptions.MethodAppStore { - return "", nil - } - - if exportMethod == exportoptions.MethodAppStore { - return "Production", nil - } - - if desiredIcloudContainerEnvironment == "" { - return "", fmt.Errorf("Your project uses CloudKit but \"iCloud container environment\" input not specified.\n"+ - "Export method is: %s (For app-store export method Production container environment is implied.)", exportMethod) - } - - return desiredIcloudContainerEnvironment, nil -} - -// generateBaseExportOptions creates a default exportOptions introudced in Xcode 7. -func generateBaseExportOptions(exportMethod exportoptions.Method, cfgUploadBitcode, cfgCompileBitcode bool, iCloudContainerEnvironment string) exportoptions.ExportOptions { - if exportMethod == exportoptions.MethodAppStore { - appStoreOptions := exportoptions.NewAppStoreOptions() - appStoreOptions.UploadBitcode = cfgUploadBitcode - if iCloudContainerEnvironment != "" { - appStoreOptions.ICloudContainerEnvironment = exportoptions.ICloudContainerEnvironment(iCloudContainerEnvironment) - } - return appStoreOptions - } - - nonAppStoreOptions := exportoptions.NewNonAppStoreOptions(exportMethod) - nonAppStoreOptions.CompileBitcode = cfgCompileBitcode - - if iCloudContainerEnvironment != "" { - nonAppStoreOptions.ICloudContainerEnvironment = exportoptions.ICloudContainerEnvironment(iCloudContainerEnvironment) - } - - return nonAppStoreOptions -} - -// CodesignIdentityProvider can list certificate infos. -type CodesignIdentityProvider interface { - ListCodesignIdentities() ([]certificateutil.CertificateInfoModel, error) -} - -// LocalCodesignIdentityProvider ... -type LocalCodesignIdentityProvider struct{} - -// ListCodesignIdentities ... -func (p LocalCodesignIdentityProvider) ListCodesignIdentities() ([]certificateutil.CertificateInfoModel, error) { - certs, err := certificateutil.InstalledCodesigningCertificateInfos() - if err != nil { - return nil, err - } - certInfo := certificateutil.FilterValidCertificateInfos(certs) - return append(certInfo.ValidCertificates, certInfo.DuplicatedCertificates...), nil -} - -// ProvisioningProfileProvider can list profile infos. -type ProvisioningProfileProvider interface { - ListProvisioningProfiles() ([]profileutil.ProvisioningProfileInfoModel, error) -} - -// LocalProvisioningProfileProvider ... -type LocalProvisioningProfileProvider struct{} - -// ListProvisioningProfiles ... -func (p LocalProvisioningProfileProvider) ListProvisioningProfiles() ([]profileutil.ProvisioningProfileInfoModel, error) { - return profileutil.InstalledProvisioningProfileInfos(profileutil.ProfileTypeIos) + return mainTargetBundleID, entitlementsByBundleID, nil } // determineCodesignGroup finds the best codesign group (certificate + profiles) @@ -358,7 +233,7 @@ func (g ExportOptionsGenerator) determineCodesignGroup(bundleIDEntitlementsMap m defaultProfileURL := os.Getenv("BITRISE_DEFAULT_PROVISION_URL") if teamID == "" && defaultProfileURL != "" { - if defaultProfile, err := g.GetDefaultProvisioningProfile(); err == nil { + if defaultProfile, err := g.profileProvider.GetDefaultProvisioningProfile(); err == nil { g.logger.Debugf("\ndefault profile: %v\n", defaultProfile) filteredCodeSignGroups := export.FilterSelectableCodeSignGroups(codeSignGroups, export.CreateExcludeProfileNameSelectableCodeSignGroupFilter(defaultProfile.Name)) @@ -408,6 +283,76 @@ func (g ExportOptionsGenerator) determineCodesignGroup(bundleIDEntitlementsMap m return &iosCodeSignGroups[0], nil } +// determineIcloudContainerEnvironment calculates the value of iCloudContainerEnvironment. +func determineIcloudContainerEnvironment(desiredIcloudContainerEnvironment string, bundleIDEntitlementsMap map[string]plistutil.PlistData, exportMethod exportoptions.Method, xcodeMajorVersion int64) (string, error) { + // iCloudContainerEnvironment: If the app is using CloudKit, this configures the "com.apple.developer.icloud-container-environment" entitlement. + // Available options vary depending on the type of provisioning profile used, but may include: Development and Production. + usesCloudKit := projectUsesCloudKit(bundleIDEntitlementsMap) + if !usesCloudKit { + return "", nil + } + + // From Xcode 9 iCloudContainerEnvironment is required for every export method, before that version only for non app-store exports. + if xcodeMajorVersion < 9 && exportMethod == exportoptions.MethodAppStore { + return "", nil + } + + if exportMethod == exportoptions.MethodAppStore { + return "Production", nil + } + + if desiredIcloudContainerEnvironment == "" { + return "", fmt.Errorf("Your project uses CloudKit but \"iCloud container environment\" input not specified.\n"+ + "Export method is: %s (For app-store export method Production container environment is implied.)", exportMethod) + } + + return desiredIcloudContainerEnvironment, nil +} + +// projectUsesCloudKit determines whether the project uses any CloudKit capability or not. +func projectUsesCloudKit(bundleIDEntitlementsMap map[string]plistutil.PlistData) bool { + fmt.Printf("Checking if project uses CloudKit") + + for _, entitlements := range bundleIDEntitlementsMap { + if entitlements == nil { + continue + } + + services, ok := entitlements.GetStringArray("com.apple.developer.icloud-services") + if !ok { + continue + } + + if sliceutil.IsStringInSlice("CloudKit", services) || sliceutil.IsStringInSlice("CloudDocuments", services) { + fmt.Printf("Project uses CloudKit") + + return true + } + } + return false +} + +// generateBaseExportOptions creates a default exportOptions introudced in Xcode 7. +func generateBaseExportOptions(exportMethod exportoptions.Method, cfgUploadBitcode, cfgCompileBitcode bool, iCloudContainerEnvironment string) exportoptions.ExportOptions { + if exportMethod == exportoptions.MethodAppStore { + appStoreOptions := exportoptions.NewAppStoreOptions() + appStoreOptions.UploadBitcode = cfgUploadBitcode + if iCloudContainerEnvironment != "" { + appStoreOptions.ICloudContainerEnvironment = exportoptions.ICloudContainerEnvironment(iCloudContainerEnvironment) + } + return appStoreOptions + } + + nonAppStoreOptions := exportoptions.NewNonAppStoreOptions(exportMethod) + nonAppStoreOptions.CompileBitcode = cfgCompileBitcode + + if iCloudContainerEnvironment != "" { + nonAppStoreOptions.ICloudContainerEnvironment = exportoptions.ICloudContainerEnvironment(iCloudContainerEnvironment) + } + + return nonAppStoreOptions +} + func addDistributionBundleIdentifierFromXcode12(exportOpts exportoptions.ExportOptions, distributionBundleIdentifier string) exportoptions.ExportOptions { switch options := exportOpts.(type) { case exportoptions.AppStoreOptionsModel: @@ -432,66 +377,71 @@ func disableManagedBuildNumberFromXcode13(exportOpts exportoptions.ExportOptions return exportOpts } -// generateExportOptions generates an exportOptions based on the provided conditions. -func (g ExportOptionsGenerator) generateExportOptions(exportMethod exportoptions.Method, containerEnvironment string, teamID string, uploadBitcode bool, compileBitcode bool, xcodeManaged bool, - bundleIDEntitlementsMap map[string]plistutil.PlistData, xcodeMajorVersion int64, distributionBundleIdentifier string) (exportoptions.ExportOptions, error) { - g.logger.TDebugf("Generating export options") - - iCloudContainerEnvironment, err := determineIcloudContainerEnvironment(containerEnvironment, bundleIDEntitlementsMap, exportMethod, xcodeMajorVersion) - if err != nil { - return nil, err +func addSigningStyle(exportOpts exportoptions.ExportOptions, signingStyle SigningStyle) exportoptions.ExportOptions { + switch options := exportOpts.(type) { + case exportoptions.AppStoreOptionsModel: + options.SigningStyle = string(signingStyle) + return options + case exportoptions.NonAppStoreOptionsModel: + options.SigningStyle = string(signingStyle) + return options } + return exportOpts +} - g.logger.Printf("Adding bundle id") - - exportOpts := generateBaseExportOptions(exportMethod, uploadBitcode, compileBitcode, iCloudContainerEnvironment) - if xcodeMajorVersion >= 12 { - exportOpts = addDistributionBundleIdentifierFromXcode12(exportOpts, distributionBundleIdentifier) - } - if xcodeMajorVersion >= 13 { - exportOpts = disableManagedBuildNumberFromXcode13(exportOpts) +func addDestinationExport(exportOpts exportoptions.ExportOptions) exportoptions.ExportOptions { + switch options := exportOpts.(type) { + case exportoptions.AppStoreOptionsModel: + options.Destination = exportoptions.DestinationExport + return options + case exportoptions.NonAppStoreOptionsModel: + options.Destination = exportoptions.DestinationExport + return options } + return exportOpts +} - g.logger.TDebugf("Determining code signing group") - - codeSignGroup, err := g.determineCodesignGroup(bundleIDEntitlementsMap, exportMethod, teamID, xcodeManaged) - if err != nil { - return nil, err - } - if codeSignGroup == nil { - return exportOpts, nil +func addTeamID(exportOpts exportoptions.ExportOptions, teamID string) exportoptions.ExportOptions { + switch options := exportOpts.(type) { + case exportoptions.AppStoreOptionsModel: + options.TeamID = teamID + return options + case exportoptions.NonAppStoreOptionsModel: + options.TeamID = teamID + return options } + return exportOpts +} +func addManualSigningFields(exportOpts exportoptions.ExportOptions, codeSignGroup *export.IosCodeSignGroup, archivedWithXcodeManagedProfiles bool, logger log.Logger) exportoptions.ExportOptions { exportCodeSignStyle := "" exportProfileMapping := map[string]string{} - g.logger.TDebugf("Determining code signing style") - for bundleID, profileInfo := range codeSignGroup.BundleIDProfileMap() { exportProfileMapping[bundleID] = profileInfo.Name isXcodeManaged := profileutil.IsXcodeManaged(profileInfo.Name) if isXcodeManaged { if exportCodeSignStyle != "" && exportCodeSignStyle != "automatic" { - g.logger.Errorf("Both Xcode managed and NON Xcode managed profiles in code signing group") + logger.Errorf("Both Xcode managed and NON Xcode managed profiles in code signing group") } exportCodeSignStyle = "automatic" } else { - if exportCodeSignStyle != "" && exportCodeSignStyle != manualSigningStyle { - g.logger.Errorf("Both Xcode managed and NON Xcode managed profiles in code signing group") + if exportCodeSignStyle != "" && exportCodeSignStyle != ManualSigningStyle { + logger.Errorf("Both Xcode managed and NON Xcode managed profiles in code signing group") } - exportCodeSignStyle = manualSigningStyle + exportCodeSignStyle = ManualSigningStyle } } - shouldSetManualSigning := xcodeManaged && exportCodeSignStyle == manualSigningStyle + shouldSetManualSigning := archivedWithXcodeManagedProfiles && exportCodeSignStyle == ManualSigningStyle if shouldSetManualSigning { - g.logger.Warnf("App was signed with Xcode managed profile when archiving,") - g.logger.Warnf("ipa export uses manual code signing.") - g.logger.Warnf(`Setting "signingStyle" to "manual".`) + logger.Warnf("App was signed with Xcode managed profile when archiving,") + logger.Warnf("ipa export uses manual code signing.") + logger.Warnf(`Setting "signingStyle" to "manual".`) } - g.logger.TDebugf("Determined code signing style") + logger.TDebugf("Determined code signing style") switch options := exportOpts.(type) { case exportoptions.AppStoreOptionsModel: @@ -500,7 +450,7 @@ func (g ExportOptionsGenerator) generateExportOptions(exportMethod exportoptions options.TeamID = codeSignGroup.Certificate().TeamID if shouldSetManualSigning { - options.SigningStyle = manualSigningStyle + options.SigningStyle = ManualSigningStyle } exportOpts = options case exportoptions.NonAppStoreOptionsModel: @@ -509,55 +459,10 @@ func (g ExportOptionsGenerator) generateExportOptions(exportMethod exportoptions options.TeamID = codeSignGroup.Certificate().TeamID if shouldSetManualSigning { - options.SigningStyle = manualSigningStyle + options.SigningStyle = ManualSigningStyle } exportOpts = options } - return exportOpts, nil -} - -// GetDefaultProvisioningProfile ... -func (g ExportOptionsGenerator) GetDefaultProvisioningProfile() (profileutil.ProvisioningProfileInfoModel, error) { - defaultProfileURL := os.Getenv("BITRISE_DEFAULT_PROVISION_URL") - if defaultProfileURL == "" { - return profileutil.ProvisioningProfileInfoModel{}, nil - } - - tmpDir, err := pathutil.NormalizedOSTempDirPath("tmp_default_profile") - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - tmpDst := filepath.Join(tmpDir, "default.mobileprovision") - tmpDstFile, err := os.Create(tmpDst) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - defer func() { - if err := tmpDstFile.Close(); err != nil { - g.logger.Errorf("Failed to close file (%s), error: %s", tmpDst, err) - } - }() - - response, err := http.Get(defaultProfileURL) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - defer func() { - if err := response.Body.Close(); err != nil { - g.logger.Errorf("Failed to close response body, error: %s", err) - } - }() - - if _, err := io.Copy(tmpDstFile, response.Body); err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - defaultProfile, err := profileutil.NewProvisioningProfileInfoFromFile(tmpDst) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - return defaultProfile, nil + return exportOpts } diff --git a/exportoptionsgenerator/exportoptionsgenerator_test.go b/exportoptionsgenerator/exportoptionsgenerator_test.go index dd0eaf56..356c55da 100644 --- a/exportoptionsgenerator/exportoptionsgenerator_test.go +++ b/exportoptionsgenerator/exportoptionsgenerator_test.go @@ -15,7 +15,7 @@ import ( ) const ( - expectedDevelopementXcode11ExportOptions = ` + expectedDevelopmentXcode11ExportOptions = ` @@ -34,7 +34,7 @@ const ( TEAM123 ` - expectedDevelopementExportOptions = ` + expectedDevelopmentExportOptions = ` @@ -120,7 +120,7 @@ const ( TEAM123 ` - expectedNoProfilesDevelopementXcode11ExportOptions = ` + expectedNoProfilesDevelopmentXcode11ExportOptions = ` @@ -130,7 +130,7 @@ const ( development ` - expectedNoProfilesXcode13AppStorExportOptions = ` + expectedNoProfilesXcode13AppStoreExportOptions = ` @@ -156,6 +156,145 @@ const ( ` ) +func TestExportOptionsGenerator_GenerateApplicationExportOptions_ForAutomaticSigningStyle(t *testing.T) { + // Arrange + const ( + bundleID = "io.bundle.id" + teamID = "TEAM123" + ) + + logger := log.NewLogger() + logger.EnableDebugLog(true) + + tests := []struct { + name string + generatorFactory func() ExportOptionsGenerator + exportMethod exportoptions.Method + containerEnvironment string + xcodeVersion int64 + want string + wantErr bool + }{ + { + name: "Default development exportOptions", + exportMethod: exportoptions.MethodDevelopment, + xcodeVersion: 15, + generatorFactory: func() ExportOptionsGenerator { + applicationTarget := givenApplicationTarget(nil) + xcodeProj := givenXcodeproj([]xcodeproj.Target{applicationTarget}) + scheme := givenScheme(applicationTarget) + + g := New(&xcodeProj, &scheme, "", logger) + g.targetInfoProvider = MockTargetInfoProvider{ + bundleID: map[string]string{"Application": bundleID}, + } + + return g + }, + want: ` + + + + destination + export + distributionBundleIdentifier + io.bundle.id + method + development + signingStyle + automatic + teamID + TEAM123 + +`, + }, + { + name: "Default app store exportOptions", + exportMethod: exportoptions.MethodAppStore, + xcodeVersion: 15, + generatorFactory: func() ExportOptionsGenerator { + applicationTarget := givenApplicationTarget(nil) + xcodeProj := givenXcodeproj([]xcodeproj.Target{applicationTarget}) + scheme := givenScheme(applicationTarget) + + g := New(&xcodeProj, &scheme, "", logger) + g.targetInfoProvider = MockTargetInfoProvider{ + bundleID: map[string]string{"Application": bundleID}, + } + + return g + }, + want: ` + + + + destination + export + manageAppVersionAndBuildNumber + + method + app-store + signingStyle + automatic + teamID + TEAM123 + +`, + }, + { + name: "When the app uses iCloud services", + exportMethod: exportoptions.MethodDevelopment, + containerEnvironment: string(exportoptions.ICloudContainerEnvironmentProduction), + xcodeVersion: 15, + generatorFactory: func() ExportOptionsGenerator { + applicationTarget := givenApplicationTarget(nil) + xcodeProj := givenXcodeproj([]xcodeproj.Target{applicationTarget}) + scheme := givenScheme(applicationTarget) + + g := New(&xcodeProj, &scheme, "", logger) + g.targetInfoProvider = MockTargetInfoProvider{ + bundleID: map[string]string{"Application": bundleID}, + codesignEntitlements: map[string]serialized.Object{"Application": map[string]interface{}{"com.apple.developer.icloud-services": []string{"CloudKit"}}}, + } + + return g + }, + want: ` + + + + destination + export + distributionBundleIdentifier + io.bundle.id + iCloudContainerEnvironment + Production + method + development + signingStyle + automatic + teamID + TEAM123 + +`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Act + gotOpts, err := tt.generatorFactory().GenerateApplicationExportOptions(tt.exportMethod, tt.containerEnvironment, teamID, true, true, false, AutomaticSigningStyle, tt.xcodeVersion) + + // Assert + require.NoError(t, err) + + got, err := gotOpts.String() + require.NoError(t, err) + fmt.Println(got) + require.Equal(t, tt.want, got) + }) + } +} + func TestExportOptionsGenerator_GenerateApplicationExportOptions(t *testing.T) { const ( bundleID = "io.bundle.id" @@ -176,13 +315,13 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions(t *testing.T) { name: "Development Xcode 11", exportMethod: exportoptions.MethodDevelopment, xcodeVersion: 11, - want: expectedDevelopementXcode11ExportOptions, + want: expectedDevelopmentXcode11ExportOptions, }, { name: "Development Xcode > 12", exportMethod: exportoptions.MethodDevelopment, xcodeVersion: 13, - want: expectedDevelopementExportOptions, + want: expectedDevelopmentExportOptions, }, { name: "Ad-hoc", @@ -245,7 +384,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions(t *testing.T) { } // Act - gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, tt.xcodeVersion) + gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, ManualSigningStyle, tt.xcodeVersion) // Assert require.NoError(t, err) @@ -278,7 +417,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_WhenNoProfileFo name: "When no profiles found, Xcode 13, then manageAppVersionAndBuildNumber is included", exportMethod: exportoptions.MethodAppStore, xcodeVersion: 13, - want: expectedNoProfilesXcode13AppStorExportOptions, + want: expectedNoProfilesXcode13AppStoreExportOptions, }, { name: "When no profiles found, Xcode > 12, distributionBundleIdentifier included", @@ -290,7 +429,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_WhenNoProfileFo name: "When no profiles found, Xcode 11", exportMethod: exportoptions.MethodDevelopment, xcodeVersion: 11, - want: expectedNoProfilesDevelopementXcode11ExportOptions, + want: expectedNoProfilesDevelopmentXcode11ExportOptions, }, } for _, tt := range tests { @@ -315,7 +454,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_WhenNoProfileFo } // Act - gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, tt.xcodeVersion) + gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, ManualSigningStyle, tt.xcodeVersion) // Assert require.NoError(t, err) @@ -344,6 +483,10 @@ func (p MockProvisioningProfileProvider) ListProvisioningProfiles() ([]profileut return p.profileInfos, nil } +func (p MockProvisioningProfileProvider) GetDefaultProvisioningProfile() (profileutil.ProvisioningProfileInfoModel, error) { + return profileutil.ProvisioningProfileInfoModel{}, nil +} + type MockTargetInfoProvider struct { bundleID map[string]string codesignEntitlements map[string]serialized.Object diff --git a/exportoptionsgenerator/profiles.go b/exportoptionsgenerator/profiles.go new file mode 100644 index 00000000..e9b3928e --- /dev/null +++ b/exportoptionsgenerator/profiles.go @@ -0,0 +1,73 @@ +package exportoptionsgenerator + +import ( + "io" + "net/http" + "os" + "path/filepath" + + "github.com/bitrise-io/go-utils/pathutil" + "github.com/bitrise-io/go-utils/v2/log" + "github.com/bitrise-io/go-xcode/profileutil" +) + +// ProvisioningProfileProvider can list profile infos. +type ProvisioningProfileProvider interface { + ListProvisioningProfiles() ([]profileutil.ProvisioningProfileInfoModel, error) + GetDefaultProvisioningProfile() (profileutil.ProvisioningProfileInfoModel, error) +} + +// LocalProvisioningProfileProvider ... +type LocalProvisioningProfileProvider struct { + logger log.Logger +} + +// ListProvisioningProfiles ... +func (p LocalProvisioningProfileProvider) ListProvisioningProfiles() ([]profileutil.ProvisioningProfileInfoModel, error) { + return profileutil.InstalledProvisioningProfileInfos(profileutil.ProfileTypeIos) +} + +// GetDefaultProvisioningProfile ... +func (p LocalProvisioningProfileProvider) GetDefaultProvisioningProfile() (profileutil.ProvisioningProfileInfoModel, error) { + defaultProfileURL := os.Getenv("BITRISE_DEFAULT_PROVISION_URL") + if defaultProfileURL == "" { + return profileutil.ProvisioningProfileInfoModel{}, nil + } + + tmpDir, err := pathutil.NormalizedOSTempDirPath("tmp_default_profile") + if err != nil { + return profileutil.ProvisioningProfileInfoModel{}, err + } + + tmpDst := filepath.Join(tmpDir, "default.mobileprovision") + tmpDstFile, err := os.Create(tmpDst) + if err != nil { + return profileutil.ProvisioningProfileInfoModel{}, err + } + defer func() { + if err := tmpDstFile.Close(); err != nil { + p.logger.Warnf("Failed to close file (%s), error: %s", tmpDst, err) + } + }() + + response, err := http.Get(defaultProfileURL) + if err != nil { + return profileutil.ProvisioningProfileInfoModel{}, err + } + defer func() { + if err := response.Body.Close(); err != nil { + p.logger.Warnf("Failed to close response body, error: %s", err) + } + }() + + if _, err := io.Copy(tmpDstFile, response.Body); err != nil { + return profileutil.ProvisioningProfileInfoModel{}, err + } + + defaultProfile, err := profileutil.NewProvisioningProfileInfoFromFile(tmpDst) + if err != nil { + return profileutil.ProvisioningProfileInfoModel{}, err + } + + return defaultProfile, nil +} diff --git a/exportoptionsgenerator/targets.go b/exportoptionsgenerator/targets.go new file mode 100644 index 00000000..fa2d9042 --- /dev/null +++ b/exportoptionsgenerator/targets.go @@ -0,0 +1,75 @@ +package exportoptionsgenerator + +import ( + "fmt" + "github.com/bitrise-io/go-xcode/exportoptions" + "github.com/bitrise-io/go-xcode/xcodeproject/serialized" + "github.com/bitrise-io/go-xcode/xcodeproject/xcodeproj" + "github.com/bitrise-io/go-xcode/xcodeproject/xcscheme" +) + +// TargetInfoProvider can determine a target's bundle id and codesign entitlements. +type TargetInfoProvider interface { + TargetBundleID(target, configuration string) (string, error) + TargetCodeSignEntitlements(target, configuration string) (serialized.Object, error) +} + +// XcodebuildTargetInfoProvider implements TargetInfoProvider. +type XcodebuildTargetInfoProvider struct { + xcodeProj *xcodeproj.XcodeProj +} + +// TargetBundleID ... +func (b XcodebuildTargetInfoProvider) TargetBundleID(target, configuration string) (string, error) { + return b.xcodeProj.TargetBundleID(target, configuration) +} + +// TargetCodeSignEntitlements ... +func (b XcodebuildTargetInfoProvider) TargetCodeSignEntitlements(target, configuration string) (serialized.Object, error) { + return b.xcodeProj.TargetCodeSignEntitlements(target, configuration) +} + +// ArchivableApplicationTarget locate archivable app target from a given project and scheme +func ArchivableApplicationTarget(xcodeProj *xcodeproj.XcodeProj, scheme *xcscheme.Scheme) (*xcodeproj.Target, error) { + archiveEntry, ok := scheme.AppBuildActionEntry() + if !ok { + return nil, fmt.Errorf("archivable entry not found in project: %s for scheme: %s", xcodeProj.Path, scheme.Name) + } + + mainTarget, ok := xcodeProj.Proj.Target(archiveEntry.BuildableReference.BlueprintIdentifier) + if !ok { + return nil, fmt.Errorf("target not found: %s", archiveEntry.BuildableReference.BlueprintIdentifier) + } + + return &mainTarget, nil +} + +func filterApplicationBundleTargets(targets []xcodeproj.Target, exportMethod exportoptions.Method) (filteredTargets []xcodeproj.Target) { + fmt.Printf("Filtering %v application bundle targets", len(targets)) + + for _, target := range targets { + if !target.IsExecutableProduct() { + continue + } + + // App store exports contain App Clip too. App Clip provisioning profile has to be included in export options: + // .. + // provisioningProfiles + // + // io.bundle.id + // Development Application Profile + // io.bundle.id.AppClipID + // Development App Clip Profile + // + // .., + if exportMethod != exportoptions.MethodAppStore && target.IsAppClipProduct() { + continue + } + + filteredTargets = append(filteredTargets, target) + } + + fmt.Printf("Found %v application bundle targets", len(filteredTargets)) + + return +} From e3a520b669336a684e03e74e8ceec4f8f971b8b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Wed, 9 Oct 2024 11:09:09 +0200 Subject: [PATCH 2/6] Update go-xcode@v1 --- .../exportoptionsgenerator.go | 38 +++++++++---------- .../exportoptionsgenerator_test.go | 6 +-- go.mod | 2 +- go.sum | 4 ++ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/exportoptionsgenerator/exportoptionsgenerator.go b/exportoptionsgenerator/exportoptionsgenerator.go index e82b67a2..98eeec6b 100644 --- a/exportoptionsgenerator/exportoptionsgenerator.go +++ b/exportoptionsgenerator/exportoptionsgenerator.go @@ -2,6 +2,8 @@ package exportoptionsgenerator import ( "fmt" + "os" + "github.com/bitrise-io/go-utils/sliceutil" "github.com/bitrise-io/go-utils/v2/log" "github.com/bitrise-io/go-xcode/export" @@ -11,20 +13,12 @@ import ( "github.com/bitrise-io/go-xcode/xcodeproject/serialized" "github.com/bitrise-io/go-xcode/xcodeproject/xcodeproj" "github.com/bitrise-io/go-xcode/xcodeproject/xcscheme" - "os" ) const ( AppClipProductType = "com.apple.product-type.application.on-demand-install-capable" ) -type SigningStyle string - -const ( - ManualSigningStyle = "manual" - AutomaticSigningStyle = "automatic" -) - // ExportOptionsGenerator generates an exportOptions.plist file. type ExportOptionsGenerator struct { xcodeProj *xcodeproj.XcodeProj @@ -59,7 +53,7 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions( uploadBitcode bool, compileBitcode bool, archivedWithXcodeManagedProfiles bool, - codeSigningStyle SigningStyle, + codeSigningStyle exportoptions.SigningStyle, xcodeMajorVersion int64, ) (exportoptions.ExportOptions, error) { mainTargetBundleID, entitlementsByBundleID, err := g.applicationTargetsAndEntitlements(exportMethod) @@ -73,9 +67,11 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions( } exportOpts := generateBaseExportOptions(exportMethod, uploadBitcode, compileBitcode, iCloudContainerEnvironment) + if xcodeMajorVersion >= 12 { exportOpts = addDistributionBundleIdentifierFromXcode12(exportOpts, mainTargetBundleID) } + if xcodeMajorVersion >= 13 { exportOpts = disableManagedBuildNumberFromXcode13(exportOpts) } @@ -85,7 +81,7 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions( exportOpts = addDestinationExport(exportOpts) } - if codeSigningStyle == AutomaticSigningStyle { + if codeSigningStyle == exportoptions.SigningStyleAutomatic { exportOpts = addTeamID(exportOpts, teamID) } else { codeSignGroup, err := g.determineCodesignGroup(entitlementsByBundleID, exportMethod, teamID, archivedWithXcodeManagedProfiles) @@ -158,7 +154,7 @@ func (g ExportOptionsGenerator) determineCodesignGroup(bundleIDEntitlementsMap m certs, err := g.certificateProvider.ListCodesignIdentities() if err != nil { - return nil, fmt.Errorf("Failed to get installed certificates, error: %s", err) + return nil, fmt.Errorf("failed to get installed certificates: %w", err) } g.logger.Debugf("Installed certificates:") @@ -168,7 +164,7 @@ func (g ExportOptionsGenerator) determineCodesignGroup(bundleIDEntitlementsMap m profs, err := g.profileProvider.ListProvisioningProfiles() if err != nil { - return nil, fmt.Errorf("Failed to get installed provisioning profiles, error: %s", err) + return nil, fmt.Errorf("failed to get installed provisioning profiles: %w", err) } g.logger.Debugf("Installed profiles:") @@ -332,7 +328,7 @@ func projectUsesCloudKit(bundleIDEntitlementsMap map[string]plistutil.PlistData) return false } -// generateBaseExportOptions creates a default exportOptions introudced in Xcode 7. +// generateBaseExportOptions creates a default exportOptions introduced in Xcode 7. func generateBaseExportOptions(exportMethod exportoptions.Method, cfgUploadBitcode, cfgCompileBitcode bool, iCloudContainerEnvironment string) exportoptions.ExportOptions { if exportMethod == exportoptions.MethodAppStore { appStoreOptions := exportoptions.NewAppStoreOptions() @@ -377,13 +373,13 @@ func disableManagedBuildNumberFromXcode13(exportOpts exportoptions.ExportOptions return exportOpts } -func addSigningStyle(exportOpts exportoptions.ExportOptions, signingStyle SigningStyle) exportoptions.ExportOptions { +func addSigningStyle(exportOpts exportoptions.ExportOptions, signingStyle exportoptions.SigningStyle) exportoptions.ExportOptions { switch options := exportOpts.(type) { case exportoptions.AppStoreOptionsModel: - options.SigningStyle = string(signingStyle) + options.SigningStyle = signingStyle return options case exportoptions.NonAppStoreOptionsModel: - options.SigningStyle = string(signingStyle) + options.SigningStyle = signingStyle return options } return exportOpts @@ -427,14 +423,14 @@ func addManualSigningFields(exportOpts exportoptions.ExportOptions, codeSignGrou } exportCodeSignStyle = "automatic" } else { - if exportCodeSignStyle != "" && exportCodeSignStyle != ManualSigningStyle { + if exportCodeSignStyle != "" && exportCodeSignStyle != string(exportoptions.SigningStyleManual) { logger.Errorf("Both Xcode managed and NON Xcode managed profiles in code signing group") } - exportCodeSignStyle = ManualSigningStyle + exportCodeSignStyle = string(exportoptions.SigningStyleManual) } } - shouldSetManualSigning := archivedWithXcodeManagedProfiles && exportCodeSignStyle == ManualSigningStyle + shouldSetManualSigning := archivedWithXcodeManagedProfiles && exportCodeSignStyle == string(exportoptions.SigningStyleManual) if shouldSetManualSigning { logger.Warnf("App was signed with Xcode managed profile when archiving,") logger.Warnf("ipa export uses manual code signing.") @@ -450,7 +446,7 @@ func addManualSigningFields(exportOpts exportoptions.ExportOptions, codeSignGrou options.TeamID = codeSignGroup.Certificate().TeamID if shouldSetManualSigning { - options.SigningStyle = ManualSigningStyle + options.SigningStyle = exportoptions.SigningStyleManual } exportOpts = options case exportoptions.NonAppStoreOptionsModel: @@ -459,7 +455,7 @@ func addManualSigningFields(exportOpts exportoptions.ExportOptions, codeSignGrou options.TeamID = codeSignGroup.Certificate().TeamID if shouldSetManualSigning { - options.SigningStyle = ManualSigningStyle + options.SigningStyle = exportoptions.SigningStyleManual } exportOpts = options } diff --git a/exportoptionsgenerator/exportoptionsgenerator_test.go b/exportoptionsgenerator/exportoptionsgenerator_test.go index 356c55da..08280cbf 100644 --- a/exportoptionsgenerator/exportoptionsgenerator_test.go +++ b/exportoptionsgenerator/exportoptionsgenerator_test.go @@ -282,7 +282,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_ForAutomaticSig for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Act - gotOpts, err := tt.generatorFactory().GenerateApplicationExportOptions(tt.exportMethod, tt.containerEnvironment, teamID, true, true, false, AutomaticSigningStyle, tt.xcodeVersion) + gotOpts, err := tt.generatorFactory().GenerateApplicationExportOptions(tt.exportMethod, tt.containerEnvironment, teamID, true, true, false, exportoptions.SigningStyleAutomatic, tt.xcodeVersion) // Assert require.NoError(t, err) @@ -384,7 +384,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions(t *testing.T) { } // Act - gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, ManualSigningStyle, tt.xcodeVersion) + gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, exportoptions.SigningStyleManual, tt.xcodeVersion) // Assert require.NoError(t, err) @@ -454,7 +454,7 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_WhenNoProfileFo } // Act - gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, ManualSigningStyle, tt.xcodeVersion) + gotOpts, err := g.GenerateApplicationExportOptions(tt.exportMethod, "Production", teamID, true, true, false, exportoptions.SigningStyleManual, tt.xcodeVersion) // Assert require.NoError(t, err) diff --git a/go.mod b/go.mod index 29ffc8fb..1e3088d5 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/bitrise-io/go-steputils/v2 v2.0.0-alpha.18 github.com/bitrise-io/go-utils v1.0.12 github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23 - github.com/bitrise-io/go-xcode v1.0.18 + github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-querystring v1.1.0 github.com/hashicorp/go-retryablehttp v0.7.7 diff --git a/go.sum b/go.sum index aeb45fbd..d21980cf 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,10 @@ github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23 h1:Dfh4nyZPuEtilBisidejqxBrkx9 github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23/go.mod h1:3XUplo0dOWc3DqT2XA2SeHToDSg7+j1y1HTHibT2H68= github.com/bitrise-io/go-xcode v1.0.18 h1:guFywV/AwcZuexqIQkL1ixc3QThpbJvA4voa9MqvPto= github.com/bitrise-io/go-xcode v1.0.18/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= +github.com/bitrise-io/go-xcode v1.1.0 h1:34JKUMnTuBYtgORcGTOoGkXNzw0fFrTVjQG7QnHQHeM= +github.com/bitrise-io/go-xcode v1.1.0/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= +github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91 h1:v87soQjWZiV4DFEX04WbwcecsFlvpYm5tdimFuCpQvA= +github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 5cfc177951b4c31930bffc6e40775decbaa1295d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Wed, 9 Oct 2024 13:09:30 +0200 Subject: [PATCH 3/6] Fix lint issue --- exportoptionsgenerator/exportoptionsgenerator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/exportoptionsgenerator/exportoptionsgenerator.go b/exportoptionsgenerator/exportoptionsgenerator.go index 98eeec6b..647ed721 100644 --- a/exportoptionsgenerator/exportoptionsgenerator.go +++ b/exportoptionsgenerator/exportoptionsgenerator.go @@ -16,6 +16,7 @@ import ( ) const ( + // AppClipProductType ... AppClipProductType = "com.apple.product-type.application.on-demand-install-capable" ) From f83343a99d6c73f3da712e5d0be77a7c4d93bb62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Wed, 9 Oct 2024 15:42:35 +0200 Subject: [PATCH 4/6] Update go-xcode@v1 --- go.mod | 2 +- go.sum | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 1e3088d5..b00c5057 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/bitrise-io/go-steputils/v2 v2.0.0-alpha.18 github.com/bitrise-io/go-utils v1.0.12 github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23 - github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91 + github.com/bitrise-io/go-xcode v1.1.1 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-querystring v1.1.0 github.com/hashicorp/go-retryablehttp v0.7.7 diff --git a/go.sum b/go.sum index d21980cf..38f9a666 100644 --- a/go.sum +++ b/go.sum @@ -11,12 +11,8 @@ github.com/bitrise-io/go-utils v1.0.12 h1:iJV1ZpyvSA0NCte/N6x+aIQ9TrNr5sIBlcJBf0 github.com/bitrise-io/go-utils v1.0.12/go.mod h1:ZY1DI+fEpZuFpO9szgDeICM4QbqoWVt0RSY3tRI1heY= github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23 h1:Dfh4nyZPuEtilBisidejqxBrkx9cWvbOUrpq8VEION0= github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.23/go.mod h1:3XUplo0dOWc3DqT2XA2SeHToDSg7+j1y1HTHibT2H68= -github.com/bitrise-io/go-xcode v1.0.18 h1:guFywV/AwcZuexqIQkL1ixc3QThpbJvA4voa9MqvPto= -github.com/bitrise-io/go-xcode v1.0.18/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= -github.com/bitrise-io/go-xcode v1.1.0 h1:34JKUMnTuBYtgORcGTOoGkXNzw0fFrTVjQG7QnHQHeM= -github.com/bitrise-io/go-xcode v1.1.0/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= -github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91 h1:v87soQjWZiV4DFEX04WbwcecsFlvpYm5tdimFuCpQvA= -github.com/bitrise-io/go-xcode v1.1.1-0.20241009090606-5f960ab7be91/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= +github.com/bitrise-io/go-xcode v1.1.1 h1:Krfa8iYZZWdLBuH7AXbufFZwL+Pys7etqvd8+Ehdwt8= +github.com/bitrise-io/go-xcode v1.1.1/go.mod h1:9OwsvrhZ4A2JxHVoEY7CPcABAKA+OE7FQqFfBfvbFuY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From e2b23d5665a45a18c973ea5a7e37d4735014b816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Wed, 9 Oct 2024 16:15:22 +0200 Subject: [PATCH 5/6] Don't set default signingStyle and destination on exportOptions --- .../exportoptionsgenerator.go | 17 ----------------- .../exportoptionsgenerator_test.go | 12 ------------ 2 files changed, 29 deletions(-) diff --git a/exportoptionsgenerator/exportoptionsgenerator.go b/exportoptionsgenerator/exportoptionsgenerator.go index 647ed721..2bd1c426 100644 --- a/exportoptionsgenerator/exportoptionsgenerator.go +++ b/exportoptionsgenerator/exportoptionsgenerator.go @@ -77,11 +77,6 @@ func (g ExportOptionsGenerator) GenerateApplicationExportOptions( exportOpts = disableManagedBuildNumberFromXcode13(exportOpts) } - if xcodeMajorVersion >= 15 { - exportOpts = addSigningStyle(exportOpts, codeSigningStyle) - exportOpts = addDestinationExport(exportOpts) - } - if codeSigningStyle == exportoptions.SigningStyleAutomatic { exportOpts = addTeamID(exportOpts, teamID) } else { @@ -386,18 +381,6 @@ func addSigningStyle(exportOpts exportoptions.ExportOptions, signingStyle export return exportOpts } -func addDestinationExport(exportOpts exportoptions.ExportOptions) exportoptions.ExportOptions { - switch options := exportOpts.(type) { - case exportoptions.AppStoreOptionsModel: - options.Destination = exportoptions.DestinationExport - return options - case exportoptions.NonAppStoreOptionsModel: - options.Destination = exportoptions.DestinationExport - return options - } - return exportOpts -} - func addTeamID(exportOpts exportoptions.ExportOptions, teamID string) exportoptions.ExportOptions { switch options := exportOpts.(type) { case exportoptions.AppStoreOptionsModel: diff --git a/exportoptionsgenerator/exportoptionsgenerator_test.go b/exportoptionsgenerator/exportoptionsgenerator_test.go index 08280cbf..19914071 100644 --- a/exportoptionsgenerator/exportoptionsgenerator_test.go +++ b/exportoptionsgenerator/exportoptionsgenerator_test.go @@ -195,14 +195,10 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_ForAutomaticSig - destination - export distributionBundleIdentifier io.bundle.id method development - signingStyle - automatic teamID TEAM123 @@ -228,14 +224,10 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_ForAutomaticSig - destination - export manageAppVersionAndBuildNumber method app-store - signingStyle - automatic teamID TEAM123 @@ -263,16 +255,12 @@ func TestExportOptionsGenerator_GenerateApplicationExportOptions_ForAutomaticSig - destination - export distributionBundleIdentifier io.bundle.id iCloudContainerEnvironment Production method development - signingStyle - automatic teamID TEAM123 From 901c84ee34425c52d59dfc80fd83905618600bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krisztia=CC=81n=20Go=CC=88drei?= Date: Wed, 9 Oct 2024 16:33:52 +0200 Subject: [PATCH 6/6] Remove unused addSigningStyle --- exportoptionsgenerator/exportoptionsgenerator.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/exportoptionsgenerator/exportoptionsgenerator.go b/exportoptionsgenerator/exportoptionsgenerator.go index 2bd1c426..28d2c652 100644 --- a/exportoptionsgenerator/exportoptionsgenerator.go +++ b/exportoptionsgenerator/exportoptionsgenerator.go @@ -369,18 +369,6 @@ func disableManagedBuildNumberFromXcode13(exportOpts exportoptions.ExportOptions return exportOpts } -func addSigningStyle(exportOpts exportoptions.ExportOptions, signingStyle exportoptions.SigningStyle) exportoptions.ExportOptions { - switch options := exportOpts.(type) { - case exportoptions.AppStoreOptionsModel: - options.SigningStyle = signingStyle - return options - case exportoptions.NonAppStoreOptionsModel: - options.SigningStyle = signingStyle - return options - } - return exportOpts -} - func addTeamID(exportOpts exportoptions.ExportOptions, teamID string) exportoptions.ExportOptions { switch options := exportOpts.(type) { case exportoptions.AppStoreOptionsModel: