@@ -68,83 +68,123 @@ func printCodesignGroup(group export.IosCodeSignGroup) {
6868func collectIpaExportCertificate (archiveCertificate certificateutil.CertificateInfoModel , installedCertificates []certificateutil.CertificateInfoModel ) (certificateutil.CertificateInfoModel , error ) {
6969 fmt .Println ()
7070 fmt .Println ()
71- question := fmt .Sprintf (`The archive used codesigning files of team: %s - %s
72- Would you like to use this team to sign your project?` , archiveCertificate .TeamID , archiveCertificate .TeamName )
73- useArchiveTeam , err := goinp .AskForBoolWithDefault (question , true )
74- if err != nil {
75- return certificateutil.CertificateInfoModel {}, fmt .Errorf ("failed to read input: %s" , err )
76- }
7771
78- selectedTeam := ""
79- certificatesByTeam := mapCertificatesByTeam (installedCertificates )
72+ selectedCertificate := certificateutil.CertificateInfoModel {}
8073
81- if ! useArchiveTeam {
82- teams := []string {}
83- for team := range certificatesByTeam {
84- teams = append (teams , team )
85- }
74+ // Asking the user over and over until we find a valid certificate for the selected export method.
75+ for searchingValidCertificate := true ; searchingValidCertificate ; {
8676
87- fmt .Println ()
88- selectedTeam , err = goinp .SelectFromStringsWithDefault ("Select the Development team to sign your project" , 1 , teams )
77+ // Export method
78+ exportMethods := []string {"development" , "app-store" , "ad-hoc" , "enterprise" }
79+
80+ selectedExportMethod , err := goinp .SelectFromStringsWithDefault ("Select the ipa export method" , 1 , exportMethods )
8981 if err != nil {
9082 return certificateutil.CertificateInfoModel {}, fmt .Errorf ("failed to read input: %s" , err )
9183 }
92- } else {
93- selectedTeam = fmt .Sprintf ("%s - %s" , archiveCertificate .TeamID , archiveCertificate .TeamName )
94- }
84+ log .Debugf ("selected export method: %v" , selectedExportMethod )
9585
96- selectedCertificate := certificateutil.CertificateInfoModel {}
86+ // Export method needs Development or Distribution certificate?
87+ exportDistCert := true
88+ if selectedExportMethod == "development" {
89+ exportDistCert = false
90+ }
9791
98- if isDistributionCertificate (archiveCertificate ) {
99- certificates := certificatesByTeam [selectedTeam ]
100- developmentCertificates := certificateutil .FilterCertificateInfoModelsByFilterFunc (certificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
101- return ! isDistributionCertificate (certInfo )
102- })
92+ selectedTeam := ""
93+ log .Debugf ("InstalledCerts: %v\n " , installedCertificates )
10394
104- certificateOptions := []string {}
105- for _ , certInfo := range developmentCertificates {
106- certificateOption := fmt .Sprintf ("%s [%s]" , certInfo .CommonName , certInfo .Serial )
107- certificateOptions = append (certificateOptions , certificateOption )
95+ // Filter the installed certificates by distribution type
96+ var certsForSelectedExport []certificateutil.CertificateInfoModel
97+ if exportDistCert {
98+ certsForSelectedExport = certificateutil .FilterCertificateInfoModelsByFilterFunc (installedCertificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
99+ return isDistributionCertificate (certInfo )
100+ })
101+ log .Debugf ("Distribution certificated: %v\n " , certsForSelectedExport )
102+ } else {
103+ certsForSelectedExport = certificateutil .FilterCertificateInfoModelsByFilterFunc (installedCertificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
104+ return ! isDistributionCertificate (certInfo )
105+ })
106+ log .Debugf ("Developer certificated: %v\n " , certsForSelectedExport )
108107 }
109108
110- fmt . Println ( )
111- question := fmt . Sprintf ( `The Xcode archive used distribution certificate : %s [%s].
112- Please select a development certificate:` , archiveCertificate . CommonName , archiveCertificate . Serial )
113- selectedCertificateOption , err := goinp . SelectFromStringsWithDefault ( question , 1 , certificateOptions )
114- if err != nil {
115- return certificateutil. CertificateInfoModel {}, fmt . Errorf ( "failed to read input: %s" , err )
109+ filteredCertificatesByTeam := mapCertificatesByTeam ( certsForSelectedExport )
110+ log . Debugf ( "Filtered certificates (by distribution type) by team : %v \n " , filteredCertificatesByTeam )
111+
112+ if len ( filteredCertificatesByTeam ) == 0 {
113+ log . Warnf ( "🚨 We couldn't find any certificate for the %s export method." , selectedExportMethod )
114+ continue
116115 }
117116
118- for _ , certInfo := range developmentCertificates {
119- certificateOption := fmt .Sprintf ("%s [%s]" , certInfo .CommonName , certInfo .Serial )
120- if certificateOption == selectedCertificateOption {
121- selectedCertificate = certInfo
117+ useArchiveTeam := true
118+ _ , contains := filteredCertificatesByTeam [fmt .Sprintf ("%s - %s" , archiveCertificate .TeamID , archiveCertificate .TeamName )]
119+
120+ // Ask the question if there is multiple valid team and the archiving team is one of them.
121+ // Skip it if only 1 team has certificates on the machine. Or the archiving team does'n have the desired certificate type.
122+ // Skip the question + set the useArchiveTeam = false, if multiple team has certificate for the export method but the archiving team is not one of them.
123+ if len (filteredCertificatesByTeam ) > 1 && contains {
124+ question := fmt .Sprintf (`The archive used codesigning files of team: %s - %s
125+ Would you like to use this team to export an ipa file?` , archiveCertificate .TeamID , archiveCertificate .TeamName )
126+ useArchiveTeam , err = goinp .AskForBoolWithDefault (question , true )
127+ if err != nil {
128+ return certificateutil.CertificateInfoModel {}, fmt .Errorf ("failed to read input: %s" , err )
122129 }
130+ // If multiple team has certificate for the export method but the archiving team is not one of them.
131+ } else if ! contains {
132+ archiveTeam := fmt .Sprintf ("%s - %s" , archiveCertificate .TeamName , archiveCertificate .TeamID )
133+
134+ fmt .Println ()
135+ log .Warnf ("🚨 The archiving team (%s) doesn't have certificate for the %s export method" , archiveTeam , selectedExportMethod )
136+ useArchiveTeam = false
137+ } else {
138+ archiveTeam := fmt .Sprintf ("%s - %s" , archiveCertificate .TeamName , archiveCertificate .TeamID )
139+
140+ fmt .Println ()
141+ log .Printf ("Only the archiving team (%s) has certificate for the %s export method" , archiveTeam , selectedExportMethod )
142+ }
143+
144+ // Use different team for export than archive.
145+ if ! useArchiveTeam {
146+ teams := []string {}
147+ for team := range filteredCertificatesByTeam {
148+ if hasCertificateForDistType (exportDistCert , filteredCertificatesByTeam [team ]) {
149+ teams = append (teams , team )
150+ }
151+ }
152+
153+ fmt .Println ()
154+ selectedTeam , err = goinp .SelectFromStringsWithDefault ("Select the Development team to export your app" , 1 , teams )
155+ if err != nil {
156+ return certificateutil.CertificateInfoModel {}, fmt .Errorf ("failed to read input: %s" , err )
157+ }
158+ } else {
159+ selectedTeam = fmt .Sprintf ("%s - %s" , archiveCertificate .TeamID , archiveCertificate .TeamName )
123160 }
124- } else {
125- certificates := certificatesByTeam [selectedTeam ]
126- distributionCertificates := certificateutil .FilterCertificateInfoModelsByFilterFunc (certificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
127- return isDistributionCertificate (certInfo )
128- })
129161
162+ // Find the specific development certificate.
163+ filteredTeamCertificates := filteredCertificatesByTeam [selectedTeam ]
130164 certificateOptions := []string {}
131- for _ , certInfo := range distributionCertificates {
165+
166+ for _ , certInfo := range filteredTeamCertificates {
132167 certificateOption := fmt .Sprintf ("%s [%s]" , certInfo .CommonName , certInfo .Serial )
133168 certificateOptions = append (certificateOptions , certificateOption )
134169 }
135170
171+ certType := "distribution"
172+ if ! exportDistCert {
173+ certType = "development"
174+ }
175+
136176 fmt .Println ()
137- question := fmt .Sprintf (`The Xcode archive used development certificate: %s [%s].
138- Please select a distribution certificate:` , archiveCertificate .CommonName , archiveCertificate .Serial )
177+ question := fmt .Sprintf ("Please select a %s certificate:" , certType )
139178 selectedCertificateOption , err := goinp .SelectFromStringsWithDefault (question , 1 , certificateOptions )
140179 if err != nil {
141180 return certificateutil.CertificateInfoModel {}, fmt .Errorf ("failed to read input: %s" , err )
142181 }
143182
144- for _ , certInfo := range distributionCertificates {
183+ for _ , certInfo := range filteredTeamCertificates {
145184 certificateOption := fmt .Sprintf ("%s [%s]" , certInfo .CommonName , certInfo .Serial )
146185 if certificateOption == selectedCertificateOption {
147186 selectedCertificate = certInfo
187+ searchingValidCertificate = false
148188 }
149189 }
150190 }
@@ -367,3 +407,20 @@ func collectIpaExportSelectableCodeSignGroups(archive xcarchive.IosArchive, inst
367407
368408 return codeSignGroups
369409}
410+
411+ // hasCertificateForDistType returns true if the provided certificate list has certificate for the selected cert type.
412+ // If isDistCert == true it will search for Distribution Certificates. If it's == false it will search for Developmenttion Certificates.
413+ // If the team doesn't have any certificate for the selected cert type, it will return false.
414+ func hasCertificateForDistType (isDistCert bool , certificates []certificateutil.CertificateInfoModel ) bool {
415+ if ! isDistCert {
416+ developmentCertificates := certificateutil .FilterCertificateInfoModelsByFilterFunc (certificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
417+ return ! isDistributionCertificate (certInfo )
418+ })
419+ return len (developmentCertificates ) > 0
420+ }
421+
422+ distributionCertificates := certificateutil .FilterCertificateInfoModelsByFilterFunc (certificates , func (certInfo certificateutil.CertificateInfoModel ) bool {
423+ return isDistributionCertificate (certInfo )
424+ })
425+ return len (distributionCertificates ) > 0
426+ }
0 commit comments