Example #1
0
func printStepSummary(title string, resultCode int, duration time.Duration, exitCode int) {
	runTime := bitrise.TimeToFormattedSeconds(duration, " sec")
	content := fmt.Sprintf("%s | .... | %s", title, runTime)
	if resultCode == stepRunResultCodeFailed || resultCode == stepRunResultCodeFailedNotImportant {
		content = fmt.Sprintf("%s | .... | exit code: %d | %s", title, exitCode, runTime)
	}
	if len(content) > stepRunSummaryBoxMaxWidthChars {
		dif := len(content) - stepRunSummaryBoxMaxWidthChars
		title = title[0:(len(title) - dif)]
		content = fmt.Sprintf("%s | .... | %s", title, runTime)
		if resultCode == stepRunResultCodeFailed || resultCode == stepRunResultCodeFailedNotImportant {
			content = fmt.Sprintf("%s | .... | exit code: %d | %s", title, exitCode, runTime)
		}
	}

	sep := strings.Repeat("-", len(content)+2)
	log.Info(sep)
	switch resultCode {
	case stepRunResultCodeSuccess:
		runStateIcon := "✅ "
		content = fmt.Sprintf("%s | %s | %s", runStateIcon, colorstring.Green(title), runTime)
		break
	case stepRunResultCodeFailed:
		runStateIcon := "❌ "
		content = fmt.Sprintf("%s | %s | %s | exit code: %d", runStateIcon, colorstring.Red(title), runTime, exitCode)
		break
	case stepRunResultCodeFailedNotImportant:
		runStateIcon := "❌ "
		content = fmt.Sprintf("%s | %s | %s | exit code: %d", runStateIcon, colorstring.Yellow(title), runTime, exitCode)
		break
	case stepRunResultCodeSkipped, stepRunResultCodeSkippedWithRunIf:
		runStateIcon := "➡ "
		content = fmt.Sprintf("%s | %s | %s", runStateIcon, colorstring.White(title), runTime)
		break
	default:
		log.Error("Unkown result code")
		return
	}

	log.Infof("| " + content + " |")
	log.Info(sep)
	fmt.Println()
}
Example #2
0
func activateAndRunSteps(workflow models.WorkflowModel, defaultStepLibSource string) (workflowRunResults models.BuildRunResultsModel) {
	log.Debugln("[BITRISE_CLI] - Activating and running steps")

	var stepStartTime time.Time

	registerStepRunResults := func(step stepmanModels.StepModel, resultCode int, exitCode int, err error) {
		stepResults := models.StepRunResultsModel{
			StepName: *step.Title,
			Error:    err,
			ExitCode: exitCode,
		}

		switch resultCode {
		case stepRunResultCodeSuccess:
			workflowRunResults.SuccessSteps = append(workflowRunResults.SuccessSteps, stepResults)
			break
		case stepRunResultCodeFailed:
			log.Errorf("Step (%s) failed, error: (%v)", *step.Title, err)
			workflowRunResults.FailedSteps = append(workflowRunResults.FailedSteps, stepResults)
			break
		case stepRunResultCodeFailedNotImportant:
			log.Warnf("Step (%s) failed, but was marked as not important, error: (%v)", *step.Title, err)
			workflowRunResults.FailedNotImportantSteps = append(workflowRunResults.FailedNotImportantSteps, stepResults)
			break
		case stepRunResultCodeSkipped:
			log.Warnf("A previous step failed, and this step (%s) was not marked as IsAlwaysRun, skipped", *step.Title)
			workflowRunResults.SkippedSteps = append(workflowRunResults.SkippedSteps, stepResults)
			break
		case stepRunResultCodeSkippedWithRunIf:
			log.Warn("The step's (" + *step.Title + ") Run-If expression evaluated to false - skipping")
			log.Info("The Run-If expression was: ", colorstring.White(*step.RunIf))
			workflowRunResults.SkippedSteps = append(workflowRunResults.SkippedSteps, stepResults)
			break
		default:
			log.Error("Unkown result code")
			return
		}

		if resultCode != stepRunResultCodeSuccess {
			if err := setBuildFailedEnv(true); err != nil {
				log.Error("Failed to set Build Status envs")
			}
		}

		printStepSummary(*step.Title, resultCode, time.Now().Sub(stepStartTime), exitCode)
	}
	registerStepListItemRunResults := func(stepListItem models.StepListItemModel, resultCode int, exitCode int, err error) {
		name := ""
		for key := range stepListItem {
			name = key
			break
		}

		stepResults := models.StepRunResultsModel{
			StepName: name,
			Error:    err,
			ExitCode: exitCode,
		}

		switch resultCode {
		case stepRunResultCodeSuccess:
			workflowRunResults.SuccessSteps = append(workflowRunResults.SuccessSteps, stepResults)
			break
		case stepRunResultCodeFailed:
			log.Errorf("Step (%s) failed, error: (%v)", name, err)
			workflowRunResults.FailedSteps = append(workflowRunResults.FailedSteps, stepResults)
			break
		case stepRunResultCodeFailedNotImportant:
			log.Warnf("Step (%s) failed, but was marked as not important, error: (%v)", name, err)
			workflowRunResults.FailedNotImportantSteps = append(workflowRunResults.FailedNotImportantSteps, stepResults)
			break
		case stepRunResultCodeSkipped:
			log.Warnf("A previous step failed, and this step (%s) was not marked as IsAlwaysRun, skipped", name)
			workflowRunResults.SkippedSteps = append(workflowRunResults.SkippedSteps, stepResults)
			break
		case stepRunResultCodeSkippedWithRunIf:
			log.Warn("The step's (" + name + ") Run-If expression evaluated to false - skipping")
			workflowRunResults.SkippedSteps = append(workflowRunResults.SkippedSteps, stepResults)
			break
		default:
			log.Error("Unkown result code")
			return
		}

		if resultCode != stepRunResultCodeSuccess {
			if err := setBuildFailedEnv(true); err != nil {
				log.Error("Failed to set Build Status envs")
			}
		}

		printStepSummary(name, resultCode, time.Now().Sub(stepStartTime), exitCode)
	}

	for idx, stepListItm := range workflow.Steps {
		stepStartTime = time.Now()

		if err := setBuildFailedEnv(buildRunResults.IsBuildFailed()); err != nil {
			log.Error("Failed to set Build Status envs")
		}
		compositeStepIDStr, workflowStep, err := models.GetStepIDStepDataPair(stepListItm)
		if err != nil {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
			continue
		}
		stepIDData, err := models.CreateStepIDDataFromString(compositeStepIDStr, defaultStepLibSource)
		if err != nil {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
			continue
		}

		log.Debugf("[BITRISE_CLI] - Running Step: %#v", workflowStep)

		if err := cleanupStepWorkDir(); err != nil {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
			continue
		}

		stepDir := bitrise.BitriseWorkStepsDirPath
		stepYMLPth := bitrise.BitriseWorkDirPath + "/current_step.yml"

		if stepIDData.SteplibSource == "path" {
			log.Debugf("[BITRISE_CLI] - Local step found: (path:%s)", stepIDData.IDorURI)
			stepAbsLocalPth, err := pathutil.AbsPath(stepIDData.IDorURI)
			if err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}

			log.Debugln("stepAbsLocalPth:", stepAbsLocalPth, "|stepDir:", stepDir)
			if err := bitrise.RunCopyDir(stepAbsLocalPth, stepDir, true); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}
			if err := bitrise.RunCopyFile(stepAbsLocalPth+"/step.yml", stepYMLPth); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}
		} else if stepIDData.SteplibSource == "git" {
			log.Debugf("[BITRISE_CLI] - Remote step, with direct git uri: (uri:%s) (tag-or-branch:%s)", stepIDData.IDorURI, stepIDData.Version)
			if err := bitrise.RunGitClone(stepIDData.IDorURI, stepDir, stepIDData.Version); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}
			if err := bitrise.RunCopyFile(stepDir+"/step.yml", stepYMLPth); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}
		} else if stepIDData.SteplibSource != "" {
			log.Debugf("[BITRISE_CLI] - Steplib (%s) step (id:%s) (version:%s) found, activating step", stepIDData.SteplibSource, stepIDData.IDorURI, stepIDData.Version)
			if err := bitrise.RunStepmanSetup(stepIDData.SteplibSource); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			}

			if err := bitrise.RunStepmanActivate(stepIDData.SteplibSource, stepIDData.IDorURI, stepIDData.Version, stepDir, stepYMLPth); err != nil {
				registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
				continue
			} else {
				log.Debugf("[BITRISE_CLI] - Step activated: (ID:%s) (version:%s)", stepIDData.IDorURI, stepIDData.Version)
			}
		} else {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, fmt.Errorf("Invalid stepIDData: No SteplibSource or LocalPath defined (%v)", stepIDData))
			continue
		}

		specStep, err := bitrise.ReadSpecStep(stepYMLPth)
		log.Debugf("Spec read from YML: %#v\n", specStep)
		if err != nil {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
			continue
		}

		mergedStep, err := models.MergeStepWith(specStep, workflowStep)
		if err != nil {
			registerStepListItemRunResults(stepListItm, stepRunResultCodeFailed, 1, err)
			continue
		}

		printRunningStep(*mergedStep.Title, idx)
		if mergedStep.RunIf != nil && *mergedStep.RunIf != "" {
			isRun, err := bitrise.EvaluateStepTemplateToBool(*mergedStep.RunIf, workflowRunResults, IsCIMode)
			if err != nil {
				registerStepRunResults(mergedStep, stepRunResultCodeFailed, 1, err)
				continue
			}
			if !isRun {
				registerStepRunResults(mergedStep, stepRunResultCodeSkippedWithRunIf, 0, err)
				continue
			}
		}
		if workflowRunResults.IsBuildFailed() && !*mergedStep.IsAlwaysRun {
			registerStepRunResults(mergedStep, stepRunResultCodeSkipped, 0, err)
			continue
		} else {
			exit, err := runStep(mergedStep, stepIDData, stepDir)
			if err != nil {
				registerStepRunResults(mergedStep, stepRunResultCodeFailed, exit, err)
				continue
			} else {
				registerStepRunResults(mergedStep, stepRunResultCodeSuccess, 0, nil)
			}
		}
	}
	return workflowRunResults
}