Example #1
0
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)
}
Example #2
0
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
}
Example #3
0
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
}