func initBitriseWorkPaths() error { bitriseWorkDirPath, err := filepath.Abs("./.bitrise") if err != nil { return err } if exist, err := pathutil.IsPathExists(bitriseWorkDirPath); err != nil { return err } else if !exist { if err := os.MkdirAll(bitriseWorkDirPath, 0777); err != nil { return err } } BitriseWorkDirPath = bitriseWorkDirPath bitriseWorkStepsDirPath, err := filepath.Abs(path.Join(BitriseWorkDirPath, "step_src")) if err != nil { return err } if exist, err := pathutil.IsPathExists(bitriseWorkStepsDirPath); err != nil { return err } else if !exist { if err := os.MkdirAll(bitriseWorkStepsDirPath, 0777); err != nil { return err } } BitriseWorkStepsDirPath = bitriseWorkStepsDirPath return nil }
// ReadSpecStep ... func ReadSpecStep(pth string) (stepmanModels.StepModel, error) { if isExists, err := pathutil.IsPathExists(pth); err != nil { return stepmanModels.StepModel{}, err } else if !isExists { return stepmanModels.StepModel{}, errors.New(fmt.Sprint("No file found at path", pth)) } bytes, err := ioutil.ReadFile(pth) if err != nil { return stepmanModels.StepModel{}, err } var stepModel stepmanModels.StepModel if err := yaml.Unmarshal(bytes, &stepModel); err != nil { return stepmanModels.StepModel{}, err } if err := stepModel.Normalize(); err != nil { return stepmanModels.StepModel{}, err } if err := stepModel.ValidateStep(); err != nil { return stepmanModels.StepModel{}, err } if err := stepModel.FillMissingDefaults(); err != nil { return stepmanModels.StepModel{}, err } return stepModel, nil }
// ReadBitriseConfig ... func ReadBitriseConfig(pth string) (models.BitriseDataModel, error) { log.Debugln("-> ReadBitriseConfig") if isExists, err := pathutil.IsPathExists(pth); err != nil { return models.BitriseDataModel{}, err } else if !isExists { return models.BitriseDataModel{}, errors.New(fmt.Sprint("No file found at path", pth)) } bytes, err := ioutil.ReadFile(pth) if err != nil { return models.BitriseDataModel{}, err } var bitriseData models.BitriseDataModel if err := yaml.Unmarshal(bytes, &bitriseData); err != nil { return models.BitriseDataModel{}, err } if err := bitriseData.Normalize(); err != nil { return models.BitriseDataModel{}, err } if err := bitriseData.Validate(); err != nil { return models.BitriseDataModel{}, err } if err := bitriseData.FillMissingDefaults(); err != nil { return models.BitriseDataModel{}, err } return bitriseData, nil }
// RemoveDir ... func RemoveDir(dirPth string) error { if exist, err := pathutil.IsPathExists(dirPth); err != nil { return err } else if exist { if err := os.RemoveAll(dirPth); err != nil { return err } } return nil }
// RemoveFile ... func RemoveFile(pth string) error { if exist, err := pathutil.IsPathExists(pth); err != nil { return err } else if exist { if err := os.Remove(pth); err != nil { return err } } return nil }
func doInit(c *cli.Context) { log.Info("[BITRISE_CLI] - Init -- Work-in-progress!") bitriseConfigFileRelPath := "./bitrise.yml" if exists, err := pathutil.IsPathExists(bitriseConfigFileRelPath); err != nil { log.Fatalln("Error:", err) } else if exists { ask := fmt.Sprintf("A config file already exists at %s - do you want to overwrite it?", bitriseConfigFileRelPath) if val, err := goinp.AskForBool(ask); err != nil { log.Fatalln("Error:", err) } else if val == false { log.Infoln("Init canceled, existing file won't be overwritten.") os.Exit(0) } } projectSettingsEnvs := []models.EnvironmentItemModel{} if val, err := goinp.AskForString("What's the BITRISE_PROJECT_TITLE?"); err != nil { log.Fatalln(err) } else { projectSettingsEnvs = append(projectSettingsEnvs, models.EnvironmentItemModel{"BITRISE_PROJECT_TITLE": val, "is_expand": "no"}) } if val, err := goinp.AskForString("What's your primary development branch's name?"); err != nil { log.Fatalln(err) } else { projectSettingsEnvs = append(projectSettingsEnvs, models.EnvironmentItemModel{"BITRISE_DEV_BRANCH": val, "is_expand": "no"}) } // TODO: // generate a couple of base steps // * timestamp gen // * bash script bitriseConf := models.BitriseConfigModel{ FormatVersion: "1.0.0", // TODO: move this into a project config file! App: models.AppModel{ Environments: projectSettingsEnvs, }, Workflows: map[string]models.WorkflowModel{ "primary": models.WorkflowModel{}, }, } if err := SaveToFile(bitriseConfigFileRelPath, bitriseConf); err != nil { log.Fatalln("Failed to init:", err) } os.Exit(1) }
func saveSecretsToFile(pth, secretsStr string) (bool, error) { if exists, err := pathutil.IsPathExists(pth); err != nil { return false, err } else if exists { ask := fmt.Sprintf("A secrets file already exists at %s - do you want to overwrite it?", pth) if val, err := goinp.AskForBool(ask); err != nil { return false, err } else if !val { log.Infoln("Init canceled, existing file (" + pth + ") won't be overwritten.") return false, nil } } if err := bitrise.WriteStringToFile(pth, secretsStr); err != nil { return false, err } return true, nil }
// ReadBitriseConfigYML ... func ReadBitriseConfigYML(pth string) (models.BitriseConfigModel, error) { if isExists, err := pathutil.IsPathExists(pth); err != nil { return models.BitriseConfigModel{}, err } else if isExists == false { return models.BitriseConfigModel{}, NewErrorf("No file found at path", pth) } bytes, err := ioutil.ReadFile(pth) if err != nil { return models.BitriseConfigModel{}, err } var bitriseConfig models.BitriseConfigModel if err := yaml.Unmarshal(bytes, &bitriseConfig); err != nil { return models.BitriseConfigModel{}, err } return bitriseConfig, nil }
func doRun(c *cli.Context) { PrintBitriseHeaderASCIIArt() log.Debugln("[BITRISE_CLI] - Run") startTime = time.Now() buildRunResults = models.BuildRunResultsModel{} // Cleanup if err := bitrise.CleanupBitriseWorkPath(); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to cleanup bitrise work dir: " + err.Error())) } // Input validation bitriseConfigPath := c.String(PathKey) if bitriseConfigPath == "" { log.Debugln("[BITRISE_CLI] - Workflow path not defined, searching for " + DefaultBitriseConfigFileName + " in current folder...") bitriseConfigPath = bitrise.CurrentDir + "/" + DefaultBitriseConfigFileName if exist, err := pathutil.IsPathExists(bitriseConfigPath); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to check path:" + err.Error())) } else if !exist { log.Fatalln("[BITRISE_CLI] - No workflow yml found") buildFailedFatal(errors.New("[BITRISE_CLI] - No workflow yml found")) } } inventoryPath = c.String(InventoryKey) if inventoryPath == "" { log.Debugln("[BITRISE_CLI] - Inventory path not defined, searching for " + DefaultSecretsFileName + " in current folder...") inventoryPath = bitrise.CurrentDir + "/" + DefaultSecretsFileName if exist, err := pathutil.IsPathExists(inventoryPath); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to check path: " + err.Error())) } else if !exist { log.Debugln("[BITRISE_CLI] - No inventory yml found") inventoryPath = "" } } else { if exist, err := pathutil.IsPathExists(inventoryPath); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to check path: " + err.Error())) } else if !exist { buildFailedFatal(errors.New("[BITRISE_CLI] - No inventory yml found")) } } if inventoryPath != "" { if err := bitrise.RunEnvmanEnvstoreTest(inventoryPath); err != nil { buildFailedFatal(errors.New("Invalid invetory format: " + err.Error())) } if err := bitrise.RunCopy(inventoryPath, bitrise.EnvstorePath); err != nil { buildFailedFatal(errors.New("Failed to copy inventory: " + err.Error())) } } // Workflow selection workflowToRunName := "" if len(c.Args()) < 1 { log.Infoln("No workfow specified!") } else { workflowToRunName = c.Args()[0] } // Envman setup if err := os.Setenv(bitrise.EnvstorePathEnvKey, bitrise.EnvstorePath); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to add env: " + err.Error())) } if err := os.Setenv(bitrise.FormattedOutputPathEnvKey, bitrise.FormattedOutputPath); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to add env: " + err.Error())) } if inventoryPath == "" { if err := bitrise.RunEnvmanInit(); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to run envman init")) } } // Run work flow bitriseConfig, err := bitrise.ReadBitriseConfig(bitriseConfigPath) if err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to read Workflow: " + err.Error())) } // Check workflow if workflowToRunName == "" { // no workflow specified // list all the available ones and then exit log.Infoln("The following workflows are available:") for wfName := range bitriseConfig.Workflows { log.Infoln(" * " + wfName) } fmt.Println() log.Infoln("You can run a selected workflow with:") log.Infoln("-> bitrise run the-workflow-name") os.Exit(1) } // App level environment if err := exportEnvironmentsList(bitriseConfig.App.Environments); err != nil { buildFailedFatal(errors.New("[BITRISE_CLI] - Failed to export App environments: " + err.Error())) } workflowToRun, exist := bitriseConfig.Workflows[workflowToRunName] if !exist { buildFailedFatal(errors.New("[BITRISE_CLI] - Specified Workflow (" + workflowToRunName + ") does not exist!")) } if workflowToRun.Title == "" { workflowToRun.Title = workflowToRunName } activateAndRunWorkflow(workflowToRun, bitriseConfig) // // Build finished printSummary() if len(buildRunResults.FailedSteps) > 0 { log.Fatal("[BITRISE_CLI] - Workflow FINISHED but a couple of steps failed - Ouch") } else { if len(buildRunResults.FailedNotImportantSteps) > 0 { log.Warn("[BITRISE_CLI] - Workflow FINISHED but a couple of non imporatant steps failed") } } }
func doInit(c *cli.Context) { PrintBitriseHeaderASCIIArt() bitriseConfigFileRelPath := "./" + DefaultBitriseConfigFileName bitriseSecretsFileRelPath := "./" + DefaultSecretsFileName if exists, err := pathutil.IsPathExists(bitriseConfigFileRelPath); err != nil { log.Fatalln("Error:", err) } else if exists { ask := fmt.Sprintf("A config file already exists at %s - do you want to overwrite it?", bitriseConfigFileRelPath) if val, err := goinp.AskForBool(ask); err != nil { log.Fatalln("Error:", err) } else if !val { log.Infoln("Init canceled, existing file won't be overwritten.") os.Exit(0) } } defaultExpand := true projectSettingsEnvs := []envmanModels.EnvironmentItemModel{} if val, err := goinp.AskForString("What's the BITRISE_PROJECT_TITLE?"); err != nil { log.Fatalln(err) } else { projectTitleEnv := envmanModels.EnvironmentItemModel{ "BITRISE_PROJECT_TITLE": val, "opts": envmanModels.EnvironmentItemOptionsModel{ IsExpand: &defaultExpand, }, } projectSettingsEnvs = append(projectSettingsEnvs, projectTitleEnv) } if val, err := goinp.AskForString("What's your primary development branch's name?"); err != nil { log.Fatalln(err) } else { devBranchEnv := envmanModels.EnvironmentItemModel{ "BITRISE_DEV_BRANCH": val, "opts": envmanModels.EnvironmentItemOptionsModel{ IsExpand: &defaultExpand, }, } projectSettingsEnvs = append(projectSettingsEnvs, devBranchEnv) } // TODO: // generate a couple of base steps // * timestamp gen // * bash script - hello world scriptStepTitle := "Hello Bitrise!" scriptStepContent := `#!/bin/bash echo "Welcome to Bitrise!"` bitriseConf := models.BitriseDataModel{ FormatVersion: c.App.Version, DefaultStepLibSource: defaultStepLibSource, App: models.AppModel{ Environments: projectSettingsEnvs, }, Workflows: map[string]models.WorkflowModel{ "primary": models.WorkflowModel{ Steps: []models.StepListItemModel{ models.StepListItemModel{ "script": stepmanModels.StepModel{ Title: &scriptStepTitle, Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "content": scriptStepContent, }, }, }, }, }, }, }, } if err := bitrise.SaveConfigToFile(bitriseConfigFileRelPath, bitriseConf); err != nil { log.Fatalln("Failed to init the bitrise config file:", err) } else { fmt.Println() fmt.Println("# NOTES about the " + DefaultBitriseConfigFileName + " config file:") fmt.Println() fmt.Println("We initialized a " + DefaultBitriseConfigFileName + " config file for you.") fmt.Println("If you're in this folder you can use this config file") fmt.Println(" with bitrise automatically, you don't have to") fmt.Println(" specify it's path.") fmt.Println() } if initialized, err := saveSecretsToFile(bitriseSecretsFileRelPath, defaultSecretsContent); err != nil { log.Fatalln("Failed to init the secrets file:", err) } else if initialized { fmt.Println() fmt.Println("# NOTES about the " + DefaultSecretsFileName + " secrets file:") fmt.Println() fmt.Println("We also created a " + DefaultSecretsFileName + " file") fmt.Println(" in this directory, to keep your passwords, absolute path configurations") fmt.Println(" and other secrets separate from your") fmt.Println(" main configuration file.") fmt.Println("This way you can safely commit and share your configuration file") fmt.Println(" and ignore this secrets file, so nobody else will") fmt.Println(" know about your secrets.") fmt.Println(colorstring.Yellow("You should NEVER commit this secrets file into your repository!!")) fmt.Println() } fmt.Println() fmt.Println("Hurray, you're good to go!") fmt.Println("You can simply run:") fmt.Println("-> bitrise run primary") fmt.Println("to test the sample configuration (which contains") fmt.Println("an example workflow called 'primary').") fmt.Println() fmt.Println("Once you tested this sample setup you can") fmt.Println(" open the " + DefaultBitriseConfigFileName + " config file,") fmt.Println(" modify it and then run a workflow with:") fmt.Println("-> bitrise run YOUR-WORKFLOW-NAME") }
func doRun(c *cli.Context) { log.Info("[BITRISE_CLI] - Run") // Input validation bitriseConfigPath := c.String(PathKey) if bitriseConfigPath == "" { log.Infoln("[BITRISE_CLI] - Workflow path not defined, searching for " + defaultBitriseConfigFileName + " in current folder...") if exist, err := pathutil.IsPathExists("./" + defaultBitriseConfigFileName); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to check path:", err) } else if !exist { log.Fatalln("[BITRISE_CLI] - No workflow yml found") } bitriseConfigPath = "./" + defaultBitriseConfigFileName } // Workflow selection if len(c.Args()) < 1 { log.Fatalln("No workfow specified!") } workflowToRunName := c.Args()[0] // Envman setup if err := os.Setenv(bitrise.EnvstorePathEnvKey, bitrise.EnvstorePath); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to add env:", err) } if err := os.Setenv(bitrise.FormattedOutputPathEnvKey, bitrise.FormattedOutputPath); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to add env:", err) } if err := bitrise.RunEnvmanInit(); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to run envman init") } // Run work flow bitriseConfig, err := bitrise.ReadBitriseConfigYML(bitriseConfigPath) if err != nil { log.Fatalln("[BITRISE_CLI] - Failed to read Workflow:", err) } workflowToRun, exist := bitriseConfig.Workflows[workflowToRunName] if !exist { log.Fatalln("[BITRISE_CLI] - Specified Workflow (" + workflowToRunName + ") does not exist!") } log.Infoln("[BITRISE_CLI] - Running Workflow:", workflowToRunName) // App level environment if err := exportEnvironmentsList(bitriseConfig.App.Environments); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to export App environments:", err) } // Workflow level environments if err := exportEnvironmentsList(workflowToRun.Environments); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to export Workflow environments:", err) } // Run the Workflow if err := activateAndRunSteps(workflowToRun); err != nil { log.Fatalln("[BITRISE_CLI] - Failed to activate steps:", err) } }