11package codesign
22
33import (
4+ "errors"
45 "fmt"
56 "time"
67
78 "github.com/bitrise-io/go-utils/v2/log"
89 "github.com/bitrise-io/go-xcode/certificateutil"
10+ "github.com/bitrise-io/go-xcode/exportoptions"
11+ "github.com/bitrise-io/go-xcode/plistutil"
12+ "github.com/bitrise-io/go-xcode/profileutil"
913 "github.com/bitrise-io/go-xcode/v2/autocodesign"
1014 "github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient"
1115 "github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient/appstoreconnect"
16+ "github.com/bitrise-io/go-xcode/v2/autocodesign/localcodesignasset"
1217 "github.com/bitrise-io/go-xcode/v2/autocodesign/projectmanager"
1318 "github.com/bitrise-io/go-xcode/v2/devportalservice"
19+ "github.com/bitrise-io/go-xcode/v2/exportoptionsgenerator"
1420 "github.com/bitrise-io/go-xcode/v2/xcarchive"
1521)
1622
@@ -58,6 +64,7 @@ type Manager struct {
5864 fallbackProfileDownloader autocodesign.ProfileProvider
5965 assetInstaller autocodesign.AssetWriter
6066 localCodeSignAssetManager autocodesign.LocalCodeSignAssetManager
67+ profileConverter localcodesignasset.ProvisioningProfileConverter
6168
6269 detailsProvider DetailsProvider
6370 assetWriter AssetWriter
@@ -75,6 +82,7 @@ func NewManagerWithArchive(
7582 fallbackProfileDownloader autocodesign.ProfileProvider ,
7683 assetInstaller autocodesign.AssetWriter ,
7784 localCodeSignAssetManager autocodesign.LocalCodeSignAssetManager ,
85+ profileConverter localcodesignasset.ProvisioningProfileConverter ,
7886 archive xcarchive.IosArchive ,
7987 logger log.Logger ,
8088) Manager {
@@ -87,6 +95,7 @@ func NewManagerWithArchive(
8795 fallbackProfileDownloader : fallbackProfileDownloader ,
8896 assetInstaller : assetInstaller ,
8997 localCodeSignAssetManager : localCodeSignAssetManager ,
98+ profileConverter : profileConverter ,
9099 detailsProvider : archive ,
91100 logger : logger ,
92101 }
@@ -102,6 +111,7 @@ func NewManagerWithProject(
102111 fallbackProfileDownloader autocodesign.ProfileProvider ,
103112 assetInstaller autocodesign.AssetWriter ,
104113 localCodeSignAssetManager autocodesign.LocalCodeSignAssetManager ,
114+ profileConverter localcodesignasset.ProvisioningProfileConverter ,
105115 project projectmanager.Project ,
106116 logger log.Logger ,
107117) Manager {
@@ -114,6 +124,7 @@ func NewManagerWithProject(
114124 fallbackProfileDownloader : fallbackProfileDownloader ,
115125 assetInstaller : assetInstaller ,
116126 localCodeSignAssetManager : localCodeSignAssetManager ,
127+ profileConverter : profileConverter ,
117128 detailsProvider : project ,
118129 assetWriter : project ,
119130 logger : logger ,
@@ -389,18 +400,23 @@ func (m *Manager) prepareCodeSigningWithBitrise(credentials devportalservice.Cre
389400 testDevicesToRegister = testDevices
390401 }
391402
392- codesignAssetsByDistributionType , err := m .prepareAutomaticAssets (credentials , appLayout , typeToLocalCerts , testDevicesToRegister )
393- if err != nil {
403+ codesignAssetsByDistributionType , autoCodesignErr := m .prepareAutomaticAssets (credentials , appLayout , typeToLocalCerts , testDevicesToRegister )
404+ if autoCodesignErr != nil {
394405 if ! m .fallbackProfileDownloader .IsAvailable () {
395- return err
406+ return autoCodesignErr
396407 }
397408
398409 m .logger .Println ()
399- m .logger .Warnf ("Automatic code signing failed: %s" , err )
410+ m .logger .Warnf ("Automatic code signing failed: %s" , autoCodesignErr )
400411 m .logger .Println ()
401412 m .logger .Infof ("Falling back to manually managed codesigning assets." )
402413
403- return m .prepareManualAssets (certs )
414+ codesignAssetsByDistributionType , err = m .prepareManualAssets (appLayout , typeToLocalCerts )
415+ if err != nil {
416+ m .logger .Println ()
417+ m .logger .Warnf ("Manual code signing failed: %s" , err )
418+ return autoCodesignErr
419+ }
404420 }
405421
406422 if m .assetWriter != nil {
@@ -438,24 +454,100 @@ func (m *Manager) prepareAutomaticAssets(credentials devportalservice.Credential
438454 return codesignAssets , nil
439455}
440456
441- func (m * Manager ) prepareManualAssets (certificates []certificateutil.CertificateInfoModel ) error {
442- if err := m .installCertificates (certificates ); err != nil {
443- return err
457+ func (m * Manager ) prepareManualAssets (appLayout autocodesign.AppLayout , typeToLocalCerts autocodesign.LocalCertificates ) (map [autocodesign.DistributionType ]autocodesign.AppCodesignAssets , error ) {
458+ var certificates []certificateutil.CertificateInfoModel
459+ for _ , certs := range typeToLocalCerts {
460+ certificates = append (certificates , certs ... )
461+ }
462+
463+ installedCerts , installedProfiles , err := m .installManualCodeSigningAssets (certificates )
464+ if err != nil {
465+ return nil , fmt .Errorf ("failed to install manual code signing assets: %w" , err )
466+ }
467+
468+ assets , err := m .createCodeSignAssetMap (appLayout , installedCerts , installedProfiles )
469+ if err != nil {
470+ return nil , fmt .Errorf ("failed to create code signing asset map: %w" , err )
471+ }
472+
473+ return assets , nil
474+ }
475+
476+ func (m * Manager ) createCodeSignAssetMap (appLayout autocodesign.AppLayout , certificates []certificateutil.CertificateInfoModel , profiles []profileutil.ProvisioningProfileInfoModel ) (map [autocodesign.DistributionType ]autocodesign.AppCodesignAssets , error ) {
477+ provider := exportoptionsgenerator .NewCodeSignGroupProvider (m .logger )
478+
479+ bundleIDEntitlementsMap := map [string ]plistutil.PlistData {}
480+ for bundleID , entitlements := range appLayout .EntitlementsByArchivableTargetBundleID {
481+ bundleIDEntitlementsMap [bundleID ] = plistutil .PlistData (entitlements )
482+ }
483+
484+ distributionTypes := []autocodesign.DistributionType {m .opts .ExportMethod }
485+ if m .opts .ExportMethod != autocodesign .Development {
486+ // Add development distribution type if the selected export method is not development
487+ distributionTypes = append (distributionTypes , autocodesign .Development )
488+ }
489+
490+ assetsByDistributionType := map [autocodesign.DistributionType ]autocodesign.AppCodesignAssets {}
491+ for _ , distributionType := range distributionTypes {
492+ signingAssets , err := provider .DetermineCodesignGroup (certificates , profiles , nil , bundleIDEntitlementsMap , exportoptions .Method (distributionType ), m .opts .TeamID , true )
493+ if err != nil || signingAssets == nil {
494+ if err == nil {
495+ err = errors .New ("no signing assets found" )
496+ }
497+ if distributionType == m .opts .ExportMethod {
498+ return nil , fmt .Errorf ("failed to determine codesign group for %s distribution: %w" , distributionType , err )
499+ }
500+ m .logger .Warnf ("Failed to determine codesign group for %s distribution: %s, skipping" , distributionType , err )
501+ continue
502+ }
503+
504+ bundleIDProfileInfoMap := signingAssets .BundleIDProfileMap ()
505+ bundleIDProfileMap := map [string ]autocodesign.Profile {}
506+ for bundleID , profileInfo := range bundleIDProfileInfoMap {
507+ signingProfile , err := m .profileConverter .ProfileInfoToProfile (profileInfo )
508+ if err != nil {
509+ return nil , fmt .Errorf ("failed to convert profile info: %w" , err )
510+ }
511+ bundleIDProfileMap [bundleID ] = signingProfile
512+ }
513+
514+ assetsByDistributionType [distributionType ] = autocodesign.AppCodesignAssets {
515+ Certificate : signingAssets .Certificate (),
516+ ArchivableTargetProfilesByBundleID : bundleIDProfileMap ,
517+ }
518+ }
519+
520+ // TODO: UI test targets are not supported yet
521+
522+ return assetsByDistributionType , nil
523+
524+ }
525+
526+ func (m * Manager ) installManualCodeSigningAssets (certificates []certificateutil.CertificateInfoModel ) ([]certificateutil.CertificateInfoModel , []profileutil.ProvisioningProfileInfoModel , error ) {
527+ m .logger .Printf ("Installing %d certificate(s):" , len (certificates ))
528+ for _ , cert := range certificates {
529+ m .logger .Printf ("- %s" , cert .String ())
530+ // Empty passphrase provided, as already parsed certificate + private key
531+ if err := m .assetInstaller .InstallCertificate (cert ); err != nil {
532+ return nil , nil , err
533+ }
444534 }
445535
446536 profiles , err := m .fallbackProfileDownloader .GetProfiles ()
447537 if err != nil {
448- return fmt .Errorf ("failed to fetch profiles: %w" , err )
538+ return certificates , nil , fmt .Errorf ("failed to fetch profiles: %w" , err )
449539 }
450540
451- m .logger .Printf ("Installing manual profiles:" )
541+ m .logger .Printf ("Installing %d profile(s)..." , len (profiles ))
542+ var installedProfiles []profileutil.ProvisioningProfileInfoModel
452543 for _ , profile := range profiles {
453- m .logger .Printf ("%s" , profile .Info .String (certificates ... ))
454-
544+ m .logger .Printf ("- UUID: %s, Name: %s, Export type: %s, Team: %s, Expiry: %s" , profile .Info .UUID , profile .Info .Name , profile .Info .ExportType , profile .Info .TeamID , profile .Info .ExpirationDate )
455545 if err := m .assetInstaller .InstallProfile (profile .Profile ); err != nil {
456- return fmt .Errorf ("failed to install profile: %w" , err )
546+ return certificates , installedProfiles , fmt .Errorf ("failed to install profile: %w" , err )
457547 }
548+
549+ installedProfiles = append (installedProfiles , profile .Info )
458550 }
459551
460- return nil
552+ return certificates , installedProfiles , nil
461553}
0 commit comments