func executeStep(step stepmanModels.StepModel, sIDData models.StepIDData, stepAbsDirPath, bitriseSourceDir string) (int, error) { toolkitForStep := toolkits.ToolkitForStep(step) toolkitName := toolkitForStep.ToolkitName() if err := toolkitForStep.PrepareForStepRun(step, sIDData, stepAbsDirPath); err != nil { return 1, fmt.Errorf("Failed to prepare the step for execution through the required toolkit (%s), error: %s", toolkitName, err) } cmd, err := toolkitForStep.StepRunCommandArguments(stepAbsDirPath, sIDData) if err != nil { return 1, fmt.Errorf("Toolkit (%s) rejected the step, error: %s", toolkitName, err) } return tools.EnvmanRun(configs.InputEnvstorePath, bitriseSourceDir, cmd) }
func runPlugin(plugin Plugin, args []string, pluginInput PluginInput) error { if !configs.IsCIMode && configs.CheckIsPluginUpdateCheckRequired() { // Check for new version log.Infof("Checking for plugin (%s) new version...", plugin.Name) if newVersion, err := CheckForNewVersion(plugin); err != nil { log.Warnf("") log.Warnf("Failed to check for plugin (%s) new version, error: %s", plugin.Name, err) } else if newVersion != "" { log.Warnf("") log.Warnf("New version (%s) of plugin (%s) available", newVersion, plugin.Name) route, found, err := ReadPluginRoute(plugin.Name) if err != nil { return err } if !found { return fmt.Errorf("no route found for already loaded plugin (%s)", plugin.Name) } route.LatestAvailableVersion = newVersion if err := AddPluginRoute(route); err != nil { return fmt.Errorf("failed to register available plugin (%s) update (%s), error: %s", plugin.Name, newVersion, err) } } else { log.Debugf("No new version of plugin (%s) available", plugin.Name) } if err := configs.SavePluginUpdateCheck(); err != nil { return err } fmt.Println() } else { route, found, err := ReadPluginRoute(plugin.Name) if err != nil { return err } if !found { return fmt.Errorf("no route found for already loaded plugin (%s)", plugin.Name) } if route.LatestAvailableVersion != "" { log.Warnf("") log.Warnf("New version (%s) of plugin (%s) available", route.LatestAvailableVersion, plugin.Name) } } // Append common data to plugin iputs bitriseVersion, err := version.BitriseCliVersion() if err != nil { return err } pluginInput[pluginInputBitriseVersionKey] = bitriseVersion.String() pluginInput[pluginInputDataDirKey] = GetPluginDataDir(plugin.Name) // Prepare plugin envstore pluginWorkDir, err := pathutil.NormalizedOSTempDirPath("plugin-work-dir") if err != nil { return err } defer func() { if err := os.RemoveAll(pluginWorkDir); err != nil { log.Warnf("Failed to remove path (%s)", pluginWorkDir) } }() pluginEnvstorePath := filepath.Join(pluginWorkDir, "envstore.yml") if err := tools.EnvmanInitAtPath(pluginEnvstorePath); err != nil { return err } if err := tools.EnvmanAdd(pluginEnvstorePath, configs.EnvstorePathEnvKey, pluginEnvstorePath, false, false); err != nil { return err } log.Debugf("plugin evstore path (%s)", pluginEnvstorePath) // Add plugin inputs for key, value := range pluginInput { if err := tools.EnvmanAdd(pluginEnvstorePath, key, value, false, false); err != nil { return err } } // Run plugin executable pluginExecutable, isBin, err := GetPluginExecutablePath(plugin.Name) if err != nil { return err } cmd := []string{} if isBin { log.Debugf("Run plugin binary (%s)", pluginExecutable) cmd = append([]string{pluginExecutable}, args...) } else { log.Debugf("Run plugin sh (%s)", pluginExecutable) cmd = append([]string{"bash", pluginExecutable}, args...) } exitCode, err := tools.EnvmanRun(pluginEnvstorePath, "", cmd) log.Debugf("Plugin run finished with exit code (%d)", exitCode) if err != nil { return err } // Read plugin output outStr, err := tools.EnvmanJSONPrint(pluginEnvstorePath) if err != nil { return err } envList, err := envmanModels.NewEnvJSONList(outStr) if err != nil { return err } pluginOutputStr, found := envList[bitrisePluginOutputEnvKey] if found { log.Debugf("Plugin output: %s", pluginOutputStr) } return nil }
func runStep(step stepmanModels.StepModel, stepIDData models.StepIDData, stepDir string, environments []envmanModels.EnvironmentItemModel, buildRunResults models.BuildRunResultsModel) (int, []envmanModels.EnvironmentItemModel, error) { log.Debugf("[BITRISE_CLI] - Try running step: %s (%s)", stepIDData.IDorURI, stepIDData.Version) // Check & Install Step Dependencies if len(step.Dependencies) > 0 { log.Warnf("step.dependencies is deprecated... Use step.deps instead.") } if len(step.Deps.Brew) > 0 || len(step.Deps.AptGet) > 0 || len(step.Deps.CheckOnly) > 0 { // // New dependency handling for _, checkOnlyDep := range step.Deps.CheckOnly { if err := bitrise.DependencyTryCheckTool(checkOnlyDep.Name); err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } log.Infof(" * "+colorstring.Green("[OK]")+" Step dependency (%s) installed, available.", checkOnlyDep.Name) } switch runtime.GOOS { case "darwin": for _, brewDep := range step.Deps.Brew { if err := bitrise.InstallWithBrewIfNeeded(brewDep.Name, configs.IsCIMode); err != nil { log.Infof("Failed to install (%s) with brew", brewDep.Name) return 1, []envmanModels.EnvironmentItemModel{}, err } log.Infof(" * "+colorstring.Green("[OK]")+" Step dependency (%s) installed, available.", brewDep.Name) } case "linux": for _, aptGetDep := range step.Deps.AptGet { log.Infof("Start installing (%s) with apt-get", aptGetDep.Name) if err := bitrise.InstallWithAptGetIfNeeded(aptGetDep.Name, configs.IsCIMode); err != nil { log.Infof("Failed to install (%s) with apt-get", aptGetDep.Name) return 1, []envmanModels.EnvironmentItemModel{}, err } log.Infof(" * "+colorstring.Green("[OK]")+" Step dependency (%s) installed, available.", aptGetDep.Name) } default: return 1, []envmanModels.EnvironmentItemModel{}, errors.New("Unsupported os") } } else if len(step.Dependencies) > 0 { log.Info("Deprecated dependencies found") // // Deprecated dependency handling for _, dep := range step.Dependencies { isSkippedBecauseOfPlatform := false switch dep.Manager { case depManagerBrew: if runtime.GOOS == "darwin" { err := bitrise.InstallWithBrewIfNeeded(dep.Name, configs.IsCIMode) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } } else { isSkippedBecauseOfPlatform = true } break case depManagerTryCheck: err := bitrise.DependencyTryCheckTool(dep.Name) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } break default: return 1, []envmanModels.EnvironmentItemModel{}, errors.New("Not supported dependency (" + dep.Manager + ") (" + dep.Name + ")") } if isSkippedBecauseOfPlatform { log.Debugf(" * Dependency (%s) skipped, manager (%s) not supported on this platform (%s)", dep.Name, dep.Manager, runtime.GOOS) } else { log.Infof(" * "+colorstring.Green("[OK]")+" Step dependency (%s) installed, available.", dep.Name) } } } // Collect step inputs if err := tools.EnvmanInitAtPath(configs.InputEnvstorePath); err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } if err := bitrise.ExportEnvironmentsList(environments); err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } evaluatedInputs := []envmanModels.EnvironmentItemModel{} for _, input := range step.Inputs { key, value, err := input.GetKeyValuePair() if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } options, err := input.GetOptions() if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } if options.IsTemplate != nil && *options.IsTemplate { outStr, err := tools.EnvmanJSONPrint(configs.InputEnvstorePath) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, fmt.Errorf("EnvmanJSONPrint failed, err: %s", err) } envList, err := envmanModels.NewEnvJSONList(outStr) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, fmt.Errorf("CreateFromJSON failed, err: %s", err) } evaluatedValue, err := bitrise.EvaluateTemplateToString(value, configs.IsCIMode, configs.IsPullRequestMode, buildRunResults, envList) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } input[key] = evaluatedValue } evaluatedInputs = append(evaluatedInputs, input) } environments = append(environments, evaluatedInputs...) if err := tools.EnvmanInitAtPath(configs.InputEnvstorePath); err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } if err := bitrise.ExportEnvironmentsList(environments); err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } // Run step stepCmd := filepath.Join(stepDir, "step.sh") cmd := []string{"bash", stepCmd} bitriseSourceDir, err := getCurrentBitriseSourceDir(environments) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } if bitriseSourceDir == "" { bitriseSourceDir = configs.CurrentDir } if exit, err := tools.EnvmanRun(configs.InputEnvstorePath, bitriseSourceDir, cmd); err != nil { stepOutputs, envErr := bitrise.CollectEnvironmentsFromFile(configs.OutputEnvstorePath) if envErr != nil { return 1, []envmanModels.EnvironmentItemModel{}, envErr } return exit, stepOutputs, err } stepOutputs, err := bitrise.CollectEnvironmentsFromFile(configs.OutputEnvstorePath) if err != nil { return 1, []envmanModels.EnvironmentItemModel{}, err } log.Debugf("[BITRISE_CLI] - Step executed: %s (%s)", stepIDData.IDorURI, stepIDData.Version) return 0, stepOutputs, nil }