1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-10-30 23:57:50 +02:00

Streamline step generation (#1142)

* Streamline step generation
* Include PR feedback, update DEVELOPMENT.md

Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
Oliver Nocon
2020-02-04 10:46:43 +01:00
committed by GitHub
parent 5e06cc4ff5
commit 9c1bd04752
23 changed files with 314 additions and 302 deletions

View File

@@ -65,7 +65,7 @@ you need to do the following in addition:
* [Install Groovy](https://groovy-lang.org/install.html)
* [Install Maven](https://maven.apache.org/install.html)
* Get a local Jenkins installed: Use for example [cx-server](toDo: add link)
* Get a local Jenkins installed: Use for example [cx-server](https://github.com/SAP/devops-docker-cx-server)
### Jenkins pipelines
@@ -86,7 +86,7 @@ Use Docker:
You can extract the binary using Docker means to your local filesystem:
```
```sh
docker create --name piper piper:latest
docker cp piper:/piper .
docker rm piper
@@ -107,9 +107,47 @@ Examples are:
* spec - containers
* spec - sidecars
There are certain extensions:
* **aliases** allow alternative parameter names also supporting deeper configuration structures. [Example](https://github.com/SAP/jenkins-library/blob/master/resources/metadata/kubernetesdeploy.yaml)
* **resources** allow to read for example from a shared `commonPipelineEnvironment` which contains information which has been provided by a previous step in the pipeline via an output. [Example](https://github.com/SAP/jenkins-library/blob/master/resources/metadata/githubrelease.yaml)
* **secrets** allow to specify references to Jenkins credentials which can be used in the `groovy` library. [Example](https://github.com/SAP/jenkins-library/blob/master/resources/metadata/kubernetesdeploy.yaml)
* **outputs** allow to write to dedicated outputs like
* Influx metrics. [Example](https://github.com/SAP/jenkins-library/blob/master/resources/metadata/checkmarx.yaml)
* Sharing data via `commonPipelineEnvironment` which can be used by another step as input
* **conditions** allow for example to specify in which case a certain container is used (depending on a configuration parameter). [Example](https://github.com/SAP/jenkins-library/blob/master/resources/metadata/kubernetesdeploy.yaml)
## Logging
to be added
Logging is done through [sirupsen/logrus](https://github.com/sirupsen/logrus) framework.
It can conveniently be accessed through:
```golang
import (
"github.com/SAP/jenkins-library/pkg/log"
)
func myStep ...
...
log.Entry().Info("This is my info.")
...
}
```
If a fatal error occurs your code should act similar to:
```golang
...
if err != nil {
log.Entry().
WithError(err).
Fatal("failed to execute step ...")
}
```
Calling `Fatal` results in an `os.Exit(0)` and before exiting some cleanup actions (e.g. writing output data, writing telemetry data if not deactivated by the user, ...) are performed.
## Error handling

View File

@@ -19,10 +19,11 @@ import (
piperHttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/bmatcuk/doublestar"
)
func checkmarxExecuteScan(config checkmarxExecuteScanOptions, influx *checkmarxExecuteScanInflux) error {
func checkmarxExecuteScan(config checkmarxExecuteScanOptions, telemetryData *telemetry.CustomData, influx *checkmarxExecuteScanInflux) error {
client := &piperHttp.Client{}
sys, err := checkmarx.NewSystemInstance(client, config.ServerURL, config.Username, config.Password)
if err != nil {

View File

@@ -156,11 +156,10 @@ func (i *checkmarxExecuteScanInflux) persist(path, resourceName string) {
}
}
var myCheckmarxExecuteScanOptions checkmarxExecuteScanOptions
// CheckmarxExecuteScanCommand Checkmarx is the recommended tool for security scans of JavaScript, iOS, Swift and Ruby code.
func CheckmarxExecuteScanCommand() *cobra.Command {
metadata := checkmarxExecuteScanMetadata()
var stepConfig checkmarxExecuteScanOptions
var startTime time.Time
var influx checkmarxExecuteScanInflux
@@ -181,9 +180,9 @@ thresholds instead of ` + "`" + `percentage` + "`" + ` whereas we strongly recom
startTime = time.Now()
log.SetStepName("checkmarxExecuteScan")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "checkmarxExecuteScan", &myCheckmarxExecuteScanOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "checkmarxExecuteScan", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -194,39 +193,37 @@ thresholds instead of ` + "`" + `percentage` + "`" + ` whereas we strongly recom
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "checkmarxExecuteScan")
// ToDo: pass telemetryData to step
err := checkmarxExecuteScan(myCheckmarxExecuteScanOptions, &influx)
checkmarxExecuteScan(stepConfig, &telemetryData, &influx)
telemetryData.ErrorCode = "0"
return err
},
}
addCheckmarxExecuteScanFlags(createCheckmarxExecuteScanCmd)
addCheckmarxExecuteScanFlags(createCheckmarxExecuteScanCmd, &stepConfig)
return createCheckmarxExecuteScanCmd
}
func addCheckmarxExecuteScanFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&myCheckmarxExecuteScanOptions.AvoidDuplicateProjectScans, "avoidDuplicateProjectScans", false, "Whether duplicate scans of the same project state shall be avoided or not")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.FilterPattern, "filterPattern", "!**/node_modules/**, !**/.xmake/**, !**/*_test.go, !**/vendor/**/*.go, **/*.html, **/*.xml, **/*.go, **/*.py, **/*.js, **/*.scala, **/*.ts", "The filter pattern used to zip the files relevant for scanning, patterns can be negated by setting an exclamation mark in front i.e. `!test/*.js` would avoid adding any javascript files located in the test directory")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.FullScanCycle, "fullScanCycle", "5", "Indicates how often a full scan should happen between the incremental scans when activated")
cmd.Flags().BoolVar(&myCheckmarxExecuteScanOptions.FullScansScheduled, "fullScansScheduled", true, "Whether full scans are to be scheduled or not. Should be used in relation with `incremental` and `fullScanCycle`")
cmd.Flags().BoolVar(&myCheckmarxExecuteScanOptions.GeneratePdfReport, "generatePdfReport", true, "Whether to generate a PDF report of the analysis results or not")
cmd.Flags().BoolVar(&myCheckmarxExecuteScanOptions.Incremental, "incremental", true, "Whether incremental scans are to be applied which optimizes the scan time but might reduce detection capabilities. Therefore full scans are still required from time to time and should be scheduled via `fullScansScheduled` and `fullScanCycle`")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.Password, "password", os.Getenv("PIPER_password"), "The password to authenticate")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.Preset, "preset", os.Getenv("PIPER_preset"), "The preset to use for scanning, if not set explicitly the step will attempt to look up the project's setting based on the availability of `checkmarxCredentialsId`")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "The name of the Checkmarx project to scan into")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "Used to supply the name for the newly created PR project branch when being used in pull request scenarios")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL pointing to the root of the Checkmarx server to be used")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.SourceEncoding, "sourceEncoding", "1", "The source encoding to be used, if not set explicitly the project's default will be used")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.TeamID, "teamId", os.Getenv("PIPER_teamId"), "The group ID related to your team which can be obtained via the Pipeline Syntax plugin as described in the `Details` section")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.TeamName, "teamName", os.Getenv("PIPER_teamName"), "The full name of the team to assign newly created projects to which is preferred to teamId")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.Username, "username", os.Getenv("PIPER_username"), "The username to authenticate")
cmd.Flags().BoolVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdEnabled, "vulnerabilityThresholdEnabled", true, "Whether the thresholds are enabled or not. If enabled the build will be set to `vulnerabilityThresholdResult` in case a specific threshold value is exceeded")
cmd.Flags().IntVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdHigh, "vulnerabilityThresholdHigh", 100, "The specific threshold for high severity findings")
cmd.Flags().IntVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdLow, "vulnerabilityThresholdLow", 10, "The specific threshold for low severity findings")
cmd.Flags().IntVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdMedium, "vulnerabilityThresholdMedium", 100, "The specific threshold for medium severity findings")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdResult, "vulnerabilityThresholdResult", "FAILURE", "The result of the build in case thresholds are enabled and exceeded")
cmd.Flags().StringVar(&myCheckmarxExecuteScanOptions.VulnerabilityThresholdUnit, "vulnerabilityThresholdUnit", "percentage", "The unit for the threshold to apply.")
func addCheckmarxExecuteScanFlags(cmd *cobra.Command, stepConfig *checkmarxExecuteScanOptions) {
cmd.Flags().BoolVar(&stepConfig.AvoidDuplicateProjectScans, "avoidDuplicateProjectScans", false, "Whether duplicate scans of the same project state shall be avoided or not")
cmd.Flags().StringVar(&stepConfig.FilterPattern, "filterPattern", "!**/node_modules/**, !**/.xmake/**, !**/*_test.go, !**/vendor/**/*.go, **/*.html, **/*.xml, **/*.go, **/*.py, **/*.js, **/*.scala, **/*.ts", "The filter pattern used to zip the files relevant for scanning, patterns can be negated by setting an exclamation mark in front i.e. `!test/*.js` would avoid adding any javascript files located in the test directory")
cmd.Flags().StringVar(&stepConfig.FullScanCycle, "fullScanCycle", "5", "Indicates how often a full scan should happen between the incremental scans when activated")
cmd.Flags().BoolVar(&stepConfig.FullScansScheduled, "fullScansScheduled", true, "Whether full scans are to be scheduled or not. Should be used in relation with `incremental` and `fullScanCycle`")
cmd.Flags().BoolVar(&stepConfig.GeneratePdfReport, "generatePdfReport", true, "Whether to generate a PDF report of the analysis results or not")
cmd.Flags().BoolVar(&stepConfig.Incremental, "incremental", true, "Whether incremental scans are to be applied which optimizes the scan time but might reduce detection capabilities. Therefore full scans are still required from time to time and should be scheduled via `fullScansScheduled` and `fullScanCycle`")
cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "The password to authenticate")
cmd.Flags().StringVar(&stepConfig.Preset, "preset", os.Getenv("PIPER_preset"), "The preset to use for scanning, if not set explicitly the step will attempt to look up the project's setting based on the availability of `checkmarxCredentialsId`")
cmd.Flags().StringVar(&stepConfig.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "The name of the Checkmarx project to scan into")
cmd.Flags().StringVar(&stepConfig.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "Used to supply the name for the newly created PR project branch when being used in pull request scenarios")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL pointing to the root of the Checkmarx server to be used")
cmd.Flags().StringVar(&stepConfig.SourceEncoding, "sourceEncoding", "1", "The source encoding to be used, if not set explicitly the project's default will be used")
cmd.Flags().StringVar(&stepConfig.TeamID, "teamId", os.Getenv("PIPER_teamId"), "The group ID related to your team which can be obtained via the Pipeline Syntax plugin as described in the `Details` section")
cmd.Flags().StringVar(&stepConfig.TeamName, "teamName", os.Getenv("PIPER_teamName"), "The full name of the team to assign newly created projects to which is preferred to teamId")
cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "The username to authenticate")
cmd.Flags().BoolVar(&stepConfig.VulnerabilityThresholdEnabled, "vulnerabilityThresholdEnabled", true, "Whether the thresholds are enabled or not. If enabled the build will be set to `vulnerabilityThresholdResult` in case a specific threshold value is exceeded")
cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdHigh, "vulnerabilityThresholdHigh", 100, "The specific threshold for high severity findings")
cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdLow, "vulnerabilityThresholdLow", 10, "The specific threshold for low severity findings")
cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdMedium, "vulnerabilityThresholdMedium", 100, "The specific threshold for medium severity findings")
cmd.Flags().StringVar(&stepConfig.VulnerabilityThresholdResult, "vulnerabilityThresholdResult", "FAILURE", "The result of the build in case thresholds are enabled and exceeded")
cmd.Flags().StringVar(&stepConfig.VulnerabilityThresholdUnit, "vulnerabilityThresholdUnit", "percentage", "The unit for the threshold to apply.")
cmd.MarkFlagRequired("password")
cmd.MarkFlagRequired("projectName")

