Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exported functions #105

Merged
merged 9 commits into from
Jun 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions cmd/xamarin.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,34 +161,31 @@ func scanXamarinProject(cmd *cobra.Command, args []string) error {
fmt.Println()
fmt.Println()
log.Printf(`🔦 Running a Build, to get all the required code signing settings...`)
var isLogFileWritten bool
logOutputFilePath := filepath.Join(absExportOutputDirPath, "xamarin-build-output.log")

archivePath, logOutput, err := xamarinCmd.GenerateArchive()
if writeFiles == codesign.WriteFilesAlways ||
writeFiles == codesign.WriteFilesFallback && err != nil { // save the xamarin output into a debug log file
if writeFiles == codesign.WriteFilesAlways || writeFiles == codesign.WriteFilesFallback && err != nil { // save the xamarin output into a debug log file
if err := os.MkdirAll(absExportOutputDirPath, 0700); err != nil {
return fmt.Errorf("failed to create output directory, error: %s", err)
}

log.Infof("💡 "+colorstring.Yellow("Saving xamarin output into file")+": %s", logOutputFilePath)
if err := fileutil.WriteStringToFile(logOutputFilePath, logOutput); err != nil {
log.Errorf("Failed to save xamarin build output into file (%s), error: %s", logOutputFilePath, err)
} else {
isLogFileWritten = true
}
}
if err != nil {
log.Warnf("Last lines of build log:")
log.Warnf("Last lines of the build log:")
fmt.Println(stringutil.LastNLines(logOutput, 15))

log.Infof(colorstring.Yellow("Please check the build log to see what caused the error."))
fmt.Println()
if isLogFileWritten {
godrei marked this conversation as resolved.
Show resolved Hide resolved
log.Warnf("Please check the logfile (%s) to see what caused the error", logOutputFilePath)
log.Warnf(`and make sure that you can "Archive for Publishing" this project from Xamarin!`)
fmt.Println()
log.Infof("Open the project: %s", xamarinCmd.SolutionFilePath)
log.Infof(`And do "Archive for Publishing", after selecting the Configuration+Platform: %s|%s`, xamarinCmd.Configuration, xamarinCmd.Platform)
fmt.Println()
}

log.Errorf("Build failed.")
log.Infof(colorstring.Yellow("Open the project: ")+"%s", xamarinCmd.SolutionFilePath)
log.Infof(colorstring.Yellow(`And do "Archive for Publishing", after selecting the Configuration+Platform: `)+"%s|%s", xamarinCmd.Configuration, xamarinCmd.Platform)
fmt.Println()

return ArchiveError{toolXamarin, "failed to run xamarin build command: " + err.Error()}
}

Expand All @@ -197,9 +194,14 @@ func scanXamarinProject(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
exoprtResult, err := codesign.UploadAndWriteCodesignFiles(certificatesToExport,
profilesToExport,
isAskForPassword,

certificates, profiles, err := codesign.ExportCodesigningFiles(certificatesToExport, profilesToExport, isAskForPassword)
if err != nil {
return err
}

exportResult, err := codesign.UploadAndWriteCodesignFiles(certificates,
profiles,
codesign.WriteFilesConfig{
WriteFiles: writeFiles,
AbsOutputDirPath: absExportOutputDirPath,
Expand All @@ -212,6 +214,6 @@ func scanXamarinProject(cmd *cobra.Command, args []string) error {
return err
}

printFinished(exoprtResult, absExportOutputDirPath)
printFinished(exportResult, absExportOutputDirPath)
return nil
}
64 changes: 19 additions & 45 deletions cmd/xcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"github.com/bitrise-io/go-utils/fileutil"
"github.com/bitrise-io/go-utils/log"
"github.com/bitrise-io/go-utils/pathutil"
"github.com/bitrise-io/go-utils/stringutil"
"github.com/bitrise-io/go-xcode/utility"
"github.com/bitrise-io/goinp/goinp"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -54,29 +52,19 @@ func absOutputDir() (string, error) {
return absExportOutputDirPath, nil
}

func scanXcodeProject(cmd *cobra.Command, args []string) error {
func scanXcodeProject(_ *cobra.Command, _ []string) error {
absExportOutputDirPath, err := absOutputDir()
if err != nil {
return err
}

// Output tools versions
xcodebuildVersion, err := utility.GetXcodeVersion()
godrei marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf("failed to get Xcode (xcodebuild) version, error: %s", err)
}
fmt.Println()
log.Infof("%s: %s (%s)", colorstring.Green("Xcode (xcodebuild) version"), xcodebuildVersion.Version, xcodebuildVersion.BuildVersion)
fmt.Println()

xcodeCmd := xcode.CommandModel{}

projectPath := paramXcodeProjectFilePath
if projectPath == "" {
log.Infof("Scan the directory for project files")
log.Warnf("You can specify the Xcode project/workscape file to scan with the --file flag.")

//
// Scan the directory for Xcode Project (.xcworkspace / .xcodeproject) file first
// If can't find any, ask the user to drag-and-drop the file
projpth, err := findXcodeProject()
Expand Down Expand Up @@ -120,47 +108,33 @@ func scanXcodeProject(cmd *cobra.Command, args []string) error {
xcodeCmd.SDK = paramXcodebuildSDK
}

fmt.Println()
log.Printf("🔦 Running an Xcode Archive, to get all the required code signing settings...")
var isLogFileWritten bool
xcodebuildOutputFilePath := filepath.Join(absExportOutputDirPath, "xcodebuild-output.log")
archivePath, xcodebuildOutput, err := xcodeCmd.GenerateArchive()
writeBuildLogs := func(xcodebuildOutput string) error {
if writeFiles == codesign.WriteFilesAlways || writeFiles == codesign.WriteFilesFallback && err != nil { // save the xcodebuild output into a debug log file
xcodebuildOutputFilePath := filepath.Join(absExportOutputDirPath, "xcodebuild-output.log")
if err := os.MkdirAll(absExportOutputDirPath, 0700); err != nil {
return fmt.Errorf("failed to create output directory, error: %s", err)
}

if writeFiles == codesign.WriteFilesAlways ||
writeFiles == codesign.WriteFilesFallback && err != nil { // save the xcodebuild output into a debug log file
if err := os.MkdirAll(absExportOutputDirPath, 0700); err != nil {
return fmt.Errorf("failed to create output directory, error: %s", err)
}
log.Infof("💡 "+colorstring.Yellow("Saving xcodebuild output into file")+": %s", xcodebuildOutputFilePath)
if err := fileutil.WriteStringToFile(xcodebuildOutputFilePath, xcodebuildOutput); err != nil {
log.Errorf("Failed to save xcodebuild output into file (%s), error: %s", xcodebuildOutputFilePath, err)
} else {
isLogFileWritten = true
log.Infof("💡 "+colorstring.Yellow("Saving xcodebuild output into file")+": %s", xcodebuildOutputFilePath)
if err := fileutil.WriteStringToFile(xcodebuildOutputFilePath, xcodebuildOutput); err != nil {
return fmt.Errorf("Failed to save xcodebuild output into file (%s), error: %s", xcodebuildOutputFilePath, err)
}
}
return nil
}

archivePath, err := codesigndoc.BuildXcodeArchive(xcodeCmd, writeBuildLogs)
if err != nil {
log.Warnf("Last lines of build log:")
fmt.Println(stringutil.LastNLines(xcodebuildOutput, 15))
fmt.Println()
if isLogFileWritten {
log.Warnf("Please check the logfile (%s) to see what caused the error", xcodebuildOutputFilePath)
log.Warnf("and make sure that you can Archive this project from Xcode!")
fmt.Println()
log.Printf("Open the project: %s", xcodeCmd.ProjectFilePath)
log.Printf("and Archive, using the Scheme: %s", xcodeCmd.Scheme)
fmt.Println()
}
return ArchiveError{toolXcode, err.Error()}
}

// If certificatesOnly is set, CollectCodesignFiles returns an empty slice for profiles
certificatesToExport, profilesToExport, err := codesigndoc.CollectCodesignFiles(archivePath, certificatesOnly)
certificates, profiles, err := codesigndoc.CodesigningFilesForXCodeProject(archivePath, certificatesOnly, isAskForPassword)
if err != nil {
return err
}
exoprtResult, err := codesign.UploadAndWriteCodesignFiles(certificatesToExport,
profilesToExport,
isAskForPassword,

exportResult, err := codesign.UploadAndWriteCodesignFiles(certificates,
profiles,
codesign.WriteFilesConfig{
WriteFiles: writeFiles,
AbsOutputDirPath: absExportOutputDirPath,
Expand All @@ -173,6 +147,6 @@ func scanXcodeProject(cmd *cobra.Command, args []string) error {
return err
}

printFinished(exoprtResult, absExportOutputDirPath)
printFinished(exportResult, absExportOutputDirPath)
return nil
}
36 changes: 20 additions & 16 deletions cmd/xcodeUITests.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,35 +114,34 @@ func scanXcodeUITestsProject(cmd *cobra.Command, args []string) error {
xcodeUITestsCmd.SDK = paramXcodebuildSDK
}

fmt.Println()
fmt.Println()
log.Printf("🔦 Running an Xcode build-for-testing, to get all the required code signing settings...")
var isLogFileWritten bool
xcodebuildOutputFilePath := filepath.Join(absExportOutputDirPath, "xcodebuild-output.log")

buildForTestingPath, xcodebuildOutput, err := xcodeUITestsCmd.RunBuildForTesting()
if writeFiles == codesign.WriteFilesAlways ||
writeFiles == codesign.WriteFilesFallback && err != nil { // save the xcodebuild output into a debug log file
if writeFiles == codesign.WriteFilesAlways || writeFiles == codesign.WriteFilesFallback && err != nil { // save the xcodebuild output into a debug log file
if err := os.MkdirAll(absExportOutputDirPath, 0700); err != nil {
return fmt.Errorf("failed to create output directory, error: %s", err)
}

log.Infof("💡 "+colorstring.Yellow("Saving xcodebuild output into file")+": %s", xcodebuildOutputFilePath)
if err := fileutil.WriteStringToFile(xcodebuildOutputFilePath, xcodebuildOutput); err != nil {
log.Errorf("Failed to save xcodebuild output into file (%s), error: %s", xcodebuildOutputFilePath, err)
} else {
isLogFileWritten = true
}
}
if err != nil {
log.Warnf("Last lines of build log:")
log.Warnf("Last lines of the build log:")
fmt.Println(stringutil.LastNLines(xcodebuildOutput, 15))

log.Infof(colorstring.Yellow("Please check the build log to see what caused the error."))
fmt.Println()
if isLogFileWritten {
log.Warnf("Please check the logfile (%s) to see what caused the error", xcodebuildOutputFilePath)
log.Warnf("and make sure that you can run Build for testing against the project from Xcode!")
fmt.Println()
log.Printf("Open the project: %s", xcodeUITestsCmd.ProjectFilePath)
fmt.Println()
}

log.Errorf("Xcode Build For Testing failed.")
log.Infof(colorstring.Yellow("Open the project: ")+"%s", xcodeUITestsCmd.ProjectFilePath)
log.Infof(colorstring.Yellow("and make sure that you can run Build For Testing, with the scheme: ")+"%s", xcodeUITestsCmd.Scheme)
fmt.Println()

return BuildForTestingError{toolXcode, err.Error()}
}

Expand All @@ -151,9 +150,14 @@ func scanXcodeUITestsProject(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
exportResult, err := codesign.UploadAndWriteCodesignFiles(certificatesToExport,
profilesToExport,
isAskForPassword,

certificates, profiles, err := codesign.ExportCodesigningFiles(certificatesToExport, profilesToExport, isAskForPassword)
if err != nil {
return err
}

exportResult, err := codesign.UploadAndWriteCodesignFiles(certificates,
profiles,
codesign.WriteFilesConfig{
WriteFiles: writeFiles,
AbsOutputDirPath: absExportOutputDirPath,
Expand Down
43 changes: 25 additions & 18 deletions codesign/export.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package codesign

import (
"bytes"
"errors"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -53,38 +52,49 @@ type ExportReport struct {
CodesignFilesWritten bool
}

// UploadAndWriteCodesignFiles exports then uploads codesign files to bitrise.io and saves them to output folder
func UploadAndWriteCodesignFiles(certificates []certificateutil.CertificateInfoModel, profiles []profileutil.ProvisioningProfileInfoModel, askForPassword bool, writeFilesConfig WriteFilesConfig, uploadConfig UploadConfig) (ExportReport, error) {
identities, err := collectAndExportIdentities(certificates, askForPassword)
// ExportCodesigningFiles exports certificates from the Keychain and provisoining profiles from their directory
func ExportCodesigningFiles(certificatesRequired []certificateutil.CertificateInfoModel, profilesRequired []profileutil.ProvisioningProfileInfoModel, askForPassword bool) (models.Certificates, []models.ProvisioningProfile, error) {
certificates, err := exportIdentities(certificatesRequired, askForPassword)
if err != nil {
return ExportReport{}, err
return models.Certificates{}, nil, err
}
provisioningProfiles, err := collectAndExportProvisioningProfiles(profiles)

profiles, err := exportProvisioningProfiles(profilesRequired)
if err != nil {
return ExportReport{}, err
return models.Certificates{}, nil, err
}

return certificates, profiles, nil
}

// UploadAndWriteCodesignFiles exports then uploads codesign files to bitrise.io and saves them to output folder
func UploadAndWriteCodesignFiles(certificates models.Certificates, provisioningProfiles []models.ProvisioningProfile, writeFilesConfig WriteFilesConfig, uploadConfig UploadConfig) (ExportReport, error) {
var client *bitrise.Client
// both or none CLI flags are required
if uploadConfig.PersonalAccessToken != "" && uploadConfig.AppSlug != "" {
// Upload automatically if token is provided as CLI paramter, do not export to filesystem
// Used to upload artifacts as part of an other CLI tool
var err error
client, err = bitrise.NewClient(uploadConfig.PersonalAccessToken)
if err != nil {
return ExportReport{}, err
}

client.SetSelectedAppSlug(uploadConfig.AppSlug)
}

if client == nil {
uploadConfirmMsg := "Do you want to upload the provisioning profiles and certificates to Bitrise?"
if len(provisioningProfiles) == 0 {
uploadConfirmMsg = "Do you want to upload the certificates to Bitrise?"
}
fmt.Println()

shouldUpload, err := goinp.AskForBoolFromReader(uploadConfirmMsg, os.Stdin)
if err != nil {
return ExportReport{}, err
}

if shouldUpload {
if client, err = bitriseio.GetInteractiveConfigClient(); err != nil {
return ExportReport{}, err
Expand All @@ -95,21 +105,21 @@ func UploadAndWriteCodesignFiles(certificates []certificateutil.CertificateInfoM
var filesWritten bool
if writeFilesConfig.WriteFiles == WriteFilesAlways ||
writeFilesConfig.WriteFiles == WriteFilesFallback && client == nil {
if err := writeFiles(identities, provisioningProfiles, writeFilesConfig); err != nil {
if err := writeFiles(certificates, provisioningProfiles, writeFilesConfig); err != nil {
return ExportReport{}, err
}
filesWritten = true
}

if client == nil {
return ExportReport{
CertificatesUploaded: len(certificates) == 0,
ProvisioningProfilesUploaded: len(profiles) == 0,
CertificatesUploaded: len(certificates.Info) == 0,
ProvisioningProfilesUploaded: len(provisioningProfiles) == 0,
CodesignFilesWritten: filesWritten,
}, nil
}

certificatesUploaded, profilesUploaded, err := bitriseio.UploadCodesigningFiles(client, identities, provisioningProfiles)
certificatesUploaded, profilesUploaded, err := bitriseio.UploadCodesigningFiles(client, certificates, provisioningProfiles)
return ExportReport{
CertificatesUploaded: certificatesUploaded,
ProvisioningProfilesUploaded: profilesUploaded,
Expand Down Expand Up @@ -147,8 +157,8 @@ func writeFiles(identities models.Certificates, provisioningProfiles []models.Pr
return nil
}

// collectAndExportIdentities exports the given certificates merged in a single .p12 file
func collectAndExportIdentities(certificates []certificateutil.CertificateInfoModel, isAskForPassword bool) (models.Certificates, error) {
// exportIdentities exports the given certificates merged in a single .p12 file
func exportIdentities(certificates []certificateutil.CertificateInfoModel, isAskForPassword bool) (models.Certificates, error) {
if len(certificates) == 0 {
return models.Certificates{}, nil
}
Expand Down Expand Up @@ -215,8 +225,8 @@ func writeIdentities(identites []byte, absExportOutputDirPath string) error {
return ioutil.WriteFile(filepath.Join(absExportOutputDirPath, "Identities.p12"), identites, 0600)
}

// collectAndExportProvisioningProfiles returns provisioning profies
func collectAndExportProvisioningProfiles(profiles []profileutil.ProvisioningProfileInfoModel) ([]models.ProvisioningProfile, error) {
// exportProvisioningProfiles returns provisioning profies
func exportProvisioningProfiles(profiles []profileutil.ProvisioningProfileInfoModel) ([]models.ProvisioningProfile, error) {
if len(profiles) == 0 {
return nil, nil
}
Expand All @@ -242,9 +252,6 @@ func collectAndExportProvisioningProfiles(profiles []profileutil.ProvisioningPro
if err != nil {
return nil, fmt.Errorf("failed to parse exported profile, error: %s", err)
}
if bytes.Compare(profile.Content(), exportedProfile.Content()) != 0 {
return nil, fmt.Errorf("Profile found in the archive does not match found profile")
}

contents, err := ioutil.ReadFile(pth)
if err != nil {
Expand Down
Loading