You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	refactor(orchestrator): Use singleton in orchestrator package and rename methods (#4639)
* rename interface, types and methods. some type changes and refactor * update dependent methods and variables * fix unit tests * a bit more refactor and fix * concurrent safe singleton * return old Options struct * refactor creating config provider and fix nil pointer derefernce * fix unit test and linter errors * introduce resetting config provider (for unit tests) * fix annoying error message when config provider is not configured --------- Co-authored-by: Gulom Alimov <gulomjon.alimov@sap.com> Co-authored-by: Muhammadali Nazarov <muhammadalinazarov@gmail.com>
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -32,6 +32,7 @@ debug.test | ||||
| /piper_master.exe | ||||
| /jenkins-library | ||||
| /jenkins-library.exe | ||||
| node_modules/ | ||||
|  | ||||
| # piper binary outputs | ||||
| .pipeline/commonPipelineEnvironment/ | ||||
|   | ||||
| @@ -66,7 +66,7 @@ type artifactPrepareVersionUtils interface { | ||||
| 	FileRead(path string) ([]byte, error) | ||||
| 	FileRemove(path string) error | ||||
|  | ||||
| 	NewOrchestratorSpecificConfigProvider() (orchestrator.OrchestratorSpecificConfigProviding, error) | ||||
| 	GetConfigProvider() (orchestrator.ConfigProvider, error) | ||||
| } | ||||
|  | ||||
| type artifactPrepareVersionUtilsBundle struct { | ||||
| @@ -75,8 +75,8 @@ type artifactPrepareVersionUtilsBundle struct { | ||||
| 	*piperhttp.Client | ||||
| } | ||||
|  | ||||
| func (a *artifactPrepareVersionUtilsBundle) NewOrchestratorSpecificConfigProvider() (orchestrator.OrchestratorSpecificConfigProviding, error) { | ||||
| 	return orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| func (a *artifactPrepareVersionUtilsBundle) GetConfigProvider() (orchestrator.ConfigProvider, error) { | ||||
| 	return orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| } | ||||
|  | ||||
| func newArtifactPrepareVersionUtilsBundle() artifactPrepareVersionUtils { | ||||
| @@ -160,7 +160,7 @@ func runArtifactPrepareVersion(config *artifactPrepareVersionOptions, telemetryD | ||||
| 	if config.VersioningType == "cloud" || config.VersioningType == "cloud_noTag" { | ||||
| 		// make sure that versioning does not create tags (when set to "cloud") | ||||
| 		// for PR pipelines, optimized pipelines (= no build) | ||||
| 		provider, err := utils.NewOrchestratorSpecificConfigProvider() | ||||
| 		provider, err := utils.GetConfigProvider() | ||||
| 		if err != nil { | ||||
| 			log.Entry().WithError(err).Warning("Cannot infer config from CI environment") | ||||
| 		} | ||||
|   | ||||
| @@ -192,7 +192,7 @@ func (a *artifactPrepareVersionMockUtils) DownloadFile(url, filename string, hea | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (a *artifactPrepareVersionMockUtils) NewOrchestratorSpecificConfigProvider() (orchestrator.OrchestratorSpecificConfigProviding, error) { | ||||
| func (a *artifactPrepareVersionMockUtils) GetConfigProvider() (orchestrator.ConfigProvider, error) { | ||||
| 	return &orchestrator.UnknownOrchestratorConfigProvider{}, nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -130,20 +130,20 @@ func initGitInfo(config *codeqlExecuteScanOptions) (codeql.RepoInfo, error) { | ||||
| 	repoInfo.Ref = config.AnalyzedRef | ||||
| 	repoInfo.CommitId = config.CommitID | ||||
|  | ||||
| 	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().Warn("No orchestrator found. We assume piper is running locally.") | ||||
| 	} else { | ||||
| 		if repoInfo.Ref == "" { | ||||
| 			repoInfo.Ref = provider.GetReference() | ||||
| 			repoInfo.Ref = provider.GitReference() | ||||
| 		} | ||||
|  | ||||
| 		if repoInfo.CommitId == "" || repoInfo.CommitId == "NA" { | ||||
| 			repoInfo.CommitId = provider.GetCommit() | ||||
| 			repoInfo.CommitId = provider.CommitSHA() | ||||
| 		} | ||||
|  | ||||
| 		if repoInfo.ServerUrl == "" { | ||||
| 			err = getGitRepoInfo(provider.GetRepoURL(), &repoInfo) | ||||
| 			err = getGitRepoInfo(provider.RepoURL(), &repoInfo) | ||||
| 			if err != nil { | ||||
| 				log.Entry().Error(err) | ||||
| 			} | ||||
|   | ||||
| @@ -249,7 +249,7 @@ func TestInitGitInfo(t *testing.T) { | ||||
| 		config := codeqlExecuteScanOptions{Repository: "https://github.hello.test", AnalyzedRef: "refs/head/branch", CommitID: "abcd1234"} | ||||
| 		repoInfo, err := initGitInfo(&config) | ||||
| 		assert.NoError(t, err) | ||||
| 		_, err = orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 		_, err = orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 		assert.Equal(t, "abcd1234", repoInfo.CommitId) | ||||
| 		assert.Equal(t, "refs/head/branch", repoInfo.Ref) | ||||
| 		if err != nil { | ||||
|   | ||||
| @@ -42,14 +42,14 @@ func newCDUtils() credentialdiggerUtils { | ||||
| func credentialdiggerScan(config credentialdiggerScanOptions, telemetryData *telemetry.CustomData) error { | ||||
| 	utils := newCDUtils() | ||||
| 	// 0: Get attributes from orchestrator | ||||
| 	provider, prov_err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, prov_err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if prov_err != nil { | ||||
| 		log.Entry().WithError(prov_err).Error( | ||||
| 			"credentialdiggerScan: unable to load orchestrator specific configuration.") | ||||
| 	} | ||||
| 	if config.Repository == "" { | ||||
| 		// Get current repository from orchestrator | ||||
| 		repoUrlOrchestrator := provider.GetRepoURL() | ||||
| 		repoUrlOrchestrator := provider.RepoURL() | ||||
| 		if repoUrlOrchestrator == "n/a" { | ||||
| 			// Jenkins configuration error | ||||
| 			log.Entry().WithError(errors.New( | ||||
| @@ -61,7 +61,7 @@ func credentialdiggerScan(config credentialdiggerScanOptions, telemetryData *tel | ||||
| 	} | ||||
| 	if provider.IsPullRequest() { | ||||
| 		// set the pr number | ||||
| 		config.PrNumber, _ = strconv.Atoi(provider.GetPullRequestConfig().Key) | ||||
| 		config.PrNumber, _ = strconv.Atoi(provider.PullRequestConfig().Key) | ||||
| 		log.Entry().Debug("Scan the current pull request: number ", config.PrNumber) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -46,7 +46,7 @@ type detectUtils interface { | ||||
|  | ||||
| 	GetIssueService() *github.IssuesService | ||||
| 	GetSearchService() *github.SearchService | ||||
| 	GetProvider() orchestrator.OrchestratorSpecificConfigProviding | ||||
| 	GetProvider() orchestrator.ConfigProvider | ||||
| } | ||||
|  | ||||
| type detectUtilsBundle struct { | ||||
| @@ -55,7 +55,7 @@ type detectUtilsBundle struct { | ||||
| 	*piperhttp.Client | ||||
| 	issues   *github.IssuesService | ||||
| 	search   *github.SearchService | ||||
| 	provider orchestrator.OrchestratorSpecificConfigProviding | ||||
| 	provider orchestrator.ConfigProvider | ||||
| } | ||||
|  | ||||
| func (d *detectUtilsBundle) GetIssueService() *github.IssuesService { | ||||
| @@ -66,7 +66,7 @@ func (d *detectUtilsBundle) GetSearchService() *github.SearchService { | ||||
| 	return d.search | ||||
| } | ||||
|  | ||||
| func (d *detectUtilsBundle) GetProvider() orchestrator.OrchestratorSpecificConfigProviding { | ||||
| func (d *detectUtilsBundle) GetProvider() orchestrator.ConfigProvider { | ||||
| 	return d.provider | ||||
| } | ||||
|  | ||||
| @@ -112,7 +112,7 @@ func newDetectUtils(client *github.Client) detectUtils { | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
|  | ||||
| 	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Warning(err) | ||||
| 		provider = &orchestrator.UnknownOrchestratorConfigProvider{} | ||||
| @@ -568,9 +568,9 @@ func isMajorVulnerability(v bd.Vulnerability) bool { | ||||
| } | ||||
|  | ||||
| func postScanChecksAndReporting(ctx context.Context, config detectExecuteScanOptions, influx *detectExecuteScanInflux, utils detectUtils, sys *blackduckSystem) error { | ||||
|  | ||||
| 	if utils.GetProvider().IsPullRequest() { | ||||
| 		issueNumber, err := strconv.Atoi(utils.GetProvider().GetPullRequestConfig().Key) | ||||
| 	provider := utils.GetProvider() | ||||
| 	if provider.IsPullRequest() { | ||||
| 		issueNumber, err := strconv.Atoi(provider.PullRequestConfig().Key) | ||||
| 		if err != nil { | ||||
| 			log.Entry().Warning("Can not get issue number ", err) | ||||
| 			return nil | ||||
|   | ||||
| @@ -33,7 +33,7 @@ type detectTestUtilsBundle struct { | ||||
| 	orchestrator *orchestratorConfigProviderMock | ||||
| } | ||||
|  | ||||
| func (d *detectTestUtilsBundle) GetProvider() orchestrator.OrchestratorSpecificConfigProviding { | ||||
| func (d *detectTestUtilsBundle) GetProvider() orchestrator.ConfigProvider { | ||||
| 	return d.orchestrator | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										11
									
								
								cmd/piper.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								cmd/piper.go
									
									
									
									
									
								
							| @@ -212,16 +212,13 @@ func Execute() { | ||||
| } | ||||
|  | ||||
| func addRootFlags(rootCmd *cobra.Command) { | ||||
| 	var provider orchestrator.OrchestratorSpecificConfigProviding | ||||
| 	var err error | ||||
|  | ||||
| 	provider, err = orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().Error(err) | ||||
| 		provider = &orchestrator.UnknownOrchestratorConfigProvider{} | ||||
| 	} | ||||
|  | ||||
| 	rootCmd.PersistentFlags().StringVar(&GeneralConfig.CorrelationID, "correlationID", provider.GetBuildURL(), "ID for unique identification of a pipeline run") | ||||
| 	rootCmd.PersistentFlags().StringVar(&GeneralConfig.CorrelationID, "correlationID", provider.BuildURL(), "ID for unique identification of a pipeline run") | ||||
| 	rootCmd.PersistentFlags().StringVar(&GeneralConfig.CustomConfig, "customConfig", ".pipeline/config.yml", "Path to the pipeline configuration file") | ||||
| 	rootCmd.PersistentFlags().StringSliceVar(&GeneralConfig.GitHubTokens, "gitHubTokens", AccessTokensFromEnvJSON(os.Getenv("PIPER_gitHubTokens")), "List of entries in form of <hostname>:<token> to allow GitHub token authentication for downloading config / defaults") | ||||
| 	rootCmd.PersistentFlags().StringSliceVar(&GeneralConfig.DefaultConfig, "defaultConfig", []string{".pipeline/defaults.yaml"}, "Default configurations, passed as path to yaml file") | ||||
| @@ -290,12 +287,12 @@ func initStageName(outputToLog bool) { | ||||
| 	} | ||||
|  | ||||
| 	// Use stageName from ENV as fall-back, for when extracting it from parametersJSON fails below | ||||
| 	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Warning("Cannot infer stage name from CI environment") | ||||
| 	} else { | ||||
| 		stageNameSource = "env variable" | ||||
| 		GeneralConfig.StageName = provider.GetStageName() | ||||
| 		GeneralConfig.StageName = provider.StageName() | ||||
| 	} | ||||
|  | ||||
| 	if len(GeneralConfig.ParametersJSON) == 0 { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/orchestrator" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -62,6 +63,7 @@ func TestAdoptStageNameFromParametersJSON(t *testing.T) { | ||||
| 			// init | ||||
| 			defer resetEnv(os.Environ()) | ||||
| 			os.Clearenv() | ||||
| 			orchestrator.ResetConfigProvider() | ||||
|  | ||||
| 			//mock Jenkins env | ||||
| 			os.Setenv("JENKINS_HOME", "anything") | ||||
|   | ||||
| @@ -477,14 +477,14 @@ func getTempDir() string { | ||||
|  | ||||
| // Fetches parameters from environment variables and updates the options accordingly (only if not already set) | ||||
| func detectParametersFromCI(options *sonarExecuteScanOptions) { | ||||
| 	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Warning("Cannot infer config from CI environment") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if provider.IsPullRequest() { | ||||
| 		config := provider.GetPullRequestConfig() | ||||
| 		config := provider.PullRequestConfig() | ||||
| 		if len(options.ChangeBranch) == 0 { | ||||
| 			log.Entry().Info("Inferring parameter changeBranch from environment: " + config.Branch) | ||||
| 			options.ChangeBranch = config.Branch | ||||
| @@ -498,7 +498,7 @@ func detectParametersFromCI(options *sonarExecuteScanOptions) { | ||||
| 			options.ChangeID = config.Key | ||||
| 		} | ||||
| 	} else { | ||||
| 		branch := provider.GetBranch() | ||||
| 		branch := provider.Branch() | ||||
| 		if options.InferBranchName && len(options.BranchName) == 0 { | ||||
| 			log.Entry().Info("Inferring parameter branchName from environment: " + branch) | ||||
| 			options.BranchName = branch | ||||
|   | ||||
| @@ -11,24 +11,30 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| ) | ||||
| 
 | ||||
| type AzureDevOpsConfigProvider struct { | ||||
| type azureDevopsConfigProvider struct { | ||||
| 	client         piperHttp.Client | ||||
| 	apiInformation map[string]interface{} | ||||
| } | ||||
| 
 | ||||
| // InitOrchestratorProvider initializes http client for AzureDevopsConfigProvider | ||||
| func (a *AzureDevOpsConfigProvider) InitOrchestratorProvider(settings *OrchestratorSettings) { | ||||
| func newAzureDevopsConfigProvider() *azureDevopsConfigProvider { | ||||
| 	return &azureDevopsConfigProvider{} | ||||
| } | ||||
| 
 | ||||
| // Configure initializes http client for AzureDevopsConfigProvider | ||||
| func (a *azureDevopsConfigProvider) Configure(opts *Options) error { | ||||
| 	a.client.SetOptions(piperHttp.ClientOptions{ | ||||
| 		Username:         "", | ||||
| 		Password:         settings.AzureToken, | ||||
| 		Password:         opts.AzureToken, | ||||
| 		MaxRetries:       3, | ||||
| 		TransportTimeout: time.Second * 10, | ||||
| 	}) | ||||
| 
 | ||||
| 	log.Entry().Debug("Successfully initialized Azure config provider") | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // fetchAPIInformation fetches Azure API information of current build | ||||
| func (a *AzureDevOpsConfigProvider) fetchAPIInformation() { | ||||
| func (a *azureDevopsConfigProvider) fetchAPIInformation() { | ||||
| 	// if apiInformation is empty fill it otherwise do nothing | ||||
| 	if len(a.apiInformation) == 0 { | ||||
| 		log.Entry().Debugf("apiInformation is empty, getting infos from API") | ||||
| @@ -57,45 +63,45 @@ func (a *AzureDevOpsConfigProvider) fetchAPIInformation() { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (a *AzureDevOpsConfigProvider) GetChangeSet() []ChangeSet { | ||||
| 	log.Entry().Warn("GetChangeSet for AzureDevOps not yet implemented") | ||||
| func (a *azureDevopsConfigProvider) ChangeSets() []ChangeSet { | ||||
| 	log.Entry().Warn("ChangeSets for AzureDevOps not yet implemented") | ||||
| 	return []ChangeSet{} | ||||
| } | ||||
| 
 | ||||
| // getSystemCollectionURI returns the URI of the TFS collection or Azure DevOps organization e.g. https://dev.azure.com/fabrikamfiber/ | ||||
| func (a *AzureDevOpsConfigProvider) getSystemCollectionURI() string { | ||||
| func (a *azureDevopsConfigProvider) getSystemCollectionURI() string { | ||||
| 	return getEnv("SYSTEM_COLLECTIONURI", "n/a") | ||||
| } | ||||
| 
 | ||||
| // getTeamProjectID is the name of the project that contains this build e.g. 123a4567-ab1c-12a1-1234-123456ab7890 | ||||
| func (a *AzureDevOpsConfigProvider) getTeamProjectID() string { | ||||
| func (a *azureDevopsConfigProvider) getTeamProjectID() string { | ||||
| 	return getEnv("SYSTEM_TEAMPROJECTID", "n/a") | ||||
| } | ||||
| 
 | ||||
| // getAzureBuildID returns the id of the build, e.g. 1234 | ||||
| func (a *AzureDevOpsConfigProvider) getAzureBuildID() string { | ||||
| func (a *azureDevopsConfigProvider) getAzureBuildID() string { | ||||
| 	// INFO: Private function only used for API requests, buildId for e.g. reporting | ||||
| 	// is GetBuildNumber to align with the UI of ADO | ||||
| 	return getEnv("BUILD_BUILDID", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetJobName returns the pipeline job name, currently org/repo | ||||
| func (a *AzureDevOpsConfigProvider) GetJobName() string { | ||||
| // JobName returns the pipeline job name, currently org/repo | ||||
| func (a *azureDevopsConfigProvider) JobName() string { | ||||
| 	return getEnv("BUILD_REPOSITORY_NAME", "n/a") | ||||
| } | ||||
| 
 | ||||
| // OrchestratorVersion returns the agent version on ADO | ||||
| func (a *AzureDevOpsConfigProvider) OrchestratorVersion() string { | ||||
| func (a *azureDevopsConfigProvider) OrchestratorVersion() string { | ||||
| 	return getEnv("AGENT_VERSION", "n/a") | ||||
| } | ||||
| 
 | ||||
| // OrchestratorType returns the orchestrator name e.g. Azure/GitHubActions/Jenkins | ||||
| func (a *AzureDevOpsConfigProvider) OrchestratorType() string { | ||||
| func (a *azureDevopsConfigProvider) OrchestratorType() string { | ||||
| 	return "Azure" | ||||
| } | ||||
| 
 | ||||
| // GetBuildStatus returns status of the build. Return variables are aligned with Jenkins build statuses. | ||||
| func (a *AzureDevOpsConfigProvider) GetBuildStatus() string { | ||||
| // BuildStatus returns status of the build. Return variables are aligned with Jenkins build statuses. | ||||
| func (a *azureDevopsConfigProvider) BuildStatus() string { | ||||
| 	// cases to align with Jenkins: SUCCESS, FAILURE, NOT_BUILD, ABORTED | ||||
| 	switch buildStatus := getEnv("AGENT_JOBSTATUS", "FAILURE"); buildStatus { | ||||
| 	case "Succeeded": | ||||
| @@ -108,8 +114,8 @@ func (a *AzureDevOpsConfigProvider) GetBuildStatus() string { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetLog returns the whole logfile for the current pipeline run | ||||
| func (a *AzureDevOpsConfigProvider) GetLog() ([]byte, error) { | ||||
| // FullLogs returns the whole logfile for the current pipeline run | ||||
| func (a *azureDevopsConfigProvider) FullLogs() ([]byte, error) { | ||||
| 	URL := a.getSystemCollectionURI() + a.getTeamProjectID() + "/_apis/build/builds/" + a.getAzureBuildID() + "/logs" | ||||
| 
 | ||||
| 	response, err := a.client.GetRequest(URL, nil, nil) | ||||
| @@ -161,8 +167,8 @@ func (a *AzureDevOpsConfigProvider) GetLog() ([]byte, error) { | ||||
| 	return logs, nil | ||||
| } | ||||
| 
 | ||||
| // GetPipelineStartTime returns the pipeline start time in UTC | ||||
| func (a *AzureDevOpsConfigProvider) GetPipelineStartTime() time.Time { | ||||
| // PipelineStartTime returns the pipeline start time in UTC | ||||
| func (a *azureDevopsConfigProvider) PipelineStartTime() time.Time { | ||||
| 	//"2022-03-18T07:30:31.1915758Z" | ||||
| 	a.fetchAPIInformation() | ||||
| 	if val, ok := a.apiInformation["startTime"]; ok { | ||||
| @@ -176,59 +182,59 @@ func (a *AzureDevOpsConfigProvider) GetPipelineStartTime() time.Time { | ||||
| 	return time.Time{}.UTC() | ||||
| } | ||||
| 
 | ||||
| // GetBuildID returns the BuildNumber displayed in the ADO UI | ||||
| func (a *AzureDevOpsConfigProvider) GetBuildID() string { | ||||
| // BuildID returns the BuildNumber displayed in the ADO UI | ||||
| func (a *azureDevopsConfigProvider) BuildID() string { | ||||
| 	// INFO: ADO has BUILD_ID and buildNumber, as buildNumber is used in the UI we return this value | ||||
| 	// for the buildID used only for API requests we have a private method getAzureBuildID | ||||
| 	// example: buildNumber: 20220318.16 buildId: 76443 | ||||
| 	return getEnv("BUILD_BUILDNUMBER", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetStageName returns the human-readable name given to a stage. e.g. "Promote" or "Init" | ||||
| func (a *AzureDevOpsConfigProvider) GetStageName() string { | ||||
| // StageName returns the human-readable name given to a stage. e.g. "Promote" or "Init" | ||||
| func (a *azureDevopsConfigProvider) StageName() string { | ||||
| 	return getEnv("SYSTEM_STAGEDISPLAYNAME", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetBranch returns the source branch name, e.g. main | ||||
| func (a *AzureDevOpsConfigProvider) GetBranch() string { | ||||
| // Branch returns the source branch name, e.g. main | ||||
| func (a *azureDevopsConfigProvider) Branch() string { | ||||
| 	tmp := getEnv("BUILD_SOURCEBRANCH", "n/a") | ||||
| 	return strings.TrimPrefix(tmp, "refs/heads/") | ||||
| } | ||||
| 
 | ||||
| // GetReference return the git reference | ||||
| func (a *AzureDevOpsConfigProvider) GetReference() string { | ||||
| // GitReference return the git reference | ||||
| func (a *azureDevopsConfigProvider) GitReference() string { | ||||
| 	return getEnv("BUILD_SOURCEBRANCH", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetBuildURL returns the builds URL e.g. https://dev.azure.com/fabrikamfiber/your-repo-name/_build/results?buildId=1234 | ||||
| func (a *AzureDevOpsConfigProvider) GetBuildURL() string { | ||||
| // BuildURL returns the builds URL e.g. https://dev.azure.com/fabrikamfiber/your-repo-name/_build/results?buildId=1234 | ||||
| func (a *azureDevopsConfigProvider) BuildURL() string { | ||||
| 	return os.Getenv("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI") + os.Getenv("SYSTEM_TEAMPROJECT") + "/" + os.Getenv("SYSTEM_DEFINITIONNAME") + "/_build/results?buildId=" + a.getAzureBuildID() | ||||
| } | ||||
| 
 | ||||
| // GetJobURL returns tje current job url e.g. https://dev.azure.com/fabrikamfiber/your-repo-name/_build?definitionId=1234 | ||||
| func (a *AzureDevOpsConfigProvider) GetJobURL() string { | ||||
| // JobURL returns tje current job url e.g. https://dev.azure.com/fabrikamfiber/your-repo-name/_build?definitionId=1234 | ||||
| func (a *azureDevopsConfigProvider) JobURL() string { | ||||
| 	// TODO: Check if this is the correct URL | ||||
| 	return os.Getenv("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI") + os.Getenv("SYSTEM_TEAMPROJECT") + "/" + os.Getenv("SYSTEM_DEFINITIONNAME") + "/_build?definitionId=" + os.Getenv("SYSTEM_DEFINITIONID") | ||||
| } | ||||
| 
 | ||||
| // GetCommit returns commit SHA of current build | ||||
| func (a *AzureDevOpsConfigProvider) GetCommit() string { | ||||
| // CommitSHA returns commit SHA of current build | ||||
| func (a *azureDevopsConfigProvider) CommitSHA() string { | ||||
| 	return getEnv("BUILD_SOURCEVERSION", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetRepoURL returns current repo URL e.g. https://github.com/SAP/jenkins-library | ||||
| func (a *AzureDevOpsConfigProvider) GetRepoURL() string { | ||||
| // RepoURL returns current repo URL e.g. https://github.com/SAP/jenkins-library | ||||
| func (a *azureDevopsConfigProvider) RepoURL() string { | ||||
| 	return getEnv("BUILD_REPOSITORY_URI", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetBuildReason returns the build reason | ||||
| func (a *AzureDevOpsConfigProvider) GetBuildReason() string { | ||||
| // BuildReason returns the build reason | ||||
| func (a *azureDevopsConfigProvider) BuildReason() string { | ||||
| 	// https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services | ||||
| 	return getEnv("BUILD_REASON", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetPullRequestConfig returns pull request configuration | ||||
| func (a *AzureDevOpsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| // PullRequestConfig returns pull request configuration | ||||
| func (a *azureDevopsConfigProvider) PullRequestConfig() PullRequestConfig { | ||||
| 	prKey := getEnv("SYSTEM_PULLREQUEST_PULLREQUESTID", "n/a") | ||||
| 
 | ||||
| 	// This variable is populated for pull requests which have a different pull request ID and pull request number. | ||||
| @@ -247,11 +253,11 @@ func (a *AzureDevOpsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| } | ||||
| 
 | ||||
| // IsPullRequest indicates whether the current build is a PR | ||||
| func (a *AzureDevOpsConfigProvider) IsPullRequest() bool { | ||||
| func (a *azureDevopsConfigProvider) IsPullRequest() bool { | ||||
| 	return getEnv("BUILD_REASON", "n/a") == "PullRequest" | ||||
| } | ||||
| 
 | ||||
| func isAzure() bool { | ||||
| 	envVars := []string{"AZURE_HTTP_USER_AGENT"} | ||||
| 	return areIndicatingEnvVarsSet(envVars) | ||||
| 	return envVarsAreSet(envVars) | ||||
| } | ||||
| @@ -30,16 +30,16 @@ func TestAzure(t *testing.T) { | ||||
| 		os.Setenv("BUILD_REPOSITORY_URI", "github.com/foo/bar") | ||||
| 		os.Setenv("SYSTEM_DEFINITIONNAME", "bar") | ||||
| 		os.Setenv("SYSTEM_DEFINITIONID", "1234") | ||||
| 		p, _ := NewOrchestratorSpecificConfigProvider() | ||||
| 		p, _ := GetOrchestratorConfigProvider(nil) | ||||
| 
 | ||||
| 		assert.False(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "feat/test-azure", p.GetBranch()) | ||||
| 		assert.Equal(t, "refs/heads/feat/test-azure", p.GetReference()) | ||||
| 		assert.Equal(t, "https://pogo.sap/foo/bar/_build/results?buildId=42", p.GetBuildURL()) | ||||
| 		assert.Equal(t, "abcdef42713", p.GetCommit()) | ||||
| 		assert.Equal(t, "github.com/foo/bar", p.GetRepoURL()) | ||||
| 		assert.Equal(t, "feat/test-azure", p.Branch()) | ||||
| 		assert.Equal(t, "refs/heads/feat/test-azure", p.GitReference()) | ||||
| 		assert.Equal(t, "https://pogo.sap/foo/bar/_build/results?buildId=42", p.BuildURL()) | ||||
| 		assert.Equal(t, "abcdef42713", p.CommitSHA()) | ||||
| 		assert.Equal(t, "github.com/foo/bar", p.RepoURL()) | ||||
| 		assert.Equal(t, "Azure", p.OrchestratorType()) | ||||
| 		assert.Equal(t, "https://pogo.sap/foo/bar/_build?definitionId=1234", p.GetJobURL()) | ||||
| 		assert.Equal(t, "https://pogo.sap/foo/bar/_build?definitionId=1234", p.JobURL()) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("PR", func(t *testing.T) { | ||||
| @@ -50,8 +50,8 @@ func TestAzure(t *testing.T) { | ||||
| 		os.Setenv("SYSTEM_PULLREQUEST_PULLREQUESTID", "42") | ||||
| 		os.Setenv("BUILD_REASON", "PullRequest") | ||||
| 
 | ||||
| 		p := AzureDevOpsConfigProvider{} | ||||
| 		c := p.GetPullRequestConfig() | ||||
| 		p := azureDevopsConfigProvider{} | ||||
| 		c := p.PullRequestConfig() | ||||
| 
 | ||||
| 		assert.True(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "feat/test-azure", c.Branch) | ||||
| @@ -68,8 +68,8 @@ func TestAzure(t *testing.T) { | ||||
| 		os.Setenv("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER", "42") | ||||
| 		os.Setenv("BUILD_REASON", "PullRequest") | ||||
| 
 | ||||
| 		p := AzureDevOpsConfigProvider{} | ||||
| 		c := p.GetPullRequestConfig() | ||||
| 		p := azureDevopsConfigProvider{} | ||||
| 		c := p.PullRequestConfig() | ||||
| 
 | ||||
| 		assert.True(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "feat/test-azure", c.Branch) | ||||
| @@ -98,14 +98,14 @@ func TestAzure(t *testing.T) { | ||||
| 		os.Setenv("BUILD_BUILDNUMBER", "20220318.16") | ||||
| 		os.Setenv("BUILD_REPOSITORY_NAME", "repo-org/repo-name") | ||||
| 
 | ||||
| 		p := AzureDevOpsConfigProvider{} | ||||
| 		p := azureDevopsConfigProvider{} | ||||
| 
 | ||||
| 		assert.Equal(t, "https://dev.azure.com/fabrikamfiber/", p.getSystemCollectionURI()) | ||||
| 		assert.Equal(t, "123a4567-ab1c-12a1-1234-123456ab7890", p.getTeamProjectID()) | ||||
| 		assert.Equal(t, "42", p.getAzureBuildID())     // Don't confuse getAzureBuildID and GetBuildID! | ||||
| 		assert.Equal(t, "20220318.16", p.GetBuildID()) // buildNumber is used in the UI | ||||
| 		assert.Equal(t, "42", p.getAzureBuildID())  // Don't confuse getAzureBuildID and provider.BuildID! | ||||
| 		assert.Equal(t, "20220318.16", p.BuildID()) // buildNumber is used in the UI | ||||
| 		assert.Equal(t, "2.193.0", p.OrchestratorVersion()) | ||||
| 		assert.Equal(t, "repo-org/repo-name", p.GetJobName()) | ||||
| 		assert.Equal(t, "repo-org/repo-name", p.JobName()) | ||||
| 
 | ||||
| 	}) | ||||
| } | ||||
| @@ -140,10 +140,10 @@ func TestAzureDevOpsConfigProvider_GetPipelineStartTime(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			a := &AzureDevOpsConfigProvider{} | ||||
| 			a := &azureDevopsConfigProvider{} | ||||
| 			a.apiInformation = tt.apiInformation | ||||
| 			pipelineStartTime := a.GetPipelineStartTime() | ||||
| 			assert.Equalf(t, tt.want, pipelineStartTime, "GetPipelineStartTime()") | ||||
| 			pipelineStartTime := a.PipelineStartTime() | ||||
| 			assert.Equalf(t, tt.want, pipelineStartTime, "PipelineStartTime()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -181,9 +181,9 @@ func TestAzureDevOpsConfigProvider_GetBuildStatus(t *testing.T) { | ||||
| 			defer resetEnv(os.Environ()) | ||||
| 			os.Clearenv() | ||||
| 			os.Setenv("AGENT_JOBSTATUS", tt.envVar) | ||||
| 			a := &AzureDevOpsConfigProvider{} | ||||
| 			a := &azureDevopsConfigProvider{} | ||||
| 
 | ||||
| 			assert.Equalf(t, tt.want, a.GetBuildStatus(), "GetBuildStatus()") | ||||
| 			assert.Equalf(t, tt.want, a.BuildStatus(), "BuildStatus()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -229,7 +229,7 @@ func TestAzureDevOpsConfigProvider_getAPIInformation(t *testing.T) { | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			a := &AzureDevOpsConfigProvider{ | ||||
| 			a := &azureDevopsConfigProvider{ | ||||
| 				apiInformation: tt.apiInformation, | ||||
| 			} | ||||
| 
 | ||||
| @@ -311,7 +311,7 @@ func TestAzureDevOpsConfigProvider_GetLog(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			a := &AzureDevOpsConfigProvider{} | ||||
| 			a := &azureDevopsConfigProvider{} | ||||
| 			a.client.SetOptions(piperhttp.ClientOptions{ | ||||
| 				MaxRequestDuration:        5 * time.Second, | ||||
| 				Token:                     "TOKEN", | ||||
| @@ -355,11 +355,11 @@ func TestAzureDevOpsConfigProvider_GetLog(t *testing.T) { | ||||
| 					}) | ||||
| 				}, | ||||
| 			) | ||||
| 			got, err := a.GetLog() | ||||
| 			if !tt.wantErr(t, err, fmt.Sprintf("GetLog()")) { | ||||
| 			got, err := a.FullLogs() | ||||
| 			if !tt.wantErr(t, err, fmt.Sprintf("FullLogs()")) { | ||||
| 				return | ||||
| 			} | ||||
| 			assert.Equalf(t, tt.want, got, "GetLog()") | ||||
| 			assert.Equalf(t, tt.want, got, "FullLogs()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -19,7 +19,7 @@ import ( | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| ) | ||||
| 
 | ||||
| type GitHubActionsConfigProvider struct { | ||||
| type githubActionsConfigProvider struct { | ||||
| 	client      *github.Client | ||||
| 	ctx         context.Context | ||||
| 	owner       string | ||||
| @@ -46,31 +46,37 @@ type fullLog struct { | ||||
| 	b [][]byte | ||||
| } | ||||
| 
 | ||||
| // InitOrchestratorProvider initializes http client for GitHubActionsDevopsConfigProvider | ||||
| func (g *GitHubActionsConfigProvider) InitOrchestratorProvider(settings *OrchestratorSettings) { | ||||
| 	var err error | ||||
| 	g.ctx, g.client, err = piperGithub.NewClientBuilder(settings.GitHubToken, getEnv("GITHUB_API_URL", "")).Build() | ||||
| 	if err != nil { | ||||
| 		log.Entry().Errorf("failed to create github client: %v", err) | ||||
| 		return | ||||
| func newGithubActionsConfigProvider() *githubActionsConfigProvider { | ||||
| 	owner, repo := getOwnerAndRepoNames() | ||||
| 	return &githubActionsConfigProvider{ | ||||
| 		owner: owner, | ||||
| 		repo:  repo, | ||||
| 	} | ||||
| 
 | ||||
| 	g.owner, g.repo = getOwnerAndRepoNames() | ||||
| 
 | ||||
| 	log.Entry().Debug("Successfully initialized GitHubActions config provider") | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) OrchestratorVersion() string { | ||||
| // Configure initializes http client for GitHubActionsDevopsConfigProvider | ||||
| func (g *githubActionsConfigProvider) Configure(opts *Options) error { | ||||
| 	var err error | ||||
| 	g.ctx, g.client, err = piperGithub.NewClientBuilder(opts.GitHubToken, getEnv("GITHUB_API_URL", "")).Build() | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "failed to create github client") | ||||
| 	} | ||||
| 
 | ||||
| 	log.Entry().Debug("Successfully initialized GitHubActions config provider") | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (g *githubActionsConfigProvider) OrchestratorVersion() string { | ||||
| 	log.Entry().Debugf("OrchestratorVersion() for GitHub Actions is not applicable.") | ||||
| 	return "n/a" | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) OrchestratorType() string { | ||||
| func (g *githubActionsConfigProvider) OrchestratorType() string { | ||||
| 	return "GitHubActions" | ||||
| } | ||||
| 
 | ||||
| // GetBuildStatus returns current run status | ||||
| func (g *GitHubActionsConfigProvider) GetBuildStatus() string { | ||||
| // BuildStatus returns current run status | ||||
| func (g *githubActionsConfigProvider) BuildStatus() string { | ||||
| 	g.fetchRunData() | ||||
| 	switch g.runData.Status { | ||||
| 	case "success": | ||||
| @@ -84,8 +90,13 @@ func (g *GitHubActionsConfigProvider) GetBuildStatus() string { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetLog returns the whole logfile for the current pipeline run | ||||
| func (g *GitHubActionsConfigProvider) GetLog() ([]byte, error) { | ||||
| // FullLogs returns the whole logfile for the current pipeline run | ||||
| func (g *githubActionsConfigProvider) FullLogs() ([]byte, error) { | ||||
| 	if g.client == nil { | ||||
| 		log.Entry().Debug("ConfigProvider for GitHub Actions is not configured. Unable to fetch logs") | ||||
| 		return []byte{}, nil | ||||
| 	} | ||||
| 
 | ||||
| 	if err := g.fetchJobs(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -129,31 +140,31 @@ func (g *GitHubActionsConfigProvider) GetLog() ([]byte, error) { | ||||
| 	return bytes.Join(fullLogs.b, []byte("")), nil | ||||
| } | ||||
| 
 | ||||
| // GetBuildID returns current run ID | ||||
| func (g *GitHubActionsConfigProvider) GetBuildID() string { | ||||
| // BuildID returns current run ID | ||||
| func (g *githubActionsConfigProvider) BuildID() string { | ||||
| 	return getEnv("GITHUB_RUN_ID", "n/a") | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) GetChangeSet() []ChangeSet { | ||||
| 	log.Entry().Debug("GetChangeSet for GitHubActions not implemented") | ||||
| func (g *githubActionsConfigProvider) ChangeSets() []ChangeSet { | ||||
| 	log.Entry().Debug("ChangeSets for GitHubActions not implemented") | ||||
| 	return []ChangeSet{} | ||||
| } | ||||
| 
 | ||||
| // GetPipelineStartTime returns the pipeline start time in UTC | ||||
| func (g *GitHubActionsConfigProvider) GetPipelineStartTime() time.Time { | ||||
| // PipelineStartTime returns the pipeline start time in UTC | ||||
| func (g *githubActionsConfigProvider) PipelineStartTime() time.Time { | ||||
| 	g.fetchRunData() | ||||
| 	return g.runData.StartedAt.UTC() | ||||
| } | ||||
| 
 | ||||
| // GetStageName returns the human-readable name given to a stage. | ||||
| func (g *GitHubActionsConfigProvider) GetStageName() string { | ||||
| // StageName returns the human-readable name given to a stage. | ||||
| func (g *githubActionsConfigProvider) StageName() string { | ||||
| 	return getEnv("GITHUB_JOB", "unknown") | ||||
| } | ||||
| 
 | ||||
| // GetBuildReason returns the reason of workflow trigger. | ||||
| // BuildReason returns the reason of workflow trigger. | ||||
| // BuildReasons are unified with AzureDevOps build reasons, see | ||||
| // https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services | ||||
| func (g *GitHubActionsConfigProvider) GetBuildReason() string { | ||||
| func (g *githubActionsConfigProvider) BuildReason() string { | ||||
| 	switch getEnv("GITHUB_EVENT_NAME", "") { | ||||
| 	case "workflow_dispatch": | ||||
| 		return BuildReasonManual | ||||
| @@ -170,50 +181,50 @@ func (g *GitHubActionsConfigProvider) GetBuildReason() string { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetBranch returns the source branch name, e.g. main | ||||
| func (g *GitHubActionsConfigProvider) GetBranch() string { | ||||
| // Branch returns the source branch name, e.g. main | ||||
| func (g *githubActionsConfigProvider) Branch() string { | ||||
| 	return getEnv("GITHUB_REF_NAME", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetReference return the git reference. For example, refs/heads/your_branch_name | ||||
| func (g *GitHubActionsConfigProvider) GetReference() string { | ||||
| // GitReference return the git reference. For example, refs/heads/your_branch_name | ||||
| func (g *githubActionsConfigProvider) GitReference() string { | ||||
| 	return getEnv("GITHUB_REF", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetBuildURL returns the builds URL. The URL should point to the pipeline (not to the stage) | ||||
| // BuildURL returns the builds URL. The URL should point to the pipeline (not to the stage) | ||||
| // that is currently being executed. For example, https://github.com/SAP/jenkins-library/actions/runs/5815297487 | ||||
| func (g *GitHubActionsConfigProvider) GetBuildURL() string { | ||||
| 	return g.GetRepoURL() + "/actions/runs/" + g.GetBuildID() | ||||
| func (g *githubActionsConfigProvider) BuildURL() string { | ||||
| 	return g.RepoURL() + "/actions/runs/" + g.BuildID() | ||||
| } | ||||
| 
 | ||||
| // GetJobURL returns the job URL. The URL should point to project’s pipelines. | ||||
| // JobURL returns the job URL. The URL should point to project’s pipelines. | ||||
| // For example, https://github.com/SAP/jenkins-library/actions/workflows/workflow-file-name.yaml | ||||
| func (g *GitHubActionsConfigProvider) GetJobURL() string { | ||||
| func (g *githubActionsConfigProvider) JobURL() string { | ||||
| 	fileName := workflowFileName() | ||||
| 	if fileName == "" { | ||||
| 		return "" | ||||
| 	} | ||||
| 
 | ||||
| 	return g.GetRepoURL() + "/actions/workflows/" + fileName | ||||
| 	return g.RepoURL() + "/actions/workflows/" + fileName | ||||
| } | ||||
| 
 | ||||
| // GetJobName returns the current workflow name. For example, "Piper workflow" | ||||
| func (g *GitHubActionsConfigProvider) GetJobName() string { | ||||
| // JobName returns the current workflow name. For example, "Piper workflow" | ||||
| func (g *githubActionsConfigProvider) JobName() string { | ||||
| 	return getEnv("GITHUB_WORKFLOW", "unknown") | ||||
| } | ||||
| 
 | ||||
| // GetCommit returns the commit SHA that triggered the workflow. For example, ffac537e6cbbf934b08745a378932722df287a53 | ||||
| func (g *GitHubActionsConfigProvider) GetCommit() string { | ||||
| // CommitSHA returns the commit SHA that triggered the workflow. For example, ffac537e6cbbf934b08745a378932722df287a53 | ||||
| func (g *githubActionsConfigProvider) CommitSHA() string { | ||||
| 	return getEnv("GITHUB_SHA", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetRepoURL returns full url to repository. For example, https://github.com/SAP/jenkins-library | ||||
| func (g *GitHubActionsConfigProvider) GetRepoURL() string { | ||||
| // RepoURL returns full url to repository. For example, https://github.com/SAP/jenkins-library | ||||
| func (g *githubActionsConfigProvider) RepoURL() string { | ||||
| 	return getEnv("GITHUB_SERVER_URL", "n/a") + "/" + getEnv("GITHUB_REPOSITORY", "n/a") | ||||
| } | ||||
| 
 | ||||
| // GetPullRequestConfig returns pull request configuration | ||||
| func (g *GitHubActionsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| // PullRequestConfig returns pull request configuration | ||||
| func (g *githubActionsConfigProvider) PullRequestConfig() PullRequestConfig { | ||||
| 	// See https://docs.github.com/en/enterprise-server@3.6/actions/learn-github-actions/variables#default-environment-variables | ||||
| 	githubRef := getEnv("GITHUB_REF", "n/a") | ||||
| 	prNumber := strings.TrimSuffix(strings.TrimPrefix(githubRef, "refs/pull/"), "/merge") | ||||
| @@ -225,13 +236,13 @@ func (g *GitHubActionsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| } | ||||
| 
 | ||||
| // IsPullRequest indicates whether the current build is triggered by a PR | ||||
| func (g *GitHubActionsConfigProvider) IsPullRequest() bool { | ||||
| 	return truthy("GITHUB_HEAD_REF") | ||||
| func (g *githubActionsConfigProvider) IsPullRequest() bool { | ||||
| 	return envVarIsTrue("GITHUB_HEAD_REF") | ||||
| } | ||||
| 
 | ||||
| func isGitHubActions() bool { | ||||
| 	envVars := []string{"GITHUB_ACTION", "GITHUB_ACTIONS"} | ||||
| 	return areIndicatingEnvVarsSet(envVars) | ||||
| 	return envVarsAreSet(envVars) | ||||
| } | ||||
| 
 | ||||
| // actionsURL returns URL to actions resource. For example, | ||||
| @@ -240,7 +251,12 @@ func actionsURL() string { | ||||
| 	return getEnv("GITHUB_API_URL", "") + "/repos/" + getEnv("GITHUB_REPOSITORY", "") + "/actions" | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) fetchRunData() { | ||||
| func (g *githubActionsConfigProvider) fetchRunData() { | ||||
| 	if g.client == nil { | ||||
| 		log.Entry().Debug("ConfigProvider for GitHub Actions is not configured. Unable to fetch run data") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if g.runData.fetched { | ||||
| 		return | ||||
| 	} | ||||
| @@ -268,7 +284,7 @@ func convertRunData(runData *github.WorkflowRun) run { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) fetchJobs() error { | ||||
| func (g *githubActionsConfigProvider) fetchJobs() error { | ||||
| 	if g.jobsFetched { | ||||
| 		return nil | ||||
| 	} | ||||
| @@ -304,8 +320,8 @@ func convertJobs(jobs []*github.WorkflowJob) []job { | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| func (g *GitHubActionsConfigProvider) runIdInt64() (int64, error) { | ||||
| 	strRunId := g.GetBuildID() | ||||
| func (g *githubActionsConfigProvider) runIdInt64() (int64, error) { | ||||
| 	strRunId := g.BuildID() | ||||
| 	runId, err := strconv.ParseInt(strRunId, 10, 64) | ||||
| 	if err != nil { | ||||
| 		return 0, errors.Wrapf(err, "invalid GITHUB_RUN_ID value %s: %s", strRunId, err) | ||||
| @@ -30,10 +30,10 @@ func TestGitHubActionsConfigProvider_GetBuildStatus(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			g := &GitHubActionsConfigProvider{ | ||||
| 			g := &githubActionsConfigProvider{ | ||||
| 				runData: tt.runData, | ||||
| 			} | ||||
| 			assert.Equalf(t, tt.want, g.GetBuildStatus(), "GetBuildStatus()") | ||||
| 			assert.Equalf(t, tt.want, g.BuildStatus(), "BuildStatus()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -54,10 +54,10 @@ func TestGitHubActionsConfigProvider_GetBuildReason(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			g := &GitHubActionsConfigProvider{} | ||||
| 			g := &githubActionsConfigProvider{} | ||||
| 
 | ||||
| 			_ = os.Setenv("GITHUB_EVENT_NAME", tt.envGithubRef) | ||||
| 			assert.Equalf(t, tt.want, g.GetBuildReason(), "GetBuildReason()") | ||||
| 			assert.Equalf(t, tt.want, g.BuildReason(), "BuildReason()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -73,11 +73,11 @@ func TestGitHubActionsConfigProvider_GetRepoURL(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			g := &GitHubActionsConfigProvider{} | ||||
| 			g := &githubActionsConfigProvider{} | ||||
| 
 | ||||
| 			_ = os.Setenv("GITHUB_SERVER_URL", tt.envServerURL) | ||||
| 			_ = os.Setenv("GITHUB_REPOSITORY", tt.envRepo) | ||||
| 			assert.Equalf(t, tt.want, g.GetRepoURL(), "GetRepoURL()") | ||||
| 			assert.Equalf(t, tt.want, g.RepoURL(), "RepoURL()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -94,12 +94,12 @@ func TestGitHubActionsConfigProvider_GetPullRequestConfig(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			g := &GitHubActionsConfigProvider{} | ||||
| 			g := &githubActionsConfigProvider{} | ||||
| 
 | ||||
| 			_ = os.Setenv("GITHUB_REF", tt.envRef) | ||||
| 			_ = os.Setenv("GITHUB_HEAD_REF", "n/a") | ||||
| 			_ = os.Setenv("GITHUB_BASE_REF", "n/a") | ||||
| 			assert.Equalf(t, tt.want, g.GetPullRequestConfig(), "GetPullRequestConfig()") | ||||
| 			assert.Equalf(t, tt.want, g.PullRequestConfig(), "PullRequestConfig()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -126,8 +126,8 @@ func TestGitHubActionsConfigProvider_fetchRunData(t *testing.T) { | ||||
| 	_ = os.Setenv("GITHUB_RUN_ID", "11111") | ||||
| 
 | ||||
| 	// setup provider | ||||
| 	g := &GitHubActionsConfigProvider{} | ||||
| 	g.InitOrchestratorProvider(&OrchestratorSettings{}) | ||||
| 	g := newGithubActionsConfigProvider() | ||||
| 	assert.NoError(t, g.Configure(&Options{})) | ||||
| 	g.client = github.NewClient(http.DefaultClient) | ||||
| 
 | ||||
| 	// setup http mock | ||||
| @@ -182,8 +182,8 @@ func TestGitHubActionsConfigProvider_fetchJobs(t *testing.T) { | ||||
| 	_ = os.Setenv("GITHUB_RUN_ID", "11111") | ||||
| 
 | ||||
| 	// setup provider | ||||
| 	g := &GitHubActionsConfigProvider{} | ||||
| 	g.InitOrchestratorProvider(&OrchestratorSettings{}) | ||||
| 	g := newGithubActionsConfigProvider() | ||||
| 	assert.NoError(t, g.Configure(&Options{})) | ||||
| 	g.client = github.NewClient(http.DefaultClient) | ||||
| 
 | ||||
| 	// setup http mock | ||||
| @@ -224,11 +224,11 @@ func TestGitHubActionsConfigProvider_GetLog(t *testing.T) { | ||||
| 	_ = os.Setenv("GITHUB_REPOSITORY", "SAP/jenkins-library") | ||||
| 
 | ||||
| 	// setup provider | ||||
| 	g := &GitHubActionsConfigProvider{ | ||||
| 		jobs:        jobs, | ||||
| 		jobsFetched: true, | ||||
| 	} | ||||
| 	g.InitOrchestratorProvider(&OrchestratorSettings{}) | ||||
| 	g := newGithubActionsConfigProvider() | ||||
| 	g.jobs = jobs | ||||
| 	g.jobsFetched = true | ||||
| 
 | ||||
| 	assert.NoError(t, g.Configure(&Options{})) | ||||
| 	g.client = github.NewClient(http.DefaultClient) | ||||
| 
 | ||||
| 	// setup http mock | ||||
| @@ -262,7 +262,7 @@ func TestGitHubActionsConfigProvider_GetLog(t *testing.T) { | ||||
| 		) | ||||
| 	} | ||||
| 	// run | ||||
| 	logs, err := g.GetLog() | ||||
| 	logs, err := g.FullLogs() | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, wantLogs, string(logs)) | ||||
| } | ||||
| @@ -283,7 +283,7 @@ func TestGitHubActionsConfigProvider_Others(t *testing.T) { | ||||
| 	_ = os.Setenv("GITHUB_REPOSITORY", "SAP/jenkins-library") | ||||
| 	_ = os.Setenv("GITHUB_WORKFLOW_REF", "SAP/jenkins-library/.github/workflows/piper.yml@refs/heads/main") | ||||
| 
 | ||||
| 	p := GitHubActionsConfigProvider{} | ||||
| 	p := githubActionsConfigProvider{} | ||||
| 	startedAt, _ := time.Parse(time.RFC3339, "2023-08-11T07:28:24Z") | ||||
| 	p.runData = run{ | ||||
| 		fetched:   true, | ||||
| @@ -293,16 +293,16 @@ func TestGitHubActionsConfigProvider_Others(t *testing.T) { | ||||
| 
 | ||||
| 	assert.Equal(t, "n/a", p.OrchestratorVersion()) | ||||
| 	assert.Equal(t, "GitHubActions", p.OrchestratorType()) | ||||
| 	assert.Equal(t, "11111", p.GetBuildID()) | ||||
| 	assert.Equal(t, []ChangeSet{}, p.GetChangeSet()) | ||||
| 	assert.Equal(t, startedAt, p.GetPipelineStartTime()) | ||||
| 	assert.Equal(t, "Build", p.GetStageName()) | ||||
| 	assert.Equal(t, "main", p.GetBranch()) | ||||
| 	assert.Equal(t, "refs/pull/42/merge", p.GetReference()) | ||||
| 	assert.Equal(t, "https://github.com/SAP/jenkins-library/actions/runs/11111", p.GetBuildURL()) | ||||
| 	assert.Equal(t, "https://github.com/SAP/jenkins-library/actions/workflows/piper.yml", p.GetJobURL()) | ||||
| 	assert.Equal(t, "Piper workflow", p.GetJobName()) | ||||
| 	assert.Equal(t, "ffac537e6cbbf934b08745a378932722df287a53", p.GetCommit()) | ||||
| 	assert.Equal(t, "11111", p.BuildID()) | ||||
| 	assert.Equal(t, []ChangeSet{}, p.ChangeSets()) | ||||
| 	assert.Equal(t, startedAt, p.PipelineStartTime()) | ||||
| 	assert.Equal(t, "Build", p.StageName()) | ||||
| 	assert.Equal(t, "main", p.Branch()) | ||||
| 	assert.Equal(t, "refs/pull/42/merge", p.GitReference()) | ||||
| 	assert.Equal(t, "https://github.com/SAP/jenkins-library/actions/runs/11111", p.BuildURL()) | ||||
| 	assert.Equal(t, "https://github.com/SAP/jenkins-library/actions/workflows/piper.yml", p.JobURL()) | ||||
| 	assert.Equal(t, "Piper workflow", p.JobName()) | ||||
| 	assert.Equal(t, "ffac537e6cbbf934b08745a378932722df287a53", p.CommitSHA()) | ||||
| 	assert.Equal(t, "https://api.github.com/repos/SAP/jenkins-library/actions", actionsURL()) | ||||
| 	assert.True(t, p.IsPullRequest()) | ||||
| 	assert.True(t, isGitHubActions()) | ||||
							
								
								
									
										40
									
								
								pkg/orchestrator/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pkg/orchestrator/helpers.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| package orchestrator | ||||
|  | ||||
| import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| // envVarsAreSet verifies if any envvar from the list has nona non-empty, non-false value | ||||
| func envVarsAreSet(envVars []string) bool { | ||||
| 	for _, v := range envVars { | ||||
| 		if envVarIsTrue(v) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // envVarIsTrue verifies if the variable is set and has a non-empty, non-false value. | ||||
| func envVarIsTrue(key string) bool { | ||||
| 	val, exists := os.LookupEnv(key) | ||||
| 	if !exists { | ||||
| 		return false | ||||
| 	} | ||||
| 	if len(val) == 0 || val == "no" || val == "false" || val == "off" || val == "0" { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Wrapper function to read env variable and set default value | ||||
| func getEnv(key, fallback string) string { | ||||
| 	if value, found := os.LookupEnv(key); found { | ||||
| 		log.Entry().Debugf("For: %s, found: %s", key, value) | ||||
| 		return value | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Debugf("Could not read env variable %v using fallback value %v", key, fallback) | ||||
| 	return fallback | ||||
| } | ||||
| @@ -4,57 +4,35 @@ | ||||
| package orchestrator | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"os" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestOrchestrator(t *testing.T) { | ||||
| 	t.Run("Not running on CI", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
| 
 | ||||
| 		provider, err := NewOrchestratorSpecificConfigProvider() | ||||
| 
 | ||||
| 		assert.EqualError(t, err, "unable to detect a supported orchestrator (Azure DevOps, GitHub Actions, Jenkins)") | ||||
| 		assert.Equal(t, "Unknown", provider.OrchestratorType()) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("Test orchestrator.toString()", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
| 
 | ||||
| 		os.Setenv("AZURE_HTTP_USER_AGENT", "FOO BAR BAZ") | ||||
| 
 | ||||
| 		o := DetectOrchestrator() | ||||
| 
 | ||||
| 		assert.Equal(t, "AzureDevOps", o.String()) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("Test areIndicatingEnvVarsSet", func(t *testing.T) { | ||||
| func Test_envVarsAreSet(t *testing.T) { | ||||
| 	t.Run("Test envVarsAreSet", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
| 
 | ||||
| 		envVars := []string{"GITHUB_ACTION", "GITHUB_ACTIONS"} | ||||
| 
 | ||||
| 		os.Setenv("GITHUB_ACTION", "true") | ||||
| 		tmp := areIndicatingEnvVarsSet(envVars) | ||||
| 		tmp := envVarsAreSet(envVars) | ||||
| 		assert.True(t, tmp) | ||||
| 
 | ||||
| 		os.Unsetenv("GITHUB_ACTION") | ||||
| 		os.Setenv("GITHUB_ACTIONS", "true") | ||||
| 		tmp = areIndicatingEnvVarsSet(envVars) | ||||
| 		tmp = envVarsAreSet(envVars) | ||||
| 		assert.True(t, tmp) | ||||
| 
 | ||||
| 		os.Setenv("GITHUB_ACTION", "1") | ||||
| 		os.Setenv("GITHUB_ACTIONS", "false") | ||||
| 		tmp = areIndicatingEnvVarsSet(envVars) | ||||
| 		tmp = envVarsAreSet(envVars) | ||||
| 		assert.True(t, tmp) | ||||
| 
 | ||||
| 		os.Setenv("GITHUB_ACTION", "false") | ||||
| 		os.Setenv("GITHUB_ACTIONS", "0") | ||||
| 		tmp = areIndicatingEnvVarsSet(envVars) | ||||
| 		tmp = envVarsAreSet(envVars) | ||||
| 		assert.False(t, tmp) | ||||
| 	}) | ||||
| } | ||||
| @@ -12,36 +12,42 @@ import ( | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| type JenkinsConfigProvider struct { | ||||
| type jenkinsConfigProvider struct { | ||||
| 	client         piperHttp.Client | ||||
| 	apiInformation map[string]interface{} | ||||
| } | ||||
|  | ||||
| // InitOrchestratorProvider initializes the Jenkins orchestrator with credentials | ||||
| func (j *JenkinsConfigProvider) InitOrchestratorProvider(settings *OrchestratorSettings) { | ||||
| func newJenkinsConfigProvider() *jenkinsConfigProvider { | ||||
| 	return &jenkinsConfigProvider{} | ||||
| } | ||||
|  | ||||
| // Configure initializes the Jenkins orchestrator with credentials | ||||
| func (j *jenkinsConfigProvider) Configure(opts *Options) error { | ||||
| 	j.client.SetOptions(piperHttp.ClientOptions{ | ||||
| 		Username:         settings.JenkinsUser, | ||||
| 		Password:         settings.JenkinsToken, | ||||
| 		Username:         opts.JenkinsUser, | ||||
| 		Password:         opts.JenkinsToken, | ||||
| 		MaxRetries:       3, | ||||
| 		TransportTimeout: time.Second * 10, | ||||
| 	}) | ||||
|  | ||||
| 	log.Entry().Debug("Successfully initialized Jenkins config provider") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // OrchestratorVersion returns the orchestrator version currently running on | ||||
| func (j *JenkinsConfigProvider) OrchestratorVersion() string { | ||||
| func (j *jenkinsConfigProvider) OrchestratorVersion() string { | ||||
| 	return getEnv("JENKINS_VERSION", "n/a") | ||||
| } | ||||
|  | ||||
| // OrchestratorType returns the orchestrator type Jenkins | ||||
| func (j *JenkinsConfigProvider) OrchestratorType() string { | ||||
| func (j *jenkinsConfigProvider) OrchestratorType() string { | ||||
| 	return "Jenkins" | ||||
| } | ||||
|  | ||||
| func (j *JenkinsConfigProvider) fetchAPIInformation() { | ||||
| func (j *jenkinsConfigProvider) fetchAPIInformation() { | ||||
| 	if len(j.apiInformation) == 0 { | ||||
| 		log.Entry().Debugf("apiInformation is empty, getting infos from API") | ||||
| 		URL := j.GetBuildURL() + "api/json" | ||||
| 		URL := j.BuildURL() + "api/json" | ||||
| 		log.Entry().Debugf("API URL: %s", URL) | ||||
| 		response, err := j.client.GetRequest(URL, nil, nil) | ||||
| 		if err != nil { | ||||
| @@ -67,8 +73,8 @@ func (j *JenkinsConfigProvider) fetchAPIInformation() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetBuildStatus returns build status of the current job | ||||
| func (j *JenkinsConfigProvider) GetBuildStatus() string { | ||||
| // BuildStatus returns build status of the current job | ||||
| func (j *jenkinsConfigProvider) BuildStatus() string { | ||||
| 	j.fetchAPIInformation() | ||||
| 	if val, ok := j.apiInformation["result"]; ok { | ||||
| 		// cases in ADO: succeeded, failed, canceled, none, partiallySucceeded | ||||
| @@ -85,8 +91,8 @@ func (j *JenkinsConfigProvider) GetBuildStatus() string { | ||||
| 	return BuildStatusFailure | ||||
| } | ||||
|  | ||||
| // GetChangeSet returns the commitIds and timestamp of the changeSet of the current run | ||||
| func (j *JenkinsConfigProvider) GetChangeSet() []ChangeSet { | ||||
| // ChangeSet returns the commitIds and timestamp of the changeSet of the current run | ||||
| func (j *jenkinsConfigProvider) ChangeSets() []ChangeSet { | ||||
| 	j.fetchAPIInformation() | ||||
|  | ||||
| 	marshal, err := json.Marshal(j.apiInformation) | ||||
| @@ -116,9 +122,9 @@ func (j *JenkinsConfigProvider) GetChangeSet() []ChangeSet { | ||||
| 	return changeSetList | ||||
| } | ||||
|  | ||||
| // GetLog returns the logfile from the current job as byte object | ||||
| func (j *JenkinsConfigProvider) GetLog() ([]byte, error) { | ||||
| 	URL := j.GetBuildURL() + "consoleText" | ||||
| // FullLogs returns the logfile from the current job as byte object | ||||
| func (j *jenkinsConfigProvider) FullLogs() ([]byte, error) { | ||||
| 	URL := j.BuildURL() + "consoleText" | ||||
|  | ||||
| 	response, err := j.client.GetRequest(URL, nil, nil) | ||||
| 	if err != nil { | ||||
| @@ -135,9 +141,9 @@ func (j *JenkinsConfigProvider) GetLog() ([]byte, error) { | ||||
| 	return logFile, nil | ||||
| } | ||||
|  | ||||
| // GetPipelineStartTime returns the pipeline start time in UTC | ||||
| func (j *JenkinsConfigProvider) GetPipelineStartTime() time.Time { | ||||
| 	URL := j.GetBuildURL() + "api/json" | ||||
| // PipelineStartTime returns the pipeline start time in UTC | ||||
| func (j *jenkinsConfigProvider) PipelineStartTime() time.Time { | ||||
| 	URL := j.BuildURL() + "api/json" | ||||
| 	response, err := j.client.GetRequest(URL, nil, nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Errorf("could not getRequest to URL %s", URL) | ||||
| @@ -163,33 +169,33 @@ func (j *JenkinsConfigProvider) GetPipelineStartTime() time.Time { | ||||
| 	return timeStamp.UTC() | ||||
| } | ||||
|  | ||||
| // GetJobName returns the job name of the current job e.g. foo/bar/BRANCH | ||||
| func (j *JenkinsConfigProvider) GetJobName() string { | ||||
| // JobName returns the job name of the current job e.g. foo/bar/BRANCH | ||||
| func (j *jenkinsConfigProvider) JobName() string { | ||||
| 	return getEnv("JOB_NAME", "n/a") | ||||
| } | ||||
|  | ||||
| // GetJobURL returns the current job URL e.g. https://jaas.url/job/foo/job/bar/job/main | ||||
| func (j *JenkinsConfigProvider) GetJobURL() string { | ||||
| // JobURL returns the current job URL e.g. https://jaas.url/job/foo/job/bar/job/main | ||||
| func (j *jenkinsConfigProvider) JobURL() string { | ||||
| 	return getEnv("JOB_URL", "n/a") | ||||
| } | ||||
|  | ||||
| // getJenkinsHome returns the jenkins home e.g. /var/lib/jenkins | ||||
| func (j *JenkinsConfigProvider) getJenkinsHome() string { | ||||
| func (j *jenkinsConfigProvider) getJenkinsHome() string { | ||||
| 	return getEnv("JENKINS_HOME", "n/a") | ||||
| } | ||||
|  | ||||
| // GetBuildID returns the build ID of the current job, e.g. 1234 | ||||
| func (j *JenkinsConfigProvider) GetBuildID() string { | ||||
| // BuildID returns the build ID of the current job, e.g. 1234 | ||||
| func (j *jenkinsConfigProvider) BuildID() string { | ||||
| 	return getEnv("BUILD_ID", "n/a") | ||||
| } | ||||
|  | ||||
| // GetStageName returns the stage name the job is currently in, e.g. Promote | ||||
| func (j *JenkinsConfigProvider) GetStageName() string { | ||||
| // StageName returns the stage name the job is currently in, e.g. Promote | ||||
| func (j *jenkinsConfigProvider) StageName() string { | ||||
| 	return getEnv("STAGE_NAME", "n/a") | ||||
| } | ||||
|  | ||||
| // GetBuildReason returns the build reason of the current build | ||||
| func (j *JenkinsConfigProvider) GetBuildReason() string { | ||||
| // BuildReason returns the build reason of the current build | ||||
| func (j *jenkinsConfigProvider) BuildReason() string { | ||||
| 	// BuildReasons are unified with AzureDevOps build reasons,see | ||||
| 	// https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services | ||||
| 	// ResourceTrigger, PullRequest, Manual, IndividualCI, Schedule | ||||
| @@ -231,13 +237,13 @@ func (j *JenkinsConfigProvider) GetBuildReason() string { | ||||
| 	return BuildReasonUnknown | ||||
| } | ||||
|  | ||||
| // GetBranch returns the branch name, only works with the git plugin enabled | ||||
| func (j *JenkinsConfigProvider) GetBranch() string { | ||||
| // Branch returns the branch name, only works with the git plugin enabled | ||||
| func (j *jenkinsConfigProvider) Branch() string { | ||||
| 	return getEnv("BRANCH_NAME", "n/a") | ||||
| } | ||||
|  | ||||
| // GetReference returns the git reference, only works with the git plugin enabled | ||||
| func (j *JenkinsConfigProvider) GetReference() string { | ||||
| // GitReference returns the git reference, only works with the git plugin enabled | ||||
| func (j *jenkinsConfigProvider) GitReference() string { | ||||
| 	ref := getEnv("BRANCH_NAME", "n/a") | ||||
| 	if ref == "n/a" { | ||||
| 		return ref | ||||
| @@ -248,23 +254,23 @@ func (j *JenkinsConfigProvider) GetReference() string { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetBuildURL returns the build url, e.g. https://jaas.url/job/foo/job/bar/job/main/1234/ | ||||
| func (j *JenkinsConfigProvider) GetBuildURL() string { | ||||
| // BuildURL returns the build url, e.g. https://jaas.url/job/foo/job/bar/job/main/1234/ | ||||
| func (j *jenkinsConfigProvider) BuildURL() string { | ||||
| 	return getEnv("BUILD_URL", "n/a") | ||||
| } | ||||
|  | ||||
| // GetCommit returns the commit SHA from the current build, only works with the git plugin enabled | ||||
| func (j *JenkinsConfigProvider) GetCommit() string { | ||||
| // CommitSHA returns the commit SHA from the current build, only works with the git plugin enabled | ||||
| func (j *jenkinsConfigProvider) CommitSHA() string { | ||||
| 	return getEnv("GIT_COMMIT", "n/a") | ||||
| } | ||||
|  | ||||
| // GetRepoURL returns the repo URL of the current build, only works with the git plugin enabled | ||||
| func (j *JenkinsConfigProvider) GetRepoURL() string { | ||||
| // RepoURL returns the repo URL of the current build, only works with the git plugin enabled | ||||
| func (j *jenkinsConfigProvider) RepoURL() string { | ||||
| 	return getEnv("GIT_URL", "n/a") | ||||
| } | ||||
|  | ||||
| // GetPullRequestConfig returns the pull request config | ||||
| func (j *JenkinsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| // PullRequestConfig returns the pull request config | ||||
| func (j *jenkinsConfigProvider) PullRequestConfig() PullRequestConfig { | ||||
| 	return PullRequestConfig{ | ||||
| 		Branch: getEnv("CHANGE_BRANCH", "n/a"), | ||||
| 		Base:   getEnv("CHANGE_TARGET", "n/a"), | ||||
| @@ -273,11 +279,11 @@ func (j *JenkinsConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| } | ||||
|  | ||||
| // IsPullRequest returns boolean indicating if current job is a PR | ||||
| func (j *JenkinsConfigProvider) IsPullRequest() bool { | ||||
| 	return truthy("CHANGE_ID") | ||||
| func (j *jenkinsConfigProvider) IsPullRequest() bool { | ||||
| 	return envVarIsTrue("CHANGE_ID") | ||||
| } | ||||
|  | ||||
| func isJenkins() bool { | ||||
| 	envVars := []string{"JENKINS_HOME", "JENKINS_URL"} | ||||
| 	return areIndicatingEnvVarsSet(envVars) | ||||
| 	return envVarsAreSet(envVars) | ||||
| } | ||||
|   | ||||
| @@ -29,14 +29,14 @@ func TestJenkins(t *testing.T) { | ||||
| 		os.Setenv("GIT_COMMIT", "abcdef42713") | ||||
| 		os.Setenv("GIT_URL", "github.com/foo/bar") | ||||
|  | ||||
| 		p, _ := NewOrchestratorSpecificConfigProvider() | ||||
| 		p := &jenkinsConfigProvider{} | ||||
|  | ||||
| 		assert.False(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main/1234/", p.GetBuildURL()) | ||||
| 		assert.Equal(t, "main", p.GetBranch()) | ||||
| 		assert.Equal(t, "refs/heads/main", p.GetReference()) | ||||
| 		assert.Equal(t, "abcdef42713", p.GetCommit()) | ||||
| 		assert.Equal(t, "github.com/foo/bar", p.GetRepoURL()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main/1234/", p.BuildURL()) | ||||
| 		assert.Equal(t, "main", p.Branch()) | ||||
| 		assert.Equal(t, "refs/heads/main", p.GitReference()) | ||||
| 		assert.Equal(t, "abcdef42713", p.CommitSHA()) | ||||
| 		assert.Equal(t, "github.com/foo/bar", p.RepoURL()) | ||||
| 		assert.Equal(t, "Jenkins", p.OrchestratorType()) | ||||
| 	}) | ||||
|  | ||||
| @@ -48,11 +48,11 @@ func TestJenkins(t *testing.T) { | ||||
| 		os.Setenv("CHANGE_TARGET", "main") | ||||
| 		os.Setenv("CHANGE_ID", "42") | ||||
|  | ||||
| 		p := JenkinsConfigProvider{} | ||||
| 		c := p.GetPullRequestConfig() | ||||
| 		p := jenkinsConfigProvider{} | ||||
| 		c := p.PullRequestConfig() | ||||
|  | ||||
| 		assert.True(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "refs/pull/42/head", p.GetReference()) | ||||
| 		assert.Equal(t, "refs/pull/42/head", p.GitReference()) | ||||
| 		assert.Equal(t, "feat/test-jenkins", c.Branch) | ||||
| 		assert.Equal(t, "main", c.Base) | ||||
| 		assert.Equal(t, "42", c.Key) | ||||
| @@ -70,16 +70,16 @@ func TestJenkins(t *testing.T) { | ||||
| 		os.Setenv("BUILD_URL", "https://jaas.url/job/foo/job/bar/job/main/1234/") | ||||
| 		os.Setenv("STAGE_NAME", "Promote") | ||||
|  | ||||
| 		p := JenkinsConfigProvider{} | ||||
| 		p := jenkinsConfigProvider{} | ||||
|  | ||||
| 		assert.Equal(t, "/var/lib/jenkins", p.getJenkinsHome()) | ||||
| 		assert.Equal(t, "1234", p.GetBuildID()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main", p.GetJobURL()) | ||||
| 		assert.Equal(t, "1234", p.BuildID()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main", p.JobURL()) | ||||
| 		assert.Equal(t, "42", p.OrchestratorVersion()) | ||||
| 		assert.Equal(t, "Jenkins", p.OrchestratorType()) | ||||
| 		assert.Equal(t, "foo/bar/BRANCH", p.GetJobName()) | ||||
| 		assert.Equal(t, "Promote", p.GetStageName()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main/1234/", p.GetBuildURL()) | ||||
| 		assert.Equal(t, "foo/bar/BRANCH", p.JobName()) | ||||
| 		assert.Equal(t, "Promote", p.StageName()) | ||||
| 		assert.Equal(t, "https://jaas.url/job/foo/job/bar/job/main/1234/", p.BuildURL()) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
| @@ -130,7 +130,7 @@ func TestJenkinsConfigProvider_GetPipelineStartTime(t *testing.T) { | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	j := &JenkinsConfigProvider{ | ||||
| 	j := &jenkinsConfigProvider{ | ||||
| 		client: piperhttp.Client{}, | ||||
| 	} | ||||
| 	j.client.SetOptions(piperhttp.ClientOptions{ | ||||
| @@ -171,7 +171,7 @@ func TestJenkinsConfigProvider_GetPipelineStartTime(t *testing.T) { | ||||
| 				}, | ||||
| 			) | ||||
|  | ||||
| 			assert.Equalf(t, tt.want, j.GetPipelineStartTime(), "GetPipelineStartTime()") | ||||
| 			assert.Equalf(t, tt.want, j.PipelineStartTime(), "PipelineStartTime()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -228,10 +228,10 @@ func TestJenkinsConfigProvider_GetBuildStatus(t *testing.T) { | ||||
| 			if err != nil { | ||||
| 				t.Fatal("could not parse json:", err) | ||||
| 			} | ||||
| 			j := &JenkinsConfigProvider{ | ||||
| 			j := &jenkinsConfigProvider{ | ||||
| 				apiInformation: apiInformation, | ||||
| 			} | ||||
| 			assert.Equalf(t, tt.want, j.GetBuildStatus(), "GetBuildStatus()") | ||||
| 			assert.Equalf(t, tt.want, j.BuildStatus(), "BuildStatus()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -367,9 +367,9 @@ func TestJenkinsConfigProvider_GetBuildReason(t *testing.T) { | ||||
| 			if err != nil { | ||||
| 				t.Fatal("could not parse json:", err) | ||||
| 			} | ||||
| 			j := &JenkinsConfigProvider{apiInformation: apiInformation} | ||||
| 			j := &jenkinsConfigProvider{apiInformation: apiInformation} | ||||
|  | ||||
| 			assert.Equalf(t, tt.want, j.GetBuildReason(), "GetBuildReason()") | ||||
| 			assert.Equalf(t, tt.want, j.BuildReason(), "BuildReason()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -415,7 +415,7 @@ func TestJenkinsConfigProvider_getAPIInformation(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			j := &JenkinsConfigProvider{ | ||||
| 			j := &jenkinsConfigProvider{ | ||||
| 				apiInformation: tt.apiInformation, | ||||
| 			} | ||||
| 			j.client.SetOptions(piperhttp.ClientOptions{ | ||||
| @@ -487,7 +487,7 @@ func TestJenkinsConfigProvider_GetLog(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			j := &JenkinsConfigProvider{} | ||||
| 			j := &jenkinsConfigProvider{} | ||||
| 			j.client.SetOptions(piperhttp.ClientOptions{ | ||||
| 				MaxRequestDuration:        5 * time.Second, | ||||
| 				Token:                     "TOKEN", | ||||
| @@ -519,33 +519,11 @@ func TestJenkinsConfigProvider_GetLog(t *testing.T) { | ||||
| 				}, | ||||
| 			) | ||||
|  | ||||
| 			got, err := j.GetLog() | ||||
| 			if !tt.wantErr(t, err, fmt.Sprintf("GetLog()")) { | ||||
| 			got, err := j.FullLogs() | ||||
| 			if !tt.wantErr(t, err, fmt.Sprintf("FullLogs()")) { | ||||
| 				return | ||||
| 			} | ||||
| 			assert.Equalf(t, tt.want, got, "GetLog()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestJenkinsConfigProvider_InitOrchestratorProvider(t *testing.T) { | ||||
|  | ||||
| 	tests := []struct { | ||||
| 		name           string | ||||
| 		settings       *OrchestratorSettings | ||||
| 		apiInformation map[string]interface{} | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:     "Init, test empty apiInformation", | ||||
| 			settings: &OrchestratorSettings{}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			j := &JenkinsConfigProvider{} | ||||
| 			j.InitOrchestratorProvider(tt.settings) | ||||
| 			var expected map[string]interface{} | ||||
| 			assert.Equal(t, j.apiInformation, expected) | ||||
| 			assert.Equalf(t, tt.want, got, "FullLogs()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @@ -664,8 +642,8 @@ func TestJenkinsConfigProvider_GetChangeSet(t *testing.T) { | ||||
| 			if err != nil { | ||||
| 				t.Fatal("could not parse json:", err) | ||||
| 			} | ||||
| 			j := &JenkinsConfigProvider{apiInformation: apiInformation} | ||||
| 			assert.Equalf(t, tt.want, j.GetChangeSet(), "GetChangeSet()") | ||||
| 			j := &jenkinsConfigProvider{apiInformation: apiInformation} | ||||
| 			assert.Equalf(t, tt.want, j.ChangeSets(), "ChangeSets()") | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,15 +1,12 @@ | ||||
| package orchestrator | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"os" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type Orchestrator int | ||||
|  | ||||
| const ( | ||||
| 	Unknown Orchestrator = iota | ||||
| 	AzureDevOps | ||||
| @@ -31,67 +28,86 @@ const ( | ||||
| 	BuildReasonUnknown         = "Unknown" | ||||
| ) | ||||
|  | ||||
| type OrchestratorSpecificConfigProviding interface { | ||||
| 	InitOrchestratorProvider(settings *OrchestratorSettings) | ||||
| var ( | ||||
| 	provider     ConfigProvider | ||||
| 	providerOnce sync.Once | ||||
| ) | ||||
|  | ||||
| type ConfigProvider interface { | ||||
| 	Configure(opts *Options) error | ||||
| 	OrchestratorType() string | ||||
| 	OrchestratorVersion() string | ||||
| 	GetStageName() string | ||||
| 	GetBranch() string | ||||
| 	GetReference() string | ||||
| 	GetBuildURL() string | ||||
| 	GetBuildID() string | ||||
| 	GetJobURL() string | ||||
| 	GetJobName() string | ||||
| 	GetCommit() string | ||||
| 	GetPullRequestConfig() PullRequestConfig | ||||
| 	GetRepoURL() string | ||||
| 	StageName() string | ||||
| 	Branch() string | ||||
| 	GitReference() string | ||||
| 	RepoURL() string | ||||
| 	BuildURL() string | ||||
| 	BuildID() string | ||||
| 	BuildStatus() string | ||||
| 	BuildReason() string | ||||
| 	JobURL() string | ||||
| 	JobName() string | ||||
| 	CommitSHA() string | ||||
| 	PullRequestConfig() PullRequestConfig | ||||
| 	IsPullRequest() bool | ||||
| 	GetLog() ([]byte, error) | ||||
| 	GetPipelineStartTime() time.Time | ||||
| 	GetBuildStatus() string | ||||
| 	GetBuildReason() string | ||||
| 	GetChangeSet() []ChangeSet | ||||
| 	FullLogs() ([]byte, error) | ||||
| 	PipelineStartTime() time.Time | ||||
| 	ChangeSets() []ChangeSet | ||||
| } | ||||
|  | ||||
| type PullRequestConfig struct { | ||||
| 	Branch string | ||||
| 	Base   string | ||||
| 	Key    string | ||||
| } | ||||
| type ( | ||||
| 	Orchestrator int | ||||
|  | ||||
| type ChangeSet struct { | ||||
| 	CommitId  string | ||||
| 	Timestamp string | ||||
| 	PrNumber  int | ||||
| } | ||||
|  | ||||
| // OrchestratorSettings struct to set orchestrator specific settings e.g. Jenkins credentials | ||||
| type OrchestratorSettings struct { | ||||
| 	JenkinsUser  string | ||||
| 	JenkinsToken string | ||||
| 	AzureToken   string | ||||
| 	GitHubToken  string | ||||
| } | ||||
|  | ||||
| func NewOrchestratorSpecificConfigProvider() (OrchestratorSpecificConfigProviding, error) { | ||||
| 	switch DetectOrchestrator() { | ||||
| 	case AzureDevOps: | ||||
| 		return &AzureDevOpsConfigProvider{}, nil | ||||
| 	case GitHubActions: | ||||
| 		ghProvider := &GitHubActionsConfigProvider{} | ||||
| 		// Temporary workaround: The orchestrator provider is not always initialized after being created, | ||||
| 		// which causes a panic in some places for GitHub Actions provider, as it needs to initialize | ||||
| 		// github sdk client. | ||||
| 		ghProvider.InitOrchestratorProvider(&OrchestratorSettings{}) | ||||
| 		return ghProvider, nil | ||||
| 	case Jenkins: | ||||
| 		return &JenkinsConfigProvider{}, nil | ||||
| 	default: | ||||
| 		return &UnknownOrchestratorConfigProvider{}, errors.New("unable to detect a supported orchestrator (Azure DevOps, GitHub Actions, Jenkins)") | ||||
| 	// Options used to set orchestrator specific settings. | ||||
| 	Options struct { | ||||
| 		JenkinsUser  string | ||||
| 		JenkinsToken string | ||||
| 		AzureToken   string | ||||
| 		GitHubToken  string | ||||
| 	} | ||||
|  | ||||
| 	PullRequestConfig struct { | ||||
| 		Branch string | ||||
| 		Base   string | ||||
| 		Key    string | ||||
| 	} | ||||
|  | ||||
| 	ChangeSet struct { | ||||
| 		CommitId  string | ||||
| 		Timestamp string | ||||
| 		PrNumber  int | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func GetOrchestratorConfigProvider(opts *Options) (ConfigProvider, error) { | ||||
| 	var err error | ||||
| 	providerOnce.Do(func() { | ||||
| 		switch DetectOrchestrator() { | ||||
| 		case AzureDevOps: | ||||
| 			provider = newAzureDevopsConfigProvider() | ||||
| 		case GitHubActions: | ||||
| 			provider = newGithubActionsConfigProvider() | ||||
| 		case Jenkins: | ||||
| 			provider = newJenkinsConfigProvider() | ||||
| 		default: | ||||
| 			provider = newUnknownOrchestratorConfigProvider() | ||||
| 			err = errors.New("unable to detect a supported orchestrator (Azure DevOps, GitHub Actions, Jenkins)") | ||||
| 		} | ||||
|  | ||||
| 		if opts == nil { | ||||
| 			log.Entry().Debug("ConfigProvider initialized without options. Some data may be unavailable") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if cfgErr := provider.Configure(opts); cfgErr != nil { | ||||
| 			err = errors.Wrap(cfgErr, "provider configuration failed") | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	return provider, err | ||||
| } | ||||
|  | ||||
| // DetectOrchestrator returns the name of the current orchestrator e.g. Jenkins, Azure, Unknown | ||||
| // DetectOrchestrator function determines in which orchestrator Piper is running by examining environment variables. | ||||
| func DetectOrchestrator() Orchestrator { | ||||
| 	if isAzure() { | ||||
| 		return AzureDevOps | ||||
| @@ -108,34 +124,10 @@ func (o Orchestrator) String() string { | ||||
| 	return [...]string{"Unknown", "AzureDevOps", "GitHubActions", "Jenkins"}[o] | ||||
| } | ||||
|  | ||||
| func areIndicatingEnvVarsSet(envVars []string) bool { | ||||
| 	for _, v := range envVars { | ||||
| 		if truthy(v) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Checks if var is set and neither empty nor false | ||||
| func truthy(key string) bool { | ||||
| 	val, exists := os.LookupEnv(key) | ||||
| 	if !exists { | ||||
| 		return false | ||||
| 	} | ||||
| 	if len(val) == 0 || val == "no" || val == "false" || val == "off" || val == "0" { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Wrapper function to read env variable and set default value | ||||
| func getEnv(key, fallback string) string { | ||||
| 	if value, ok := os.LookupEnv(key); ok { | ||||
| 		log.Entry().Debugf("For: %s, found: %s", key, value) | ||||
| 		return value | ||||
| 	} | ||||
| 	log.Entry().Debugf("Could not read env variable %v using fallback value %v", key, fallback) | ||||
| 	return fallback | ||||
| // ResetConfigProvider is intended to be used only for unit tests because some of these tests | ||||
| // run with different environment variables (for example, mock runs in various orchestrators). | ||||
| // Usage in production code is not recommended. | ||||
| func ResetConfigProvider() { | ||||
| 	provider = nil | ||||
| 	providerOnce = sync.Once{} | ||||
| } | ||||
|   | ||||
| @@ -8,109 +8,99 @@ import ( | ||||
|  | ||||
| type UnknownOrchestratorConfigProvider struct{} | ||||
|  | ||||
| // InitOrchestratorProvider returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) InitOrchestratorProvider(settings *OrchestratorSettings) { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| const unknownOrchestratorWarning = "Unknown orchestrator - returning default values." | ||||
|  | ||||
| func newUnknownOrchestratorConfigProvider() *UnknownOrchestratorConfigProvider { | ||||
| 	return &UnknownOrchestratorConfigProvider{} | ||||
| } | ||||
|  | ||||
| func (u *UnknownOrchestratorConfigProvider) Configure(_ *Options) error { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // OrchestratorVersion returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) OrchestratorVersion() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetBuildStatus returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetBuildStatus() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) BuildStatus() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "FAILURE" | ||||
| } | ||||
|  | ||||
| func (u *UnknownOrchestratorConfigProvider) GetChangeSet() []ChangeSet { | ||||
| 	log.Entry().Infof("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) ChangeSets() []ChangeSet { | ||||
| 	log.Entry().Infof(unknownOrchestratorWarning) | ||||
| 	return []ChangeSet{} | ||||
| } | ||||
|  | ||||
| // GetBuildReason returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetBuildReason() string { | ||||
| 	log.Entry().Infof("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) BuildReason() string { | ||||
| 	log.Entry().Infof(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetBuildID returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetBuildID() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) BuildID() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetJobName returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetJobName() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) JobName() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // OrchestratorType returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) OrchestratorType() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "Unknown" | ||||
| } | ||||
|  | ||||
| // GetLog returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetLog() ([]byte, error) { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) FullLogs() ([]byte, error) { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return []byte{}, nil | ||||
| } | ||||
|  | ||||
| // GetPipelineStartTime returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetPipelineStartTime() time.Time { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) PipelineStartTime() time.Time { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return time.Time{}.UTC() | ||||
| } | ||||
|  | ||||
| // GetStageName returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetStageName() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) StageName() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetBranch returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetBranch() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) Branch() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetReference returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetReference() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) GitReference() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetBuildURL returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetBuildURL() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) BuildURL() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetJobURL returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetJobURL() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) JobURL() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetCommit returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetCommit() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) CommitSHA() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetRepoURL returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetRepoURL() string { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) RepoURL() string { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return "n/a" | ||||
| } | ||||
|  | ||||
| // GetPullRequestConfig returns n/a for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) GetPullRequestConfig() PullRequestConfig { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| func (u *UnknownOrchestratorConfigProvider) PullRequestConfig() PullRequestConfig { | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return PullRequestConfig{ | ||||
| 		Branch: "n/a", | ||||
| 		Base:   "n/a", | ||||
| @@ -118,8 +108,7 @@ func (u *UnknownOrchestratorConfigProvider) GetPullRequestConfig() PullRequestCo | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // IsPullRequest returns false for the unknownOrchestrator | ||||
| func (u *UnknownOrchestratorConfigProvider) IsPullRequest() bool { | ||||
| 	log.Entry().Warning("Unknown orchestrator - returning default values.") | ||||
| 	log.Entry().Warning(unknownOrchestratorWarning) | ||||
| 	return false | ||||
| } | ||||
|   | ||||
| @@ -1,61 +0,0 @@ | ||||
| //go:build unit | ||||
| // +build unit | ||||
|  | ||||
| package orchestrator | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestUnknownOrchestrator(t *testing.T) { | ||||
| 	t.Run("BranchBuild", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
|  | ||||
| 		p, _ := NewOrchestratorSpecificConfigProvider() | ||||
|  | ||||
| 		assert.False(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "n/a", p.GetBuildURL()) | ||||
| 		assert.Equal(t, "n/a", p.GetBranch()) | ||||
| 		assert.Equal(t, "n/a", p.GetCommit()) | ||||
| 		assert.Equal(t, "n/a", p.GetRepoURL()) | ||||
| 		assert.Equal(t, "Unknown", p.OrchestratorType()) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("PR", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
|  | ||||
| 		p := UnknownOrchestratorConfigProvider{} | ||||
| 		c := p.GetPullRequestConfig() | ||||
|  | ||||
| 		assert.False(t, p.IsPullRequest()) | ||||
| 		assert.Equal(t, "n/a", c.Branch) | ||||
| 		assert.Equal(t, "n/a", c.Base) | ||||
| 		assert.Equal(t, "n/a", c.Key) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("env variables", func(t *testing.T) { | ||||
| 		defer resetEnv(os.Environ()) | ||||
| 		os.Clearenv() | ||||
|  | ||||
| 		p := UnknownOrchestratorConfigProvider{} | ||||
|  | ||||
| 		assert.Equal(t, "n/a", p.OrchestratorVersion()) | ||||
| 		assert.Equal(t, "n/a", p.GetBuildID()) | ||||
| 		assert.Equal(t, "n/a", p.GetJobName()) | ||||
| 		assert.Equal(t, "Unknown", p.OrchestratorType()) | ||||
| 		assert.Equal(t, time.Time{}.UTC(), p.GetPipelineStartTime()) | ||||
| 		assert.Equal(t, "FAILURE", p.GetBuildStatus()) | ||||
| 		assert.Equal(t, "n/a", p.GetRepoURL()) | ||||
| 		assert.Equal(t, "n/a", p.GetBuildURL()) | ||||
| 		assert.Equal(t, "n/a", p.GetStageName()) | ||||
| 		log, err := p.GetLog() | ||||
| 		assert.Equal(t, []byte{}, log) | ||||
| 		assert.Equal(t, nil, err) | ||||
| 	}) | ||||
| } | ||||
| @@ -67,14 +67,14 @@ func (p *PolicyViolationReport) ToMarkdown() ([]byte, error) { | ||||
| 	} | ||||
|  | ||||
| 	// only fill with orchestrator information if orchestrator can be identified properly | ||||
| 	if provider, err := orchestrator.NewOrchestratorSpecificConfigProvider(); err == nil { | ||||
| 	if provider, err := orchestrator.GetOrchestratorConfigProvider(nil); err == nil { | ||||
| 		// only add information if not yet provided | ||||
| 		if len(p.CommitID) == 0 { | ||||
| 			p.CommitID = provider.GetCommit() | ||||
| 			p.CommitID = provider.CommitSHA() | ||||
| 		} | ||||
| 		if len(p.PipelineLink) == 0 { | ||||
| 			p.PipelineLink = provider.GetJobURL() | ||||
| 			p.PipelineName = provider.GetJobName() | ||||
| 			p.PipelineLink = provider.JobURL() | ||||
| 			p.PipelineName = provider.JobName() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -91,18 +91,18 @@ func (v *VulnerabilityReport) ToMarkdown() ([]byte, error) { | ||||
| 	} | ||||
|  | ||||
| 	// only fill with orchestrator information if orchestrator can be identified properly | ||||
| 	if provider, err := orchestrator.NewOrchestratorSpecificConfigProvider(); err == nil { | ||||
| 	if provider, err := orchestrator.GetOrchestratorConfigProvider(nil); err == nil { | ||||
| 		// only add information if not yet provided | ||||
| 		if len(v.CommitID) == 0 { | ||||
| 			v.CommitID = provider.GetCommit() | ||||
| 			v.CommitID = provider.CommitSHA() | ||||
| 		} | ||||
| 		if len(v.PipelineLink) == 0 { | ||||
| 			v.PipelineLink = provider.GetJobURL() | ||||
| 			v.PipelineName = provider.GetJobName() | ||||
| 			v.PipelineLink = provider.JobURL() | ||||
| 			v.PipelineName = provider.JobName() | ||||
| 		} | ||||
|  | ||||
| 		if len(v.Branch) == 0 { | ||||
| 			v.Branch = provider.GetBranch() | ||||
| 			v.Branch = provider.Branch() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -14,8 +14,8 @@ type BaseData struct { | ||||
| 	URL             string `json:"url"` | ||||
| 	StepName        string `json:"e_3"` // set by step generator | ||||
| 	StageName       string `json:"e_10"` | ||||
| 	PipelineURLHash string `json:"e_4"`  // defaults to sha1 of provider.GetBuildURL() | ||||
| 	BuildURLHash    string `json:"e_5"`  // defaults to sha1 of provider.GetJobURL() | ||||
| 	PipelineURLHash string `json:"e_4"`  // defaults to sha1 of provider.BuildURL() | ||||
| 	BuildURLHash    string `json:"e_5"`  // defaults to sha1 of provider.JobURL() | ||||
| 	Orchestrator    string `json:"e_14"` // defaults to provider.OrchestratorType() | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -28,7 +28,7 @@ type Telemetry struct { | ||||
| 	baseData             BaseData | ||||
| 	baseMetaData         BaseMetaData | ||||
| 	data                 Data | ||||
| 	provider             orchestrator.OrchestratorSpecificConfigProviding | ||||
| 	provider             orchestrator.ConfigProvider | ||||
| 	disabled             bool | ||||
| 	client               *piperhttp.Client | ||||
| 	CustomReportingDsn   string | ||||
| @@ -43,8 +43,8 @@ type Telemetry struct { | ||||
| func (t *Telemetry) Initialize(telemetryDisabled bool, stepName string) { | ||||
| 	t.disabled = telemetryDisabled | ||||
|  | ||||
| 	provider, err := orchestrator.NewOrchestratorSpecificConfigProvider() | ||||
| 	if err != nil || provider == nil { | ||||
| 	provider, err := orchestrator.GetOrchestratorConfigProvider(nil) | ||||
| 	if err != nil { | ||||
| 		log.Entry().Warningf("could not get orchestrator config provider, leads to insufficient data") | ||||
| 		provider = &orchestrator.UnknownOrchestratorConfigProvider{} | ||||
| 	} | ||||
| @@ -73,8 +73,8 @@ func (t *Telemetry) Initialize(telemetryDisabled bool, stepName string) { | ||||
| 	} | ||||
|  | ||||
| 	t.baseData = BaseData{ | ||||
| 		Orchestrator:    provider.OrchestratorType(), | ||||
| 		StageName:       provider.GetStageName(), | ||||
| 		Orchestrator:    t.provider.OrchestratorType(), | ||||
| 		StageName:       t.provider.StageName(), | ||||
| 		URL:             LibraryRepository, | ||||
| 		ActionName:      actionName, | ||||
| 		EventType:       eventType, | ||||
| @@ -87,12 +87,12 @@ func (t *Telemetry) Initialize(telemetryDisabled bool, stepName string) { | ||||
| } | ||||
|  | ||||
| func (t *Telemetry) getPipelineURLHash() string { | ||||
| 	jobURL := t.provider.GetJobURL() | ||||
| 	jobURL := t.provider.JobURL() | ||||
| 	return t.toSha1OrNA(jobURL) | ||||
| } | ||||
|  | ||||
| func (t *Telemetry) getBuildURLHash() string { | ||||
| 	buildURL := t.provider.GetBuildURL() | ||||
| 	buildURL := t.provider.BuildURL() | ||||
| 	return t.toSha1OrNA(buildURL) | ||||
| } | ||||
|  | ||||
| @@ -160,7 +160,7 @@ func (t *Telemetry) logStepTelemetryData() { | ||||
| 		StepDuration:    t.data.CustomData.Duration, | ||||
| 		ErrorCategory:   t.data.CustomData.ErrorCategory, | ||||
| 		ErrorDetail:     fatalError, | ||||
| 		CorrelationID:   t.provider.GetBuildURL(), | ||||
| 		CorrelationID:   t.provider.BuildURL(), | ||||
| 		PiperCommitHash: t.data.CustomData.PiperCommitHash, | ||||
| 	} | ||||
| 	stepTelemetryJSON, err := json.Marshal(stepTelemetryData) | ||||
|   | ||||
| @@ -26,7 +26,7 @@ func TestTelemetry_Initialize(t *testing.T) { | ||||
| 		baseData             BaseData | ||||
| 		baseMetaData         BaseMetaData | ||||
| 		data                 Data | ||||
| 		provider             orchestrator.OrchestratorSpecificConfigProviding | ||||
| 		provider             orchestrator.ConfigProvider | ||||
| 		disabled             bool | ||||
| 		client               *piperhttp.Client | ||||
| 		CustomReportingDsn   string | ||||
| @@ -81,7 +81,7 @@ func TestTelemetry_Send(t *testing.T) { | ||||
| 		baseData             BaseData | ||||
| 		baseMetaData         BaseMetaData | ||||
| 		data                 Data | ||||
| 		provider             orchestrator.OrchestratorSpecificConfigProviding | ||||
| 		provider             orchestrator.ConfigProvider | ||||
| 		disabled             bool | ||||
| 		client               *piperhttp.Client | ||||
| 		CustomReportingDsn   string | ||||
| @@ -268,7 +268,7 @@ func TestTelemetry_logStepTelemetryData(t *testing.T) { | ||||
|  | ||||
| 	type fields struct { | ||||
| 		data     Data | ||||
| 		provider orchestrator.OrchestratorSpecificConfigProviding | ||||
| 		provider orchestrator.ConfigProvider | ||||
| 	} | ||||
| 	tests := []struct { | ||||
| 		name       string | ||||
|   | ||||
		Reference in New Issue
	
	Block a user