diff --git a/go.mod b/go.mod index 1c40574..d7eac5d 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/bitrise-io/go-utils v1.0.2 github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.11 github.com/bitrise-io/go-xcode v1.0.9 - github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.20 + github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.25 howett.net/plist v1.0.0 ) diff --git a/go.sum b/go.sum index ef17078..3cea4ad 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.11 h1:IacLMHL7hhgVcqtx15Bysq738P8 github.com/bitrise-io/go-utils/v2 v2.0.0-alpha.11/go.mod h1:SJqGxzwjIAx2LVQxNGS4taN7X//eDPJLrFxJ1MpOuyA= github.com/bitrise-io/go-xcode v1.0.9 h1:+sbqOYidQ+aiFfCTDpf2LdGSQEM5RfbtDsiG27zJG+s= github.com/bitrise-io/go-xcode v1.0.9/go.mod h1:Y0Wu2dXm0MilJ/4D3+gPHaNMlUcP+1DjIPoLPykq7wY= -github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.20 h1:MIH3eGNcAsc5VBACiU+EFcmUfqCyT6/fMSi2UjYR9+s= -github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.20/go.mod h1:8WBcRgrVXY8tzR7NcjE4fw6WguOIfB3YcC7ZTcQYUEY= +github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.25 h1:h01Qp6Mw3LiPg7A7g4pf5F5LcejrY/i9rL7PkBnlOBs= +github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.25/go.mod h1:8WBcRgrVXY8tzR7NcjE4fw6WguOIfB3YcC7ZTcQYUEY= github.com/bitrise-io/pkcs12 v0.0.0-20211108084543-e52728e011c8 h1:kmvU8AxrNTxXsVPKepBHD8W+eCVmeaKyTkRuUJB2K38= github.com/bitrise-io/pkcs12 v0.0.0-20211108084543-e52728e011c8/go.mod h1:UiXKNs0essbC14a2TvGlnUKo9isP9m4guPrp8KJHJpU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/certdownloader/certdownloader.go b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/certdownloader/certdownloader.go index 7c67cf8..fe5a988 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/certdownloader/certdownloader.go +++ b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/certdownloader/certdownloader.go @@ -32,6 +32,7 @@ func NewDownloader(certs []CertificateAndPassphrase, client *http.Client) autoco } } +// GetCertificates ... func (d downloader) GetCertificates() ([]certificateutil.CertificateInfoModel, error) { var certInfos []certificateutil.CertificateInfoModel diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient/spaceship/spaceship/Gemfile.lock b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient/spaceship/spaceship/Gemfile.lock index f7ce354..e483615 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient/spaceship/spaceship/Gemfile.lock +++ b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/devportalclient/spaceship/spaceship/Gemfile.lock @@ -1,29 +1,30 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + CFPropertyList (3.0.6) + rexml + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.500.0) - aws-sdk-core (3.121.0) + aws-partitions (1.716.0) + aws-sdk-core (3.170.0) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.239.0) - aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.48.0) - aws-sdk-core (~> 3, >= 3.120.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.62.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.102.0) - aws-sdk-core (~> 3, >= 3.120.0) + aws-sdk-s3 (1.119.1) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.4.0) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) - claide (1.0.3) + claide (1.1.0) colored (1.2) colored2 (3.1.2) commander (4.6.0) @@ -33,19 +34,20 @@ GEM rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) - emoji_regex (3.2.2) - excon (0.85.0) - faraday (1.7.1) + dotenv (2.8.1) + emoji_regex (3.2.3) + excon (0.99.0) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.1) + faraday-net_http_persistent (~> 1.0) faraday-patron (~> 1.0) faraday-rack (~> 1.0) - multipart-post (>= 1.2, < 3) + faraday-retry (~> 1.0) ruby2_keywords (>= 0.0.4) faraday-cookie_jar (0.0.7) faraday (>= 0.8.0) @@ -54,14 +56,17 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) - faraday_middleware (1.1.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.5) - fastlane (2.193.1) + fastimage (2.2.6) + fastlane (2.212.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -101,9 +106,9 @@ GEM xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.11.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-core (0.4.1) + google-apis-androidpublisher_v3 (0.34.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -112,53 +117,53 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.7.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-playcustomapp_v1 (0.5.0) - google-apis-core (>= 0.4, < 2.a) - google-apis-storage_v1 (0.6.0) - google-apis-core (>= 0.4, < 2.a) + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-playcustomapp_v1 (0.13.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-env (1.5.0) - faraday (>= 0.17.3, < 2.0) - google-cloud-errors (1.1.0) - google-cloud-storage (1.34.1) - addressable (~> 2.5) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + google-cloud-errors (1.3.0) + google-cloud-storage (1.44.0) + addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (0.17.1) - faraday (>= 0.17.3, < 2.0) + googleauth (1.3.0) + faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) - signet (~> 0.15) + signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.4) + http-cookie (1.0.5) domain_name (~> 0.5) httpclient (2.8.3) - jmespath (1.4.0) - json (2.5.1) - jwt (2.2.3) + jmespath (1.6.2) + json (2.6.3) + jwt (2.7.0) memoist (0.16.2) - mini_magick (4.11.0) - mini_mime (1.1.1) + mini_magick (4.12.0) + mini_mime (1.1.2) multi_json (1.15.0) multipart-post (2.0.0) nanaimo (0.3.0) naturally (2.2.1) optparse (0.1.1) - os (1.1.1) - plist (3.6.0) - public_suffix (4.0.6) + os (1.1.4) + plist (3.7.0) + public_suffix (5.0.1) rake (13.0.6) - representable (3.1.1) + representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) @@ -168,18 +173,18 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.16.0) + signet (0.17.0) addressable (~> 2.8) - faraday (>= 0.17.3, < 2.0) + faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) - simctl (1.6.8) + simctl (1.6.10) CFPropertyList naturally terminal-notifier (2.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - trailblazer-option (0.1.1) + trailblazer-option (0.1.2) tty-cursor (0.7.1) tty-screen (0.8.1) tty-spinner (0.9.3) @@ -187,11 +192,11 @@ GEM uber (0.1.0) unf (0.1.4) unf_ext - unf_ext (0.0.7.7) - unicode-display_width (1.7.0) - webrick (1.7.0) + unf_ext (0.0.8.2) + unicode-display_width (1.8.0) + webrick (1.8.1) word_wrap (1.0.0) - xcodeproj (1.21.0) + xcodeproj (1.22.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -204,6 +209,7 @@ GEM xcpretty (~> 0.2, >= 0.0.7) PLATFORMS + universal-darwin-22 x86_64-darwin-19 DEPENDENCIES diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/errors.go b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/errors.go index 3a95d80..5af3ef1 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/errors.go +++ b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/errors.go @@ -14,7 +14,7 @@ type DetailedError struct { Recommendation string } -func (e *DetailedError) Error() string { +func (e DetailedError) Error() string { message := "" if e.ErrorMessage != "" { message += e.ErrorMessage + "\n" diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/profiledownloader/profiledownloader.go b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/profiledownloader/profiledownloader.go index 819c7e2..3bb4210 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/profiledownloader/profiledownloader.go +++ b/vendor/github.com/bitrise-io/go-xcode/v2/autocodesign/profiledownloader/profiledownloader.go @@ -26,10 +26,12 @@ func New(profileURLs []string, client *http.Client) autocodesign.ProfileProvider } } +// IsAvailable returns true if there are available remote profiles to download func (d downloader) IsAvailable() bool { return len(d.urls) != 0 } +// GetProfiles downloads remote profiles and returns their contents func (d downloader) GetProfiles() ([]autocodesign.LocalProfile, error) { var profiles []autocodesign.LocalProfile diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/codesign/codesign.go b/vendor/github.com/bitrise-io/go-xcode/v2/codesign/codesign.go index 2519ae3..ec425a7 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/codesign/codesign.go +++ b/vendor/github.com/bitrise-io/go-xcode/v2/codesign/codesign.go @@ -209,8 +209,8 @@ func SelectConnectionCredentials( if authType == APIKeyAuth { if bitriseConnection == nil || bitriseConnection.APIKeyConnection == nil { - logger.Errorf(devportalclient.NotConnectedWarning) - return appleauth.Credentials{}, fmt.Errorf("API key authentication is selected in Step inputs, but Bitrise Apple Service connection is unset") + logger.Warnf(devportalclient.NotConnectedWarning) + return appleauth.Credentials{}, fmt.Errorf("Apple Service connection via App Store Connect API key is not estabilished") } logger.Donef("Using Apple Service connection with API key.") @@ -222,13 +222,13 @@ func SelectConnectionCredentials( if authType == AppleIDAuth { if bitriseConnection == nil || bitriseConnection.AppleIDConnection == nil { - logger.Errorf(devportalclient.NotConnectedWarning) - return appleauth.Credentials{}, fmt.Errorf("Apple ID authentication is selected in Step inputs, but Bitrise Apple Service connection is unset") + logger.Warnf(devportalclient.NotConnectedWarning) + return appleauth.Credentials{}, fmt.Errorf("Apple Service connection through Apple ID is not estabilished") } session, err := bitriseConnection.AppleIDConnection.FastlaneLoginSession() if err != nil { - return appleauth.Credentials{}, err + return appleauth.Credentials{}, fmt.Errorf("failed to restore Apple ID login session: %w", err) } logger.Donef("Using Apple Service connection with Apple ID.") @@ -400,7 +400,7 @@ func (m *Manager) prepareCodeSigningWithBitrise(credentials appleauth.Credential } m.logger.Println() - m.logger.Errorf("Automatic code signing failed: %s", err) + m.logger.Warnf("Automatic code signing failed: %s", err) m.logger.Println() m.logger.Infof("Falling back to manually managed codesigning assets.") diff --git a/vendor/github.com/bitrise-io/go-xcode/v2/codesign/inputparse.go b/vendor/github.com/bitrise-io/go-xcode/v2/codesign/inputparse.go index e29be1e..eef0d44 100644 --- a/vendor/github.com/bitrise-io/go-xcode/v2/codesign/inputparse.go +++ b/vendor/github.com/bitrise-io/go-xcode/v2/codesign/inputparse.go @@ -52,19 +52,26 @@ type Config struct { // ParseConfig validates and parses step inputs related to code signing and returns with a Config func ParseConfig(input Input, cmdFactory command.Factory) (Config, error) { - certificatesAndPassphrases, err := parseCertificates(input) + certificatesAndPassphrases, err := parseCertificatesAndPassphrases(input.CertificateURLList, string(input.CertificatePassphraseList)) if err != nil { - return Config{}, fmt.Errorf("failed to parse certificate URL and passphrase inputs: %s", err) + return Config{}, err + } + + if strings.TrimSpace(input.KeychainPath) == "" { + return Config{}, fmt.Errorf("keychain path is not specified") + } + if strings.TrimSpace(string(input.KeychainPassword)) == "" { + return Config{}, fmt.Errorf("keychain password is not specified") } keychainWriter, err := keychain.New(input.KeychainPath, input.KeychainPassword, cmdFactory) if err != nil { - return Config{}, fmt.Errorf("failed to open keychain: %s", err) + return Config{}, fmt.Errorf("failed to open keychain: %w", err) } - fallbackProfiles, err := validateAndExpandProfilePaths(input.FallbackProvisioningProfiles) + fallbackProfiles, err := parseFallbackProvisioningProfiles(input.FallbackProvisioningProfiles) if err != nil { - return Config{}, fmt.Errorf("failed to parse provisioning profiles: %w", err) + return Config{}, err } return Config{ @@ -81,22 +88,22 @@ func parseConnectionOverrideConfig(keyPathOrURL stepconf.Secret, keyID, keyIssue if strings.HasPrefix(string(keyPathOrURL), "https://") { resp, err := retryhttp.NewClient(logger).Get(string(keyPathOrURL)) if err != nil { - return nil, fmt.Errorf("API key download error: %s", err) + return nil, fmt.Errorf("failed to download App Store Connect API key: %w", err) } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { - logger.Errorf(err.Error()) + logger.Warnf(err.Error()) } }(resp.Body) if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("API key HTTP response %d: %s", resp.StatusCode, resp.Body) + return nil, fmt.Errorf("downloading App Store Connect API key failed with exit status %d: %s", resp.StatusCode, resp.Body) } key, err = io.ReadAll(resp.Body) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to read App Store Connect API key download response: %w", err) } } else { trimmedPath := string(keyPathOrURL) @@ -106,9 +113,9 @@ func parseConnectionOverrideConfig(keyPathOrURL stepconf.Secret, keyID, keyIssue var err error key, err = os.ReadFile(trimmedPath) if errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("private key does not exist at %s", trimmedPath) + return nil, fmt.Errorf("App Store Connect API does not exist at %s", trimmedPath) } else if err != nil { - return nil, err + return nil, fmt.Errorf("failed to read App Store Connect API at %s: %w", trimmedPath, err) } } @@ -119,19 +126,13 @@ func parseConnectionOverrideConfig(keyPathOrURL stepconf.Secret, keyID, keyIssue }, nil } -// parseCertificates returns an array of p12 file URLs and passphrases -func parseCertificates(input Input) ([]certdownloader.CertificateAndPassphrase, error) { - if strings.TrimSpace(input.CertificateURLList) == "" { - return nil, fmt.Errorf("code signing certificate URL: required input is not present") - } - if strings.TrimSpace(input.KeychainPath) == "" { - return nil, fmt.Errorf("keychain path: required input is not present") - } - if strings.TrimSpace(string(input.KeychainPassword)) == "" { - return nil, fmt.Errorf("keychain password: required input is not present") +// parseCertificatesAndPassphrases returns an array of p12 file URLs and passphrases +func parseCertificatesAndPassphrases(certificateURLList, certificatePassphraseList string) ([]certdownloader.CertificateAndPassphrase, error) { + if strings.TrimSpace(certificateURLList) == "" { + return nil, fmt.Errorf("code signing certificate URL is not specified") } - pfxURLs, passphrases, err := validateCertificates(input.CertificateURLList, string(input.CertificatePassphraseList)) + pfxURLs, passphrases, err := splitCertificatesAndPassphrases(certificateURLList, string(certificatePassphraseList)) if err != nil { return nil, err } @@ -147,13 +148,13 @@ func parseCertificates(input Input) ([]certdownloader.CertificateAndPassphrase, return files, nil } -// validateCertificates validates if the number of certificate URLs matches those of passphrases -func validateCertificates(certURLList string, certPassphraseList string) ([]string, []string, error) { +// splitCertificatesAndPassphrases validates if the number of certificate URLs matches those of passphrases +func splitCertificatesAndPassphrases(certURLList string, certPassphraseList string) ([]string, []string, error) { pfxURLs := splitAndClean(certURLList, "|", true) passphrases := splitAndClean(certPassphraseList, "|", false) // allow empty items because passphrase can be empty if len(pfxURLs) != len(passphrases) { - return nil, nil, fmt.Errorf("certificate count (%d) and passphrase count (%d) should match", len(pfxURLs), len(passphrases)) + return nil, nil, fmt.Errorf("code signing certificate count (%d) and passphrase count (%d) should match", len(pfxURLs), len(passphrases)) } return pfxURLs, passphrases, nil @@ -164,12 +165,12 @@ func splitAndClean(list string, sep string, omitEmpty bool) (items []string) { return sliceutil.CleanWhitespace(strings.Split(list, sep), omitEmpty) } -// validateAndExpandProfilePaths validates and expands profilesList. +// parseFallbackProvisioningProfiles validates and expands profilesList. // profilesList must be a list of paths separated either by `|` or `\n`. // List items must be a remote (https://) or local (file://) file paths, // or a local directory (with no scheme). // For directory list items, the contained profiles' path will be returned. -func validateAndExpandProfilePaths(profilesList string) ([]string, error) { +func parseFallbackProvisioningProfiles(profilesList string) ([]string, error) { profiles := splitAndClean(profilesList, "\n", true) if len(profiles) == 1 { profiles = splitAndClean(profiles[0], "|", true) @@ -179,7 +180,7 @@ func validateAndExpandProfilePaths(profilesList string) ([]string, error) { for _, profile := range profiles { profileURL, err := url.Parse(profile) if err != nil { - return []string{}, fmt.Errorf("invalid provisioning profile URL (%s): %w", profile, err) + return []string{}, fmt.Errorf("invalid provisioning profile URL specified (%s): %w", profile, err) } // When file or https scheme provided, will fetch as a file @@ -203,14 +204,14 @@ func validateAndExpandProfilePaths(profilesList string) ([]string, error) { func listProfilesInDirectory(dir string) ([]string, error) { exists, err := pathutil.IsDirExists(dir) if err != nil { - return nil, fmt.Errorf("failed to check if provisioning profile path (%s) exists: %w", dir, err) + return nil, fmt.Errorf("failed to check if provisioning profile path exists (%s): %w", dir, err) } else if !exists { - return nil, fmt.Errorf("please provide remote (https://) or local (file://) provisioning profile file paths with a scheme, or a local directory without a scheme: profile directory (%s) does not exist", dir) + return nil, fmt.Errorf("directory of provisioning profiles does not exist (%s)", dir) } dirEntries, err := os.ReadDir(dir) if err != nil { - return nil, fmt.Errorf("failed to list profile directory: %w", err) + return nil, fmt.Errorf("failed to list entries of the provisioning profiles directory (%s): %w", dir, err) } var profiles []string diff --git a/vendor/modules.txt b/vendor/modules.txt index a1f5893..8d02df8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -51,7 +51,7 @@ github.com/bitrise-io/go-xcode/xcodeproject/serialized github.com/bitrise-io/go-xcode/xcodeproject/xcodeproj github.com/bitrise-io/go-xcode/xcodeproject/xcscheme github.com/bitrise-io/go-xcode/xcodeproject/xcworkspace -# github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.20 +# github.com/bitrise-io/go-xcode/v2 v2.0.0-alpha.25 ## explicit; go 1.16 github.com/bitrise-io/go-xcode/v2/autocodesign github.com/bitrise-io/go-xcode/v2/autocodesign/certdownloader