View File

@@ -6,22 +6,22 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func detectExecuteScan(myDetectExecuteScanOptions detectExecuteScanOptions) error {
func detectExecuteScan(config detectExecuteScanOptions, telemetryData *telemetry.CustomData) {
c := command.Command{}
// reroute command output to logging framework
c.Stdout(log.Entry().Writer())
c.Stderr(log.Entry().Writer())
runDetect(myDetectExecuteScanOptions, &c)
return nil
runDetect(config, &c)
}
func runDetect(myDetectExecuteScanOptions detectExecuteScanOptions, command shellRunner) {
func runDetect(config detectExecuteScanOptions, command shellRunner) {
// detect execution details, see https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/88440888/Sample+Synopsys+Detect+Scan+Configuration+Scenarios+for+Black+Duck
args := []string{"bash <(curl -s https://detect.synopsys.com/detect.sh)"}
args = addDetectArgs(args, myDetectExecuteScanOptions)
args = addDetectArgs(args, config)
script := strings.Join(args, " ")
command.Dir(".")
@@ -30,32 +30,31 @@ func runDetect(myDetectExecuteScanOptions detectExecuteScanOptions, command shel
if err != nil {
log.Entry().
WithError(err).
WithField("command", myKarmaExecuteTestsOptions.InstallCommand).
Fatal("failed to execute detect scan")
}
}
func addDetectArgs(args []string, myDetectExecuteScanOptions detectExecuteScanOptions) []string {
func addDetectArgs(args []string, config detectExecuteScanOptions) []string {
args = append(args, myDetectExecuteScanOptions.ScanProperties...)
args = append(args, config.ScanProperties...)
args = append(args, fmt.Sprintf("--blackduck.url=%v", myDetectExecuteScanOptions.ServerURL))
args = append(args, fmt.Sprintf("--blackduck.api.token=%v", myDetectExecuteScanOptions.APIToken))
args = append(args, fmt.Sprintf("--blackduck.url=%v", config.ServerURL))
args = append(args, fmt.Sprintf("--blackduck.api.token=%v", config.APIToken))
args = append(args, fmt.Sprintf("--detect.project.name=%v", myDetectExecuteScanOptions.ProjectName))
args = append(args, fmt.Sprintf("--detect.project.version.name=%v", myDetectExecuteScanOptions.ProjectVersion))
codeLocation := myDetectExecuteScanOptions.CodeLocation
if len(codeLocation) == 0 && len(myDetectExecuteScanOptions.ProjectName) > 0 {
codeLocation = fmt.Sprintf("%v/%v", myDetectExecuteScanOptions.ProjectName, myDetectExecuteScanOptions.ProjectVersion)
args = append(args, fmt.Sprintf("--detect.project.name=%v", config.ProjectName))
args = append(args, fmt.Sprintf("--detect.project.version.name=%v", config.ProjectVersion))
codeLocation := config.CodeLocation
if len(codeLocation) == 0 && len(config.ProjectName) > 0 {
codeLocation = fmt.Sprintf("%v/%v", config.ProjectName, config.ProjectVersion)
}
args = append(args, fmt.Sprintf("--detect.code.location.name=%v", codeLocation))
if sliceContains(myDetectExecuteScanOptions.Scanners, "signature") {
args = append(args, fmt.Sprintf("--detect.blackduck.signature.scanner.paths=%v", strings.Join(myDetectExecuteScanOptions.ScanPaths, ",")))
if sliceContains(config.Scanners, "signature") {
args = append(args, fmt.Sprintf("--detect.blackduck.signature.scanner.paths=%v", strings.Join(config.ScanPaths, ",")))
}
if sliceContains(myDetectExecuteScanOptions.Scanners, "source") {
args = append(args, fmt.Sprintf("--detect.source.path=%v", myDetectExecuteScanOptions.ScanPaths[0]))
if sliceContains(config.Scanners, "source") {
args = append(args, fmt.Sprintf("--detect.source.path=%v", config.ScanPaths[0]))
}
return args
}

View File

@@ -22,11 +22,10 @@ type detectExecuteScanOptions struct {
ServerURL string `json:"serverUrl,omitempty"`
}
var myDetectExecuteScanOptions detectExecuteScanOptions
// DetectExecuteScanCommand Executes Synopsis Detect scan
func DetectExecuteScanCommand() *cobra.Command {
metadata := detectExecuteScanMetadata()
var stepConfig detectExecuteScanOptions
var startTime time.Time
var createDetectExecuteScanCmd = &cobra.Command{
@@ -37,9 +36,9 @@ func DetectExecuteScanCommand() *cobra.Command {
startTime = time.Now()
log.SetStepName("detectExecuteScan")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "detectExecuteScan", &myDetectExecuteScanOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "detectExecuteScan", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -49,26 +48,24 @@ func DetectExecuteScanCommand() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "detectExecuteScan")
// ToDo: pass telemetryData to step
err := detectExecuteScan(myDetectExecuteScanOptions)
detectExecuteScan(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addDetectExecuteScanFlags(createDetectExecuteScanCmd)
addDetectExecuteScanFlags(createDetectExecuteScanCmd, &stepConfig)
return createDetectExecuteScanCmd
}
func addDetectExecuteScanFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&myDetectExecuteScanOptions.APIToken, "apiToken", os.Getenv("PIPER_apiToken"), "Api token to be used for connectivity with Synopsis Detect server.")
cmd.Flags().StringVar(&myDetectExecuteScanOptions.CodeLocation, "codeLocation", os.Getenv("PIPER_codeLocation"), "An override for the name Detect will use for the scan file it creates.")
cmd.Flags().StringVar(&myDetectExecuteScanOptions.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "Name of the Synopsis Detect (formerly BlackDuck) project.")
cmd.Flags().StringVar(&myDetectExecuteScanOptions.ProjectVersion, "projectVersion", os.Getenv("PIPER_projectVersion"), "Version of the Synopsis Detect (formerly BlackDuck) project.")
cmd.Flags().StringSliceVar(&myDetectExecuteScanOptions.Scanners, "scanners", []string{"signature"}, "List of scanners to be used for Synopsis Detect (formerly BlackDuck) scan.")
cmd.Flags().StringSliceVar(&myDetectExecuteScanOptions.ScanPaths, "scanPaths", []string{"."}, "List of paths which should be scanned by the Synopsis Detect (formerly BlackDuck) scan.")
cmd.Flags().StringSliceVar(&myDetectExecuteScanOptions.ScanProperties, "scanProperties", []string{"--blackduck.signature.scanner.memory=4096", "--blackduck.timeout=6000", "--blackduck.trust.cert=true", "--detect.policy.check.fail.on.severities=BLOCKER,CRITICAL,MAJOR", "--detect.report.timeout=4800", "--logging.level.com.synopsys.integration=DEBUG"}, "Properties passed to the Synopsis Detect (formerly BlackDuck) scan. You can find details in the [Synopsis Detect documentation](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/622846/Using+Synopsys+Detect+Properties)")
cmd.Flags().StringVar(&myDetectExecuteScanOptions.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "Server url to the Synopsis Detect (formerly BlackDuck) Server.")
func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScanOptions) {
cmd.Flags().StringVar(&stepConfig.APIToken, "apiToken", os.Getenv("PIPER_apiToken"), "Api token to be used for connectivity with Synopsis Detect server.")
cmd.Flags().StringVar(&stepConfig.CodeLocation, "codeLocation", os.Getenv("PIPER_codeLocation"), "An override for the name Detect will use for the scan file it creates.")
cmd.Flags().StringVar(&stepConfig.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "Name of the Synopsis Detect (formerly BlackDuck) project.")
cmd.Flags().StringVar(&stepConfig.ProjectVersion, "projectVersion", os.Getenv("PIPER_projectVersion"), "Version of the Synopsis Detect (formerly BlackDuck) project.")
cmd.Flags().StringSliceVar(&stepConfig.Scanners, "scanners", []string{"signature"}, "List of scanners to be used for Synopsis Detect (formerly BlackDuck) scan.")
cmd.Flags().StringSliceVar(&stepConfig.ScanPaths, "scanPaths", []string{"."}, "List of paths which should be scanned by the Synopsis Detect (formerly BlackDuck) scan.")
cmd.Flags().StringSliceVar(&stepConfig.ScanProperties, "scanProperties", []string{"--blackduck.signature.scanner.memory=4096", "--blackduck.timeout=6000", "--blackduck.trust.cert=true", "--detect.policy.check.fail.on.severities=BLOCKER,CRITICAL,MAJOR", "--detect.report.timeout=4800", "--logging.level.com.synopsys.integration=DEBUG"}, "Properties passed to the Synopsis Detect (formerly BlackDuck) scan. You can find details in the [Synopsis Detect documentation](https://synopsys.atlassian.net/wiki/spaces/INTDOCS/pages/622846/Using+Synopsys+Detect+Properties)")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "Server url to the Synopsis Detect (formerly BlackDuck) Server.")
cmd.MarkFlagRequired("apiToken")
cmd.MarkFlagRequired("projectName")

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v28/github"
"github.com/pkg/errors"
@@ -18,30 +19,28 @@ type githubIssueService interface {
Edit(ctx context.Context, owner string, repo string, number int, issue *github.IssueRequest) (*github.Issue, *github.Response, error)
}
func githubCreatePullRequest(myGithubCreatePullRequestOptions githubCreatePullRequestOptions) error {
ctx, client, err := piperGithub.NewClient(myGithubCreatePullRequestOptions.Token, myGithubCreatePullRequestOptions.APIURL, "")
func githubCreatePullRequest(config githubCreatePullRequestOptions, telemetryData *telemetry.CustomData) {
ctx, client, err := piperGithub.NewClient(config.Token, config.APIURL, "")
if err != nil {
log.Entry().WithError(err).Fatal("Failed to get GitHub client")
}
err = runGithubCreatePullRequest(ctx, &myGithubCreatePullRequestOptions, client.PullRequests, client.Issues)
err = runGithubCreatePullRequest(ctx, &config, client.PullRequests, client.Issues)
if err != nil {
log.Entry().WithError(err).Fatal("Failed to create GitHub pull request")
}
return nil
}
func runGithubCreatePullRequest(ctx context.Context, myGithubCreatePullRequestOptions *githubCreatePullRequestOptions, ghPRService githubPRService, ghIssueService githubIssueService) error {
func runGithubCreatePullRequest(ctx context.Context, config *githubCreatePullRequestOptions, ghPRService githubPRService, ghIssueService githubIssueService) error {
prRequest := github.NewPullRequest{
Title: &myGithubCreatePullRequestOptions.Title,
Head: &myGithubCreatePullRequestOptions.Head,
Base: &myGithubCreatePullRequestOptions.Base,
Body: &myGithubCreatePullRequestOptions.Body,
Title: &config.Title,
Head: &config.Head,
Base: &config.Base,
Body: &config.Body,
}
newPR, resp, err := ghPRService.Create(ctx, myGithubCreatePullRequestOptions.Owner, myGithubCreatePullRequestOptions.Repository, &prRequest)
newPR, resp, err := ghPRService.Create(ctx, config.Owner, config.Repository, &prRequest)
if err != nil {
log.Entry().Errorf("GitHub response code %v", resp.Status)
return errors.Wrap(err, "Error occured when creating pull request")
@@ -49,11 +48,11 @@ func runGithubCreatePullRequest(ctx context.Context, myGithubCreatePullRequestOp
log.Entry().Debugf("New pull request created: %v", newPR)
issueRequest := github.IssueRequest{
Labels: &myGithubCreatePullRequestOptions.Labels,
Assignees: &myGithubCreatePullRequestOptions.Assignees,
Labels: &config.Labels,
Assignees: &config.Assignees,
}
updatedPr, resp, err := ghIssueService.Edit(ctx, myGithubCreatePullRequestOptions.Owner, myGithubCreatePullRequestOptions.Repository, newPR.GetNumber(), &issueRequest)
updatedPr, resp, err := ghIssueService.Edit(ctx, config.Owner, config.Repository, newPR.GetNumber(), &issueRequest)
if err != nil {
log.Entry().Errorf("GitHub response code %v", resp.Status)
return errors.Wrap(err, "Error occured when editing pull request")

View File

@@ -25,11 +25,10 @@ type githubCreatePullRequestOptions struct {
Labels []string `json:"labels,omitempty"`
}
var myGithubCreatePullRequestOptions githubCreatePullRequestOptions
// GithubCreatePullRequestCommand Create a pull request on GitHub
func GithubCreatePullRequestCommand() *cobra.Command {
metadata := githubCreatePullRequestMetadata()
var stepConfig githubCreatePullRequestOptions
var startTime time.Time
var createGithubCreatePullRequestCmd = &cobra.Command{
@@ -42,9 +41,9 @@ It can for example be used for GitOps scenarios or for scenarios where you want
startTime = time.Now()
log.SetStepName("githubCreatePullRequest")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "githubCreatePullRequest", &myGithubCreatePullRequestOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "githubCreatePullRequest", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -54,29 +53,27 @@ It can for example be used for GitOps scenarios or for scenarios where you want
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "githubCreatePullRequest")
// ToDo: pass telemetryData to step
err := githubCreatePullRequest(myGithubCreatePullRequestOptions)
githubCreatePullRequest(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addGithubCreatePullRequestFlags(createGithubCreatePullRequestCmd)
addGithubCreatePullRequestFlags(createGithubCreatePullRequestCmd, &stepConfig)
return createGithubCreatePullRequestCmd
}
func addGithubCreatePullRequestFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVar(&myGithubCreatePullRequestOptions.Assignees, "assignees", []string{}, "Login names of users to which the PR should be assigned to.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Base, "base", os.Getenv("PIPER_base"), "The name of the branch you want the changes pulled into.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Body, "body", os.Getenv("PIPER_body"), "The description text of the pull request in markdown format.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.APIURL, "apiUrl", "https://api.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Head, "head", os.Getenv("PIPER_head"), "The name of the branch where your changes are implemented.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.ServerURL, "serverUrl", "https://github.com", "GitHub server url for end-user access.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Title, "title", os.Getenv("PIPER_title"), "Title of the pull request.")
cmd.Flags().StringVar(&myGithubCreatePullRequestOptions.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
cmd.Flags().StringSliceVar(&myGithubCreatePullRequestOptions.Labels, "labels", []string{}, "Labels to be added to the pull request.")
func addGithubCreatePullRequestFlags(cmd *cobra.Command, stepConfig *githubCreatePullRequestOptions) {
cmd.Flags().StringSliceVar(&stepConfig.Assignees, "assignees", []string{}, "Login names of users to which the PR should be assigned to.")
cmd.Flags().StringVar(&stepConfig.Base, "base", os.Getenv("PIPER_base"), "The name of the branch you want the changes pulled into.")
cmd.Flags().StringVar(&stepConfig.Body, "body", os.Getenv("PIPER_body"), "The description text of the pull request in markdown format.")
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", "https://api.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.Head, "head", os.Getenv("PIPER_head"), "The name of the branch where your changes are implemented.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", "https://github.com", "GitHub server url for end-user access.")
cmd.Flags().StringVar(&stepConfig.Title, "title", os.Getenv("PIPER_title"), "Title of the pull request.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
cmd.Flags().StringSliceVar(&stepConfig.Labels, "labels", []string{}, "Labels to be added to the pull request.")
cmd.MarkFlagRequired("base")
cmd.MarkFlagRequired("body")

View File

@@ -9,6 +9,7 @@ import (
"strings"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/google/go-github/v28/github"
"github.com/pkg/errors"
@@ -27,29 +28,27 @@ type githubIssueClient interface {
ListByRepo(ctx context.Context, owner string, repo string, opt *github.IssueListByRepoOptions) ([]*github.Issue, *github.Response, error)
}
func githubPublishRelease(myGithubPublishReleaseOptions githubPublishReleaseOptions) error {
ctx, client, err := piperGithub.NewClient(myGithubPublishReleaseOptions.Token, myGithubPublishReleaseOptions.APIURL, myGithubPublishReleaseOptions.UploadURL)
func githubPublishRelease(config githubPublishReleaseOptions, telemetryData *telemetry.CustomData) {
ctx, client, err := piperGithub.NewClient(config.Token, config.APIURL, config.UploadURL)
if err != nil {
log.Entry().WithError(err).Fatal("Failed to get GitHub client.")
}
err = runGithubPublishRelease(ctx, &myGithubPublishReleaseOptions, client.Repositories, client.Issues)
err = runGithubPublishRelease(ctx, &config, client.Repositories, client.Issues)
if err != nil {
log.Entry().WithError(err).Fatal("Failed to publish GitHub release.")
}
return nil
}
func runGithubPublishRelease(ctx context.Context, myGithubPublishReleaseOptions *githubPublishReleaseOptions, ghRepoClient githubRepoClient, ghIssueClient githubIssueClient) error {
func runGithubPublishRelease(ctx context.Context, config *githubPublishReleaseOptions, ghRepoClient githubRepoClient, ghIssueClient githubIssueClient) error {
var publishedAt github.Timestamp
lastRelease, resp, err := ghRepoClient.GetLatestRelease(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository)
lastRelease, resp, err := ghRepoClient.GetLatestRelease(ctx, config.Owner, config.Repository)
if err != nil {
if resp.StatusCode == 404 {
//no previous release found -> first release
myGithubPublishReleaseOptions.AddDeltaToLastRelease = false
config.AddDeltaToLastRelease = false
log.Entry().Debug("This is the first release.")
} else {
return errors.Wrap(err, "Error occured when retrieving latest GitHub release.")
@@ -59,45 +58,45 @@ func runGithubPublishRelease(ctx context.Context, myGithubPublishReleaseOptions
log.Entry().Debugf("Previous GitHub release published: '%v'", publishedAt)
//updating assets only supported on latest release
if len(myGithubPublishReleaseOptions.AssetPath) > 0 && myGithubPublishReleaseOptions.Version == "latest" {
return uploadReleaseAsset(ctx, lastRelease.GetID(), myGithubPublishReleaseOptions, ghRepoClient)
if len(config.AssetPath) > 0 && config.Version == "latest" {
return uploadReleaseAsset(ctx, lastRelease.GetID(), config, ghRepoClient)
}
releaseBody := ""
if len(myGithubPublishReleaseOptions.ReleaseBodyHeader) > 0 {
releaseBody += myGithubPublishReleaseOptions.ReleaseBodyHeader + "\n"
if len(config.ReleaseBodyHeader) > 0 {
releaseBody += config.ReleaseBodyHeader + "\n"
}
if myGithubPublishReleaseOptions.AddClosedIssues {
releaseBody += getClosedIssuesText(ctx, publishedAt, myGithubPublishReleaseOptions, ghIssueClient)
if config.AddClosedIssues {
releaseBody += getClosedIssuesText(ctx, publishedAt, config, ghIssueClient)
}
if myGithubPublishReleaseOptions.AddDeltaToLastRelease {
releaseBody += getReleaseDeltaText(myGithubPublishReleaseOptions, lastRelease)
if config.AddDeltaToLastRelease {
releaseBody += getReleaseDeltaText(config, lastRelease)
}
release := github.RepositoryRelease{
TagName: &myGithubPublishReleaseOptions.Version,
TargetCommitish: &myGithubPublishReleaseOptions.Commitish,
Name: &myGithubPublishReleaseOptions.Version,
TagName: &config.Version,
TargetCommitish: &config.Commitish,
Name: &config.Version,
Body: &releaseBody,
}
createdRelease, _, err := ghRepoClient.CreateRelease(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository, &release)
createdRelease, _, err := ghRepoClient.CreateRelease(ctx, config.Owner, config.Repository, &release)
if err != nil {
return errors.Wrapf(err, "Creation of release '%v' failed", *release.TagName)
}
log.Entry().Infof("Release %v created on %v/%v", *createdRelease.TagName, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository)
log.Entry().Infof("Release %v created on %v/%v", *createdRelease.TagName, config.Owner, config.Repository)
if len(myGithubPublishReleaseOptions.AssetPath) > 0 {
return uploadReleaseAsset(ctx, createdRelease.GetID(), myGithubPublishReleaseOptions, ghRepoClient)
if len(config.AssetPath) > 0 {
return uploadReleaseAsset(ctx, createdRelease.GetID(), config, ghRepoClient)
}
return nil
}
func getClosedIssuesText(ctx context.Context, publishedAt github.Timestamp, myGithubPublishReleaseOptions *githubPublishReleaseOptions, ghIssueClient githubIssueClient) string {
func getClosedIssuesText(ctx context.Context, publishedAt github.Timestamp, config *githubPublishReleaseOptions, ghIssueClient githubIssueClient) string {
closedIssuesText := ""
options := github.IssueListByRepoOptions{
@@ -105,10 +104,10 @@ func getClosedIssuesText(ctx context.Context, publishedAt github.Timestamp, myGi
Direction: "asc",
Since: publishedAt.Time,
}
if len(myGithubPublishReleaseOptions.Labels) > 0 {
options.Labels = myGithubPublishReleaseOptions.Labels
if len(config.Labels) > 0 {
options.Labels = config.Labels
}
ghIssues, _, err := ghIssueClient.ListByRepo(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository, &options)
ghIssues, _, err := ghIssueClient.ListByRepo(ctx, config.Owner, config.Repository, &options)
if err != nil {
log.Entry().WithError(err).Error("Failed to get GitHub issues.")
}
@@ -117,10 +116,10 @@ func getClosedIssuesText(ctx context.Context, publishedAt github.Timestamp, myGi
issueTexts := []string{"**List of closed issues since last release**"}
for _, issue := range ghIssues {
if issue.IsPullRequest() && !isExcluded(issue, myGithubPublishReleaseOptions.ExcludeLabels) {
if issue.IsPullRequest() && !isExcluded(issue, config.ExcludeLabels) {
prTexts = append(prTexts, fmt.Sprintf("[#%v](%v): %v", issue.GetNumber(), issue.GetHTMLURL(), issue.GetTitle()))
log.Entry().Debugf("Added PR #%v to release", issue.GetNumber())
} else if !issue.IsPullRequest() && !isExcluded(issue, myGithubPublishReleaseOptions.ExcludeLabels) {
} else if !issue.IsPullRequest() && !isExcluded(issue, config.ExcludeLabels) {
issueTexts = append(issueTexts, fmt.Sprintf("[#%v](%v): %v", issue.GetNumber(), issue.GetHTMLURL(), issue.GetTitle()))
log.Entry().Debugf("Added Issue #%v to release", issue.GetNumber())
}
@@ -136,7 +135,7 @@ func getClosedIssuesText(ctx context.Context, publishedAt github.Timestamp, myGi
return closedIssuesText
}
func getReleaseDeltaText(myGithubPublishReleaseOptions *githubPublishReleaseOptions, lastRelease *github.RepositoryRelease) string {
func getReleaseDeltaText(config *githubPublishReleaseOptions, lastRelease *github.RepositoryRelease) string {
releaseDeltaText := ""
//add delta link to previous release
@@ -144,58 +143,58 @@ func getReleaseDeltaText(myGithubPublishReleaseOptions *githubPublishReleaseOpti
releaseDeltaText += fmt.Sprintf(
"[%v...%v](%v/%v/%v/compare/%v...%v)\n",
lastRelease.GetTagName(),
myGithubPublishReleaseOptions.Version,
myGithubPublishReleaseOptions.ServerURL,
myGithubPublishReleaseOptions.Owner,
myGithubPublishReleaseOptions.Repository,
lastRelease.GetTagName(), myGithubPublishReleaseOptions.Version,
config.Version,
config.ServerURL,
config.Owner,
config.Repository,
lastRelease.GetTagName(), config.Version,
)
return releaseDeltaText
}
func uploadReleaseAsset(ctx context.Context, releaseID int64, myGithubPublishReleaseOptions *githubPublishReleaseOptions, ghRepoClient githubRepoClient) error {
func uploadReleaseAsset(ctx context.Context, releaseID int64, config *githubPublishReleaseOptions, ghRepoClient githubRepoClient) error {
assets, _, err := ghRepoClient.ListReleaseAssets(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository, releaseID, &github.ListOptions{})
assets, _, err := ghRepoClient.ListReleaseAssets(ctx, config.Owner, config.Repository, releaseID, &github.ListOptions{})
if err != nil {
return errors.Wrap(err, "Failed to get list of release assets.")
}
var assetID int64
for _, a := range assets {
if a.GetName() == filepath.Base(myGithubPublishReleaseOptions.AssetPath) {
if a.GetName() == filepath.Base(config.AssetPath) {
assetID = a.GetID()
break
}
}
if assetID != 0 {
//asset needs to be deleted first since API does not allow for replacement
_, err := ghRepoClient.DeleteReleaseAsset(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository, assetID)
_, err := ghRepoClient.DeleteReleaseAsset(ctx, config.Owner, config.Repository, assetID)
if err != nil {
return errors.Wrap(err, "Failed to delete release asset.")
}
}
mediaType := mime.TypeByExtension(filepath.Ext(myGithubPublishReleaseOptions.AssetPath))
mediaType := mime.TypeByExtension(filepath.Ext(config.AssetPath))
if mediaType == "" {
mediaType = "application/octet-stream"
}
log.Entry().Debugf("Using mediaType '%v'", mediaType)
name := filepath.Base(myGithubPublishReleaseOptions.AssetPath)
name := filepath.Base(config.AssetPath)
log.Entry().Debugf("Using file name '%v'", name)
opts := github.UploadOptions{
Name: name,
MediaType: mediaType,
}
file, err := os.Open(myGithubPublishReleaseOptions.AssetPath)
file, err := os.Open(config.AssetPath)
defer file.Close()
if err != nil {
return errors.Wrapf(err, "Failed to load release asset '%v'", myGithubPublishReleaseOptions.AssetPath)
return errors.Wrapf(err, "Failed to load release asset '%v'", config.AssetPath)
}
log.Entry().Info("Starting to upload release asset.")
asset, _, err := ghRepoClient.UploadReleaseAsset(ctx, myGithubPublishReleaseOptions.Owner, myGithubPublishReleaseOptions.Repository, releaseID, &opts, file)
asset, _, err := ghRepoClient.UploadReleaseAsset(ctx, config.Owner, config.Repository, releaseID, &opts, file)
if err != nil {
return errors.Wrap(err, "Failed to upload release asset.")
}

View File

@@ -28,11 +28,10 @@ type githubPublishReleaseOptions struct {
Version string `json:"version,omitempty"`
}
var myGithubPublishReleaseOptions githubPublishReleaseOptions
// GithubPublishReleaseCommand Publish a release in GitHub
func GithubPublishReleaseCommand() *cobra.Command {
metadata := githubPublishReleaseMetadata()
var stepConfig githubPublishReleaseOptions
var startTime time.Time
var createGithubPublishReleaseCmd = &cobra.Command{
@@ -52,9 +51,9 @@ The result looks like
startTime = time.Now()
log.SetStepName("githubPublishRelease")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "githubPublishRelease", &myGithubPublishReleaseOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "githubPublishRelease", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -64,32 +63,30 @@ The result looks like
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "githubPublishRelease")
// ToDo: pass telemetryData to step
err := githubPublishRelease(myGithubPublishReleaseOptions)
githubPublishRelease(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addGithubPublishReleaseFlags(createGithubPublishReleaseCmd)
addGithubPublishReleaseFlags(createGithubPublishReleaseCmd, &stepConfig)
return createGithubPublishReleaseCmd
}
func addGithubPublishReleaseFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&myGithubPublishReleaseOptions.AddClosedIssues, "addClosedIssues", false, "If set to `true`, closed issues and merged pull-requests since the last release will added below the `releaseBodyHeader`")
cmd.Flags().BoolVar(&myGithubPublishReleaseOptions.AddDeltaToLastRelease, "addDeltaToLastRelease", false, "If set to `true`, a link will be added to the relese information that brings up all commits since the last release.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.APIURL, "apiUrl", "https://api.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.AssetPath, "assetPath", os.Getenv("PIPER_assetPath"), "Path to a release asset which should be uploaded to the list of release assets.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.Commitish, "commitish", "master", "Target git commitish for the release")
cmd.Flags().StringSliceVar(&myGithubPublishReleaseOptions.ExcludeLabels, "excludeLabels", []string{}, "Allows to exclude issues with dedicated list of labels.")
cmd.Flags().StringSliceVar(&myGithubPublishReleaseOptions.Labels, "labels", []string{}, "Labels to include in issue search.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.ReleaseBodyHeader, "releaseBodyHeader", os.Getenv("PIPER_releaseBodyHeader"), "Content which will appear for the release.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.ServerURL, "serverUrl", "https://github.com", "GitHub server url for end-user access.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.UploadURL, "uploadUrl", "https://uploads.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.Version, "version", os.Getenv("PIPER_version"), "Define the version number which will be written as tag as well as release name.")
func addGithubPublishReleaseFlags(cmd *cobra.Command, stepConfig *githubPublishReleaseOptions) {
cmd.Flags().BoolVar(&stepConfig.AddClosedIssues, "addClosedIssues", false, "If set to `true`, closed issues and merged pull-requests since the last release will added below the `releaseBodyHeader`")
cmd.Flags().BoolVar(&stepConfig.AddDeltaToLastRelease, "addDeltaToLastRelease", false, "If set to `true`, a link will be added to the relese information that brings up all commits since the last release.")
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", "https://api.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.AssetPath, "assetPath", os.Getenv("PIPER_assetPath"), "Path to a release asset which should be uploaded to the list of release assets.")
cmd.Flags().StringVar(&stepConfig.Commitish, "commitish", "master", "Target git commitish for the release")
cmd.Flags().StringSliceVar(&stepConfig.ExcludeLabels, "excludeLabels", []string{}, "Allows to exclude issues with dedicated list of labels.")
cmd.Flags().StringSliceVar(&stepConfig.Labels, "labels", []string{}, "Labels to include in issue search.")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.ReleaseBodyHeader, "releaseBodyHeader", os.Getenv("PIPER_releaseBodyHeader"), "Content which will appear for the release.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", "https://github.com", "GitHub server url for end-user access.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line")
cmd.Flags().StringVar(&stepConfig.UploadURL, "uploadUrl", "https://uploads.github.com", "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.Version, "version", os.Getenv("PIPER_version"), "Define the version number which will be written as tag as well as release name.")
cmd.MarkFlagRequired("apiUrl")
cmd.MarkFlagRequired("owner")

View File

@@ -5,36 +5,36 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func karmaExecuteTests(myKarmaExecuteTestsOptions karmaExecuteTestsOptions) error {
func karmaExecuteTests(config karmaExecuteTestsOptions, telemetryData *telemetry.CustomData) {
c := command.Command{}
// reroute command output to loging framework
// also log stdout as Karma reports into it
c.Stdout(log.Entry().Writer())
c.Stderr(log.Entry().Writer())
runKarma(myKarmaExecuteTestsOptions, &c)
return nil
runKarma(config, &c)
}
func runKarma(myKarmaExecuteTestsOptions karmaExecuteTestsOptions, command execRunner) {
installCommandTokens := tokenize(myKarmaExecuteTestsOptions.InstallCommand)
command.Dir(myKarmaExecuteTestsOptions.ModulePath)
func runKarma(config karmaExecuteTestsOptions, command execRunner) {
installCommandTokens := tokenize(config.InstallCommand)
command.Dir(config.ModulePath)
err := command.RunExecutable(installCommandTokens[0], installCommandTokens[1:]...)
if err != nil {
log.Entry().
WithError(err).
WithField("command", myKarmaExecuteTestsOptions.InstallCommand).
WithField("command", config.InstallCommand).
Fatal("failed to execute install command")
}
runCommandTokens := tokenize(myKarmaExecuteTestsOptions.RunCommand)
command.Dir(myKarmaExecuteTestsOptions.ModulePath)
runCommandTokens := tokenize(config.RunCommand)
command.Dir(config.ModulePath)
err = command.RunExecutable(runCommandTokens[0], runCommandTokens[1:]...)
if err != nil {
log.Entry().
WithError(err).
WithField("command", myKarmaExecuteTestsOptions.RunCommand).
WithField("command", config.RunCommand).
Fatal("failed to execute run command")
}
}

View File

@@ -16,11 +16,10 @@ type karmaExecuteTestsOptions struct {
RunCommand string `json:"runCommand,omitempty"`
}
var myKarmaExecuteTestsOptions karmaExecuteTestsOptions
// KarmaExecuteTestsCommand Executes the Karma test runner
func KarmaExecuteTestsCommand() *cobra.Command {
metadata := karmaExecuteTestsMetadata()
var stepConfig karmaExecuteTestsOptions
var startTime time.Time
var createKarmaExecuteTestsCmd = &cobra.Command{
@@ -41,9 +40,9 @@ In the Docker network, the containers can be referenced by the values provided i
startTime = time.Now()
log.SetStepName("karmaExecuteTests")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "karmaExecuteTests", &myKarmaExecuteTestsOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "karmaExecuteTests", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -53,21 +52,19 @@ In the Docker network, the containers can be referenced by the values provided i
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "karmaExecuteTests")
// ToDo: pass telemetryData to step
err := karmaExecuteTests(myKarmaExecuteTestsOptions)
karmaExecuteTests(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addKarmaExecuteTestsFlags(createKarmaExecuteTestsCmd)
addKarmaExecuteTestsFlags(createKarmaExecuteTestsCmd, &stepConfig)
return createKarmaExecuteTestsCmd
}
func addKarmaExecuteTestsFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&myKarmaExecuteTestsOptions.InstallCommand, "installCommand", "npm install --quiet", "The command that is executed to install the test tool.")
cmd.Flags().StringVar(&myKarmaExecuteTestsOptions.ModulePath, "modulePath", ".", "Define the path of the module to execute tests on.")
cmd.Flags().StringVar(&myKarmaExecuteTestsOptions.RunCommand, "runCommand", "npm run karma", "The command that is executed to start the tests.")
func addKarmaExecuteTestsFlags(cmd *cobra.Command, stepConfig *karmaExecuteTestsOptions) {
cmd.Flags().StringVar(&stepConfig.InstallCommand, "installCommand", "npm install --quiet", "The command that is executed to install the test tool.")
cmd.Flags().StringVar(&stepConfig.ModulePath, "modulePath", ".", "Define the path of the module to execute tests on.")
cmd.Flags().StringVar(&stepConfig.RunCommand, "runCommand", "npm run karma", "The command that is executed to start the tests.")
cmd.MarkFlagRequired("installCommand")
cmd.MarkFlagRequired("modulePath")

View File

@@ -12,14 +12,14 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func kubernetesDeploy(config kubernetesDeployOptions) error {
func kubernetesDeploy(config kubernetesDeployOptions, telemetryData *telemetry.CustomData) {
c := command.Command{}
// reroute stderr output to logging framework, stdout will be used for command interactions
c.Stderr(log.Entry().Writer())
runKubernetesDeploy(config, &c, log.Entry().Writer())
return nil
}
func runKubernetesDeploy(config kubernetesDeployOptions, command envExecRunner, stdout io.Writer) {

View File

@@ -33,11 +33,10 @@ type kubernetesDeployOptions struct {
TillerNamespace string `json:"tillerNamespace,omitempty"`
}
var myKubernetesDeployOptions kubernetesDeployOptions
// KubernetesDeployCommand Deployment to Kubernetes test or production namespace within the specified Kubernetes cluster.
func KubernetesDeployCommand() *cobra.Command {
metadata := kubernetesDeployMetadata()
var stepConfig kubernetesDeployOptions
var startTime time.Time
var createKubernetesDeployCmd = &cobra.Command{
@@ -65,9 +64,9 @@ helm upgrade <deploymentName> <chartPath> --install --force --namespace <namespa
startTime = time.Now()
log.SetStepName("kubernetesDeploy")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "kubernetesDeploy", &myKubernetesDeployOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "kubernetesDeploy", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -77,37 +76,35 @@ helm upgrade <deploymentName> <chartPath> --install --force --namespace <namespa
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "kubernetesDeploy")
// ToDo: pass telemetryData to step
err := kubernetesDeploy(myKubernetesDeployOptions)
kubernetesDeploy(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addKubernetesDeployFlags(createKubernetesDeployCmd)
addKubernetesDeployFlags(createKubernetesDeployCmd, &stepConfig)
return createKubernetesDeployCmd
}
func addKubernetesDeployFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVar(&myKubernetesDeployOptions.AdditionalParameters, "additionalParameters", []string{}, "Defines additional parameters for \"helm install\" or \"kubectl apply\" command.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.APIServer, "apiServer", os.Getenv("PIPER_apiServer"), "Defines the Url of the API Server of the Kubernetes cluster.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.AppTemplate, "appTemplate", os.Getenv("PIPER_appTemplate"), "Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml)")
cmd.Flags().StringVar(&myKubernetesDeployOptions.ChartPath, "chartPath", os.Getenv("PIPER_chartPath"), "Defines the chart path for deployments using helm.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.ContainerRegistryPassword, "containerRegistryPassword", os.Getenv("PIPER_containerRegistryPassword"), "Password for container registry access - typically provided by the CI/CD environment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "http(s) url of the Container registry.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.ContainerRegistryUser, "containerRegistryUser", os.Getenv("PIPER_containerRegistryUser"), "Username for container registry access - typically provided by the CI/CD environment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.ContainerRegistrySecret, "containerRegistrySecret", "regsecret", "Name of the container registry secret used for pulling containers from the registry.")
cmd.Flags().BoolVar(&myKubernetesDeployOptions.CreateDockerRegistrySecret, "createDockerRegistrySecret", false, "Toggle to turn on Regsecret creation with a \"deployTool:kubectl\" deployment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.DeploymentName, "deploymentName", os.Getenv("PIPER_deploymentName"), "Defines the name of the deployment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.DeployTool, "deployTool", "kubectl", "Defines the tool which should be used for deployment.")
cmd.Flags().IntVar(&myKubernetesDeployOptions.HelmDeployWaitSeconds, "helmDeployWaitSeconds", 300, "Number of seconds before helm deploy returns.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.Image, "image", os.Getenv("PIPER_image"), "Full name of the image to be deployed.")
cmd.Flags().StringSliceVar(&myKubernetesDeployOptions.IngressHosts, "ingressHosts", []string{}, "List of ingress hosts to be exposed via helm deployment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.KubeConfig, "kubeConfig", os.Getenv("PIPER_kubeConfig"), "Defines the path to the \"kubeconfig\" file.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.KubeContext, "kubeContext", os.Getenv("PIPER_kubeContext"), "Defines the context to use from the \"kubeconfig\" file.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.KubeToken, "kubeToken", os.Getenv("PIPER_kubeToken"), "Contains the id_token used by kubectl for authentication. Consider using kubeConfig parameter instead.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.Namespace, "namespace", "default", "Defines the target Kubernetes namespace for the deployment.")
cmd.Flags().StringVar(&myKubernetesDeployOptions.TillerNamespace, "tillerNamespace", os.Getenv("PIPER_tillerNamespace"), "Defines optional tiller namespace for deployments using helm.")
func addKubernetesDeployFlags(cmd *cobra.Command, stepConfig *kubernetesDeployOptions) {
cmd.Flags().StringSliceVar(&stepConfig.AdditionalParameters, "additionalParameters", []string{}, "Defines additional parameters for \"helm install\" or \"kubectl apply\" command.")
cmd.Flags().StringVar(&stepConfig.APIServer, "apiServer", os.Getenv("PIPER_apiServer"), "Defines the Url of the API Server of the Kubernetes cluster.")
cmd.Flags().StringVar(&stepConfig.AppTemplate, "appTemplate", os.Getenv("PIPER_appTemplate"), "Defines the filename for the kubernetes app template (e.g. k8s_apptemplate.yaml)")
cmd.Flags().StringVar(&stepConfig.ChartPath, "chartPath", os.Getenv("PIPER_chartPath"), "Defines the chart path for deployments using helm.")
cmd.Flags().StringVar(&stepConfig.ContainerRegistryPassword, "containerRegistryPassword", os.Getenv("PIPER_containerRegistryPassword"), "Password for container registry access - typically provided by the CI/CD environment.")
cmd.Flags().StringVar(&stepConfig.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "http(s) url of the Container registry.")
cmd.Flags().StringVar(&stepConfig.ContainerRegistryUser, "containerRegistryUser", os.Getenv("PIPER_containerRegistryUser"), "Username for container registry access - typically provided by the CI/CD environment.")
cmd.Flags().StringVar(&stepConfig.ContainerRegistrySecret, "containerRegistrySecret", "regsecret", "Name of the container registry secret used for pulling containers from the registry.")
cmd.Flags().BoolVar(&stepConfig.CreateDockerRegistrySecret, "createDockerRegistrySecret", false, "Toggle to turn on Regsecret creation with a \"deployTool:kubectl\" deployment.")
cmd.Flags().StringVar(&stepConfig.DeploymentName, "deploymentName", os.Getenv("PIPER_deploymentName"), "Defines the name of the deployment.")
cmd.Flags().StringVar(&stepConfig.DeployTool, "deployTool", "kubectl", "Defines the tool which should be used for deployment.")
cmd.Flags().IntVar(&stepConfig.HelmDeployWaitSeconds, "helmDeployWaitSeconds", 300, "Number of seconds before helm deploy returns.")
cmd.Flags().StringVar(&stepConfig.Image, "image", os.Getenv("PIPER_image"), "Full name of the image to be deployed.")
cmd.Flags().StringSliceVar(&stepConfig.IngressHosts, "ingressHosts", []string{}, "List of ingress hosts to be exposed via helm deployment.")
cmd.Flags().StringVar(&stepConfig.KubeConfig, "kubeConfig", os.Getenv("PIPER_kubeConfig"), "Defines the path to the \"kubeconfig\" file.")
cmd.Flags().StringVar(&stepConfig.KubeContext, "kubeContext", os.Getenv("PIPER_kubeContext"), "Defines the context to use from the \"kubeconfig\" file.")
cmd.Flags().StringVar(&stepConfig.KubeToken, "kubeToken", os.Getenv("PIPER_kubeToken"), "Contains the id_token used by kubectl for authentication. Consider using kubeConfig parameter instead.")
cmd.Flags().StringVar(&stepConfig.Namespace, "namespace", "default", "Defines the target Kubernetes namespace for the deployment.")
cmd.Flags().StringVar(&stepConfig.TillerNamespace, "tillerNamespace", os.Getenv("PIPER_tillerNamespace"), "Defines optional tiller namespace for deployments using helm.")
cmd.MarkFlagRequired("chartPath")
cmd.MarkFlagRequired("containerRegistryUrl")

View File

@@ -2,6 +2,8 @@ package cmd
import (
"fmt"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
// GitCommit ...
@@ -10,7 +12,7 @@ var GitCommit string
// GitTag ...
var GitTag string
func version(myVersionOptions versionOptions) error {
func version(config versionOptions, telemetryData *telemetry.CustomData) {
gitCommit, gitTag := "<n/a>", "<n/a>"
@@ -22,7 +24,5 @@ func version(myVersionOptions versionOptions) error {
gitTag = GitTag
}
_, err := fmt.Printf("piper-version:\n commit: \"%s\"\n tag: \"%s\"\n", gitCommit, gitTag)
return err
fmt.Printf("piper-version:\n commit: \"%s\"\n tag: \"%s\"\n", gitCommit, gitTag)
}

View File

@@ -13,11 +13,10 @@ import (
type versionOptions struct {
}
var myVersionOptions versionOptions
// VersionCommand Returns the version of the piper binary
func VersionCommand() *cobra.Command {
metadata := versionMetadata()
var stepConfig versionOptions
var startTime time.Time
var createVersionCmd = &cobra.Command{
@@ -28,9 +27,9 @@ func VersionCommand() *cobra.Command {
startTime = time.Now()
log.SetStepName("version")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "version", &myVersionOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "version", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -40,18 +39,16 @@ func VersionCommand() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "version")
// ToDo: pass telemetryData to step
err := version(myVersionOptions)
version(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addVersionFlags(createVersionCmd)
addVersionFlags(createVersionCmd, &stepConfig)
return createVersionCmd
}
func addVersionFlags(cmd *cobra.Command) {
func addVersionFlags(cmd *cobra.Command, stepConfig *versionOptions) {
}

View File

@@ -6,6 +6,8 @@ import (
"io"
"os"
"testing"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func TestVersion(t *testing.T) {
@@ -51,10 +53,9 @@ func runVersionCommand(t *testing.T, commitID, tag string) string {
//
var myVersionOptions versionOptions
e = version(myVersionOptions)
if e != nil {
t.Error("Version command failed.")
}
telemetryData := telemetry.CustomData{}
version(myVersionOptions, &telemetryData)
w.Close()

View File

@@ -7,6 +7,7 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/pkg/errors"
"io"
"io/ioutil"
@@ -107,9 +108,14 @@ const completeScript = `#!/bin/bash
xs {{.Mode.GetDeployCommand}} -i {{.OperationID}} -a {{.Action.GetAction}}
`
func xsDeploy(XsDeployOptions xsDeployOptions) error {
func xsDeploy(config xsDeployOptions, telemetryData *telemetry.CustomData) {
c := command.Command{}
return runXsDeploy(XsDeployOptions, &c, piperutils.FileExists, piperutils.Copy, os.Remove, os.Stdout)
err := runXsDeploy(config, &c, piperutils.FileExists, piperutils.Copy, os.Remove, os.Stdout)
if err != nil {
log.Entry().
WithError(err).
Fatal("failed to execute xs deployment")
}
}
func runXsDeploy(XsDeployOptions xsDeployOptions, s shellRunner,

View File

@@ -27,11 +27,10 @@ type xsDeployOptions struct {
XsSessionFile string `json:"xsSessionFile,omitempty"`
}
var myXsDeployOptions xsDeployOptions
// XsDeployCommand Performs xs deployment
func XsDeployCommand() *cobra.Command {
metadata := xsDeployMetadata()
var stepConfig xsDeployOptions
var startTime time.Time
var createXsDeployCmd = &cobra.Command{
@@ -42,9 +41,9 @@ func XsDeployCommand() *cobra.Command {
startTime = time.Now()
log.SetStepName("xsDeploy")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "xsDeploy", &myXsDeployOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "xsDeploy", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -54,31 +53,29 @@ func XsDeployCommand() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "xsDeploy")
// ToDo: pass telemetryData to step
err := xsDeploy(myXsDeployOptions)
xsDeploy(stepConfig, &telemetryData)
telemetryData.ErrorCode = "0"
return err
},
}
addXsDeployFlags(createXsDeployCmd)
addXsDeployFlags(createXsDeployCmd, &stepConfig)
return createXsDeployCmd
}
func addXsDeployFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&myXsDeployOptions.DeployOpts, "deployOpts", os.Getenv("PIPER_deployOpts"), "Additional options appended to the deploy command. Only needed for sophisticated cases. When provided it is the duty of the provider to ensure proper quoting / escaping.")
cmd.Flags().StringVar(&myXsDeployOptions.OperationIDLogPattern, "operationIdLogPattern", "^.*xs bg-deploy -i (.*) -a.*$", "Regex pattern for retrieving the ID of the operation from the xs log.")
cmd.Flags().StringVar(&myXsDeployOptions.MtaPath, "mtaPath", os.Getenv("PIPER_mtaPath"), "Path to deployable")
cmd.Flags().StringVar(&myXsDeployOptions.Action, "action", "NONE", "Used for finalizing the blue-green deployment.")
cmd.Flags().StringVar(&myXsDeployOptions.Mode, "mode", "DEPLOY", "Controls if there is a standard deployment or a blue green deployment. Values: 'DEPLOY', 'BG_DEPLOY'")
cmd.Flags().StringVar(&myXsDeployOptions.OperationID, "operationId", os.Getenv("PIPER_operationId"), "The operation ID. Used in case of bg-deploy in order to resume or abort a previously started deployment.")
cmd.Flags().StringVar(&myXsDeployOptions.APIURL, "apiUrl", os.Getenv("PIPER_apiUrl"), "The api url (e.g. https://example.org:12345")
cmd.Flags().StringVar(&myXsDeployOptions.User, "user", os.Getenv("PIPER_user"), "User")
cmd.Flags().StringVar(&myXsDeployOptions.Password, "password", os.Getenv("PIPER_password"), "Password")
cmd.Flags().StringVar(&myXsDeployOptions.Org, "org", os.Getenv("PIPER_org"), "The org")
cmd.Flags().StringVar(&myXsDeployOptions.Space, "space", os.Getenv("PIPER_space"), "The space")
cmd.Flags().StringVar(&myXsDeployOptions.LoginOpts, "loginOpts", os.Getenv("PIPER_loginOpts"), "Additional options appended to the login command. Only needed for sophisticated cases. When provided it is the duty of the provider to ensure proper quoting / escaping.")
cmd.Flags().StringVar(&myXsDeployOptions.XsSessionFile, "xsSessionFile", os.Getenv("PIPER_xsSessionFile"), "The file keeping the xs session.")
func addXsDeployFlags(cmd *cobra.Command, stepConfig *xsDeployOptions) {
cmd.Flags().StringVar(&stepConfig.DeployOpts, "deployOpts", os.Getenv("PIPER_deployOpts"), "Additional options appended to the deploy command. Only needed for sophisticated cases. When provided it is the duty of the provider to ensure proper quoting / escaping.")
cmd.Flags().StringVar(&stepConfig.OperationIDLogPattern, "operationIdLogPattern", "^.*xs bg-deploy -i (.*) -a.*$", "Regex pattern for retrieving the ID of the operation from the xs log.")
cmd.Flags().StringVar(&stepConfig.MtaPath, "mtaPath", os.Getenv("PIPER_mtaPath"), "Path to deployable")
cmd.Flags().StringVar(&stepConfig.Action, "action", "NONE", "Used for finalizing the blue-green deployment.")
cmd.Flags().StringVar(&stepConfig.Mode, "mode", "DEPLOY", "Controls if there is a standard deployment or a blue green deployment. Values: 'DEPLOY', 'BG_DEPLOY'")
cmd.Flags().StringVar(&stepConfig.OperationID, "operationId", os.Getenv("PIPER_operationId"), "The operation ID. Used in case of bg-deploy in order to resume or abort a previously started deployment.")
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", os.Getenv("PIPER_apiUrl"), "The api url (e.g. https://example.org:12345")
cmd.Flags().StringVar(&stepConfig.User, "user", os.Getenv("PIPER_user"), "User")
cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password")
cmd.Flags().StringVar(&stepConfig.Org, "org", os.Getenv("PIPER_org"), "The org")
cmd.Flags().StringVar(&stepConfig.Space, "space", os.Getenv("PIPER_space"), "The space")
cmd.Flags().StringVar(&stepConfig.LoginOpts, "loginOpts", os.Getenv("PIPER_loginOpts"), "Additional options appended to the login command. Only needed for sophisticated cases. When provided it is the duty of the provider to ensure proper quoting / escaping.")
cmd.Flags().StringVar(&stepConfig.XsSessionFile, "xsSessionFile", os.Getenv("PIPER_xsSessionFile"), "The file keeping the xs session.")
cmd.MarkFlagRequired("mtaPath")
cmd.MarkFlagRequired("mode")

2
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect

5
go.sum
View File

@@ -1,4 +1,5 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/bmatcuk/doublestar v1.2.2 h1:oC24CykoSAB8zd7XgruHo33E0cHJf/WhQA/7BeXj+x0=
@@ -64,8 +65,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=

View File

@@ -62,11 +62,10 @@ type {{ .StepName }}Options struct {
{{ index $oRes "def"}}
{{ end }}
var my{{ .StepName | title}}Options {{.StepName}}Options
// {{.CobraCmdFuncName}} {{.Short}}
func {{.CobraCmdFuncName}}() *cobra.Command {
metadata := {{ .StepName }}Metadata()
var stepConfig {{.StepName}}Options
var startTime time.Time
{{- range $notused, $oRes := .OutputResources }}
var {{ index $oRes "name" }} {{ index $oRes "objectname" }}{{ end }}
@@ -79,9 +78,9 @@ func {{.CobraCmdFuncName}}() *cobra.Command {
startTime = time.Now()
log.SetStepName("{{ .StepName }}")
log.SetVerbose({{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.Verbose)
return {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}PrepareConfig(cmd, &metadata, "{{ .StepName }}", &my{{ .StepName | title}}Options, config.OpenPiperFile)
return {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}PrepareConfig(cmd, &metadata, "{{ .StepName }}", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -93,20 +92,18 @@ func {{.CobraCmdFuncName}}() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize({{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.NoTelemetry, "{{ .StepName }}")
// ToDo: pass telemetryData to step
err := {{.StepName}}(my{{ .StepName | title }}Options{{ range $notused, $oRes := .OutputResources}}, &{{ index $oRes "name" }}{{ end }})
{{.StepName}}(stepConfig, &telemetryData{{ range $notused, $oRes := .OutputResources}}, &{{ index $oRes "name" }}{{ end }})
telemetryData.ErrorCode = "0"
return err
},
}
{{.FlagsFunc}}({{.CreateCmdVar}})
{{.FlagsFunc}}({{.CreateCmdVar}}, &stepConfig)
return {{.CreateCmdVar}}
}
func {{.FlagsFunc}}(cmd *cobra.Command) {
func {{.FlagsFunc}}(cmd *cobra.Command, stepConfig *{{.StepName}}Options) {
{{- range $key, $value := .Metadata }}
cmd.Flags().{{ $value.Type | flagType }}(&my{{ $.StepName | title }}Options.{{ $value.Name | golangName }}, "{{ $value.Name }}", {{ $value.Default }}, "{{ $value.Description }}"){{ end }}
cmd.Flags().{{ $value.Type | flagType }}(&stepConfig.{{ $value.Name | golangName }}, "{{ $value.Name }}", {{ $value.Default }}, "{{ $value.Description }}"){{ end }}
{{- printf "\n" }}
{{- range $key, $value := .Metadata }}{{ if $value.Mandatory }}
cmd.MarkFlagRequired("{{ $value.Name }}"){{ end }}{{ end }}
@@ -157,9 +154,10 @@ func Test{{.CobraCmdFuncName}}(t *testing.T) {
const stepGoImplementationTemplate = `package cmd
import (
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func {{.StepName}}(config {{ .StepName }}Options{{ range $notused, $oRes := .OutputResources}}, {{ index $oRes "name" }} *{{ index $oRes "objectname" }} {{ end }}) error {
func {{.StepName}}(config {{ .StepName }}Options, telemetryData *telemetry.CustomData{{ range $notused, $oRes := .OutputResources}}, {{ index $oRes "name" }} *{{ index $oRes "objectname" }} {{ end }}) error {
log.Entry().WithField("customKey", "customValue").Info("This is how you write a log message with a custom field ...")
return nil
}

View File

@@ -89,11 +89,10 @@ func (i *testStepInfluxTest) persist(path, resourceName string) {
}
var myTestStepOptions testStepOptions
// TestStepCommand Test description
func TestStepCommand() *cobra.Command {
metadata := testStepMetadata()
var stepConfig testStepOptions
var startTime time.Time
var commonPipelineEnvironment testStepCommonPipelineEnvironment
var influxTest testStepInfluxTest
@@ -106,9 +105,9 @@ func TestStepCommand() *cobra.Command {
startTime = time.Now()
log.SetStepName("testStep")
log.SetVerbose(piperOsCmd.GeneralConfig.Verbose)
return piperOsCmd.PrepareConfig(cmd, &metadata, "testStep", &myTestStepOptions, config.OpenPiperFile)
return piperOsCmd.PrepareConfig(cmd, &metadata, "testStep", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -120,21 +119,19 @@ func TestStepCommand() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(piperOsCmd.GeneralConfig.NoTelemetry, "testStep")
// ToDo: pass telemetryData to step
err := testStep(myTestStepOptions, &commonPipelineEnvironment, &influxTest)
testStep(stepConfig, &telemetryData, &commonPipelineEnvironment, &influxTest)
telemetryData.ErrorCode = "0"
return err
},
}
addTestStepFlags(createTestStepCmd)
addTestStepFlags(createTestStepCmd, &stepConfig)
return createTestStepCmd
}
func addTestStepFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&myTestStepOptions.Param0, "param0", "val0", "param0 description")
cmd.Flags().StringVar(&myTestStepOptions.Param1, "param1", os.Getenv("PIPER_param1"), "param1 description")
cmd.Flags().StringVar(&myTestStepOptions.Param2, "param2", os.Getenv("PIPER_param2"), "param1 description")
func addTestStepFlags(cmd *cobra.Command, stepConfig *testStepOptions) {
cmd.Flags().StringVar(&stepConfig.Param0, "param0", "val0", "param0 description")
cmd.Flags().StringVar(&stepConfig.Param1, "param1", os.Getenv("PIPER_param1"), "param1 description")
cmd.Flags().StringVar(&stepConfig.Param2, "param2", os.Getenv("PIPER_param2"), "param1 description")
cmd.MarkFlagRequired("param0")
cmd.MarkFlagRequired("param2")

View File

@@ -88,11 +88,10 @@ func (i *testStepInfluxTest) persist(path, resourceName string) {
}
var myTestStepOptions testStepOptions
// TestStepCommand Test description
func TestStepCommand() *cobra.Command {
metadata := testStepMetadata()
var stepConfig testStepOptions
var startTime time.Time
var commonPipelineEnvironment testStepCommonPipelineEnvironment
var influxTest testStepInfluxTest
@@ -105,9 +104,9 @@ func TestStepCommand() *cobra.Command {
startTime = time.Now()
log.SetStepName("testStep")
log.SetVerbose(GeneralConfig.Verbose)
return PrepareConfig(cmd, &metadata, "testStep", &myTestStepOptions, config.OpenPiperFile)
return PrepareConfig(cmd, &metadata, "testStep", &stepConfig, config.OpenPiperFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
telemetryData := telemetry.CustomData{}
telemetryData.ErrorCode = "1"
handler := func() {
@@ -119,21 +118,19 @@ func TestStepCommand() *cobra.Command {
log.DeferExitHandler(handler)
defer handler()
telemetry.Initialize(GeneralConfig.NoTelemetry, "testStep")
// ToDo: pass telemetryData to step
err := testStep(myTestStepOptions, &commonPipelineEnvironment, &influxTest)
testStep(stepConfig, &telemetryData, &commonPipelineEnvironment, &influxTest)
telemetryData.ErrorCode = "0"
return err
},
}
addTestStepFlags(createTestStepCmd)
addTestStepFlags(createTestStepCmd, &stepConfig)
return createTestStepCmd
}
func addTestStepFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&myTestStepOptions.Param0, "param0", "val0", "param0 description")
cmd.Flags().StringVar(&myTestStepOptions.Param1, "param1", os.Getenv("PIPER_param1"), "param1 description")
cmd.Flags().StringVar(&myTestStepOptions.Param2, "param2", os.Getenv("PIPER_param2"), "param1 description")
func addTestStepFlags(cmd *cobra.Command, stepConfig *testStepOptions) {
cmd.Flags().StringVar(&stepConfig.Param0, "param0", "val0", "param0 description")
cmd.Flags().StringVar(&stepConfig.Param1, "param1", os.Getenv("PIPER_param1"), "param1 description")
cmd.Flags().StringVar(&stepConfig.Param2, "param2", os.Getenv("PIPER_param2"), "param1 description")
cmd.MarkFlagRequired("param0")
cmd.MarkFlagRequired("param2")