mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-08 04:21:26 +02:00
Persisted pipeline environment for golang library (#1091)
* Use commonPipelineEnvironment in go binary * Update groovy part incl. tests * Rework structure and naming * Support influx resources in steps * Update tests and some cleanups * Add correct defer handling * Address PR feedback * Fix test * Update resources.go Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com>
This commit is contained in:
parent
e5db600cf4
commit
a46b57e6b4
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
1. [Getting started](#getting-started)
|
1. [Getting started](#getting-started)
|
||||||
1. [Build the project](#build-the-project_)
|
1. [Build the project](#build-the-project_)
|
||||||
|
1. [Generating step framework](#generating-step-framework)
|
||||||
1. [Logging](#logging)
|
1. [Logging](#logging)
|
||||||
1. [Error handling](#error-handling)
|
1. [Error handling](#error-handling)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,11 +21,11 @@ type detectExecuteScanOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var myDetectExecuteScanOptions detectExecuteScanOptions
|
var myDetectExecuteScanOptions detectExecuteScanOptions
|
||||||
var detectExecuteScanStepConfigJSON string
|
|
||||||
|
|
||||||
// DetectExecuteScanCommand Executes Synopsis Detect scan
|
// DetectExecuteScanCommand Executes Synopsis Detect scan
|
||||||
func DetectExecuteScanCommand() *cobra.Command {
|
func DetectExecuteScanCommand() *cobra.Command {
|
||||||
metadata := detectExecuteScanMetadata()
|
metadata := detectExecuteScanMetadata()
|
||||||
|
|
||||||
var createDetectExecuteScanCmd = &cobra.Command{
|
var createDetectExecuteScanCmd = &cobra.Command{
|
||||||
Use: "detectExecuteScan",
|
Use: "detectExecuteScan",
|
||||||
Short: "Executes Synopsis Detect scan",
|
Short: "Executes Synopsis Detect scan",
|
||||||
@ -35,6 +36,7 @@ func DetectExecuteScanCommand() *cobra.Command {
|
|||||||
return PrepareConfig(cmd, &metadata, "detectExecuteScan", &myDetectExecuteScanOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "detectExecuteScan", &myDetectExecuteScanOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return detectExecuteScan(myDetectExecuteScanOptions)
|
return detectExecuteScan(myDetectExecuteScanOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -66,6 +68,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "apiToken",
|
Name: "apiToken",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -73,6 +76,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "codeLocation",
|
Name: "codeLocation",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -80,6 +84,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "projectName",
|
Name: "projectName",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -87,6 +92,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "projectVersion",
|
Name: "projectVersion",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -94,6 +100,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "scanners",
|
Name: "scanners",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -101,6 +108,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "scanPaths",
|
Name: "scanPaths",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -108,6 +116,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "scanProperties",
|
Name: "scanProperties",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -115,6 +124,7 @@ func detectExecuteScanMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "serverUrl",
|
Name: "serverUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
|
@ -54,6 +54,8 @@ func generateConfig() error {
|
|||||||
return errors.Wrap(err, "metadata: read failed")
|
return errors.Wrap(err, "metadata: read failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resourceParams := metadata.GetResourceParameters(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
||||||
|
|
||||||
var customConfig io.ReadCloser
|
var customConfig io.ReadCloser
|
||||||
{
|
{
|
||||||
exists, e := piperutils.FileExists(GeneralConfig.CustomConfig)
|
exists, e := piperutils.FileExists(GeneralConfig.CustomConfig)
|
||||||
@ -91,7 +93,7 @@ func generateConfig() error {
|
|||||||
params = metadata.Spec.Inputs.Parameters
|
params = metadata.Spec.Inputs.Parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
stepConfig, err = myConfig.GetStepConfig(flags, GeneralConfig.ParametersJSON, customConfig, defaultConfig, paramFilter, params, GeneralConfig.StageName, metadata.Metadata.Name)
|
stepConfig, err = myConfig.GetStepConfig(flags, GeneralConfig.ParametersJSON, customConfig, defaultConfig, paramFilter, params, resourceParams, GeneralConfig.StageName, metadata.Metadata.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "getting step config failed")
|
return errors.Wrap(err, "getting step config failed")
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,11 +24,11 @@ type githubCreatePullRequestOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var myGithubCreatePullRequestOptions githubCreatePullRequestOptions
|
var myGithubCreatePullRequestOptions githubCreatePullRequestOptions
|
||||||
var githubCreatePullRequestStepConfigJSON string
|
|
||||||
|
|
||||||
// GithubCreatePullRequestCommand Create a pull request on GitHub
|
// GithubCreatePullRequestCommand Create a pull request on GitHub
|
||||||
func GithubCreatePullRequestCommand() *cobra.Command {
|
func GithubCreatePullRequestCommand() *cobra.Command {
|
||||||
metadata := githubCreatePullRequestMetadata()
|
metadata := githubCreatePullRequestMetadata()
|
||||||
|
|
||||||
var createGithubCreatePullRequestCmd = &cobra.Command{
|
var createGithubCreatePullRequestCmd = &cobra.Command{
|
||||||
Use: "githubCreatePullRequest",
|
Use: "githubCreatePullRequest",
|
||||||
Short: "Create a pull request on GitHub",
|
Short: "Create a pull request on GitHub",
|
||||||
@ -40,6 +41,7 @@ It can for example be used for GitOps scenarios or for scenarios where you want
|
|||||||
return PrepareConfig(cmd, &metadata, "githubCreatePullRequest", &myGithubCreatePullRequestOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "githubCreatePullRequest", &myGithubCreatePullRequestOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return githubCreatePullRequest(myGithubCreatePullRequestOptions)
|
return githubCreatePullRequest(myGithubCreatePullRequestOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -80,6 +82,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "assignees",
|
Name: "assignees",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -87,6 +90,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "base",
|
Name: "base",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -94,6 +98,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "body",
|
Name: "body",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -101,6 +106,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "apiUrl",
|
Name: "apiUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -108,6 +114,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "head",
|
Name: "head",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -115,6 +122,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "owner",
|
Name: "owner",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -122,6 +130,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "repository",
|
Name: "repository",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -129,6 +138,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "serverUrl",
|
Name: "serverUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -136,6 +146,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "title",
|
Name: "title",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -143,6 +154,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "token",
|
Name: "token",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -150,6 +162,7 @@ func githubCreatePullRequestMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "labels",
|
Name: "labels",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
|
@ -5,32 +5,33 @@ import (
|
|||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type githubPublishReleaseOptions struct {
|
type githubPublishReleaseOptions struct {
|
||||||
AddClosedIssues bool `json:"addClosedIssues,omitempty"`
|
AddClosedIssues bool `json:"addClosedIssues,omitempty"`
|
||||||
AddDeltaToLastRelease bool `json:"addDeltaToLastRelease,omitempty"`
|
AddDeltaToLastRelease bool `json:"addDeltaToLastRelease,omitempty"`
|
||||||
|
APIURL string `json:"apiUrl,omitempty"`
|
||||||
AssetPath string `json:"assetPath,omitempty"`
|
AssetPath string `json:"assetPath,omitempty"`
|
||||||
Commitish string `json:"commitish,omitempty"`
|
Commitish string `json:"commitish,omitempty"`
|
||||||
ExcludeLabels []string `json:"excludeLabels,omitempty"`
|
ExcludeLabels []string `json:"excludeLabels,omitempty"`
|
||||||
APIURL string `json:"apiUrl,omitempty"`
|
Labels []string `json:"labels,omitempty"`
|
||||||
Owner string `json:"owner,omitempty"`
|
Owner string `json:"owner,omitempty"`
|
||||||
|
ReleaseBodyHeader string `json:"releaseBodyHeader,omitempty"`
|
||||||
Repository string `json:"repository,omitempty"`
|
Repository string `json:"repository,omitempty"`
|
||||||
ServerURL string `json:"serverUrl,omitempty"`
|
ServerURL string `json:"serverUrl,omitempty"`
|
||||||
Token string `json:"token,omitempty"`
|
Token string `json:"token,omitempty"`
|
||||||
UploadURL string `json:"uploadUrl,omitempty"`
|
UploadURL string `json:"uploadUrl,omitempty"`
|
||||||
Labels []string `json:"labels,omitempty"`
|
|
||||||
ReleaseBodyHeader string `json:"releaseBodyHeader,omitempty"`
|
|
||||||
Version string `json:"version,omitempty"`
|
Version string `json:"version,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var myGithubPublishReleaseOptions githubPublishReleaseOptions
|
var myGithubPublishReleaseOptions githubPublishReleaseOptions
|
||||||
var githubPublishReleaseStepConfigJSON string
|
|
||||||
|
|
||||||
// GithubPublishReleaseCommand Publish a release in GitHub
|
// GithubPublishReleaseCommand Publish a release in GitHub
|
||||||
func GithubPublishReleaseCommand() *cobra.Command {
|
func GithubPublishReleaseCommand() *cobra.Command {
|
||||||
metadata := githubPublishReleaseMetadata()
|
metadata := githubPublishReleaseMetadata()
|
||||||
|
|
||||||
var createGithubPublishReleaseCmd = &cobra.Command{
|
var createGithubPublishReleaseCmd = &cobra.Command{
|
||||||
Use: "githubPublishRelease",
|
Use: "githubPublishRelease",
|
||||||
Short: "Publish a release in GitHub",
|
Short: "Publish a release in GitHub",
|
||||||
@ -50,6 +51,7 @@ The result looks like
|
|||||||
return PrepareConfig(cmd, &metadata, "githubPublishRelease", &myGithubPublishReleaseOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "githubPublishRelease", &myGithubPublishReleaseOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return githubPublishRelease(myGithubPublishReleaseOptions)
|
return githubPublishRelease(myGithubPublishReleaseOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -61,17 +63,17 @@ The result looks like
|
|||||||
func addGithubPublishReleaseFlags(cmd *cobra.Command) {
|
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.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().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.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().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.ExcludeLabels, "excludeLabels", []string{}, "Allows to exclude issues with dedicated list of labels.")
|
||||||
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.APIURL, "apiUrl", "https://api.github.com", "Set the GitHub API url.")
|
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.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.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.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.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.UploadURL, "uploadUrl", "https://uploads.github.com", "Set the GitHub API url.")
|
||||||
cmd.Flags().StringSliceVar(&myGithubPublishReleaseOptions.Labels, "labels", []string{}, "Labels to include in issue search.")
|
|
||||||
cmd.Flags().StringVar(&myGithubPublishReleaseOptions.ReleaseBodyHeader, "releaseBodyHeader", os.Getenv("PIPER_releaseBodyHeader"), "Content which will appear for the release.")
|
|
||||||
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.")
|
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.")
|
||||||
|
|
||||||
cmd.MarkFlagRequired("apiUrl")
|
cmd.MarkFlagRequired("apiUrl")
|
||||||
@ -91,6 +93,7 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "addClosedIssues",
|
Name: "addClosedIssues",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "bool",
|
Type: "bool",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -98,13 +101,23 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "addDeltaToLastRelease",
|
Name: "addDeltaToLastRelease",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "bool",
|
Type: "bool",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
Aliases: []config.Alias{},
|
Aliases: []config.Alias{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "apiUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
|
Type: "string",
|
||||||
|
Mandatory: true,
|
||||||
|
Aliases: []config.Alias{{Name: "githubApiUrl"}},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "assetPath",
|
Name: "assetPath",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -112,6 +125,7 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "commitish",
|
Name: "commitish",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -119,27 +133,39 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "excludeLabels",
|
Name: "excludeLabels",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "[]string",
|
Type: "[]string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
Aliases: []config.Alias{},
|
Aliases: []config.Alias{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "apiUrl",
|
Name: "labels",
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
ResourceRef: []config.ResourceReference{},
|
||||||
Type: "string",
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Mandatory: true,
|
Type: "[]string",
|
||||||
Aliases: []config.Alias{{Name: "githubApiUrl"}},
|
Mandatory: false,
|
||||||
|
Aliases: []config.Alias{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "owner",
|
Name: "owner",
|
||||||
|
ResourceRef: []config.ResourceReference{{Name: "commonPipelineEnvironment", Param: "github/owner"}},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
Aliases: []config.Alias{{Name: "githubOrg"}},
|
Aliases: []config.Alias{{Name: "githubOrg"}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "releaseBodyHeader",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
|
Type: "string",
|
||||||
|
Mandatory: false,
|
||||||
|
Aliases: []config.Alias{},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "repository",
|
Name: "repository",
|
||||||
|
ResourceRef: []config.ResourceReference{{Name: "commonPipelineEnvironment", Param: "github/repository"}},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -147,6 +173,7 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "serverUrl",
|
Name: "serverUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -154,6 +181,7 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "token",
|
Name: "token",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -161,27 +189,15 @@ func githubPublishReleaseMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "uploadUrl",
|
Name: "uploadUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
Aliases: []config.Alias{{Name: "githubUploadUrl"}},
|
Aliases: []config.Alias{{Name: "githubUploadUrl"}},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "labels",
|
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
|
||||||
Type: "[]string",
|
|
||||||
Mandatory: false,
|
|
||||||
Aliases: []config.Alias{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "releaseBodyHeader",
|
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
|
||||||
Type: "string",
|
|
||||||
Mandatory: false,
|
|
||||||
Aliases: []config.Alias{},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
|
ResourceRef: []config.ResourceReference{{Name: "commonPipelineEnvironment", Param: "artifactVersion"}},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
|
@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,11 +14,11 @@ type karmaExecuteTestsOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var myKarmaExecuteTestsOptions karmaExecuteTestsOptions
|
var myKarmaExecuteTestsOptions karmaExecuteTestsOptions
|
||||||
var karmaExecuteTestsStepConfigJSON string
|
|
||||||
|
|
||||||
// KarmaExecuteTestsCommand Executes the Karma test runner
|
// KarmaExecuteTestsCommand Executes the Karma test runner
|
||||||
func KarmaExecuteTestsCommand() *cobra.Command {
|
func KarmaExecuteTestsCommand() *cobra.Command {
|
||||||
metadata := karmaExecuteTestsMetadata()
|
metadata := karmaExecuteTestsMetadata()
|
||||||
|
|
||||||
var createKarmaExecuteTestsCmd = &cobra.Command{
|
var createKarmaExecuteTestsCmd = &cobra.Command{
|
||||||
Use: "karmaExecuteTests",
|
Use: "karmaExecuteTests",
|
||||||
Short: "Executes the Karma test runner",
|
Short: "Executes the Karma test runner",
|
||||||
@ -38,6 +39,7 @@ In the Docker network, the containers can be referenced by the values provided i
|
|||||||
return PrepareConfig(cmd, &metadata, "karmaExecuteTests", &myKarmaExecuteTestsOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "karmaExecuteTests", &myKarmaExecuteTestsOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return karmaExecuteTests(myKarmaExecuteTestsOptions)
|
return karmaExecuteTests(myKarmaExecuteTestsOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -64,6 +66,7 @@ func karmaExecuteTestsMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "installCommand",
|
Name: "installCommand",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -71,6 +74,7 @@ func karmaExecuteTestsMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "modulePath",
|
Name: "modulePath",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -78,6 +82,7 @@ func karmaExecuteTestsMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "runCommand",
|
Name: "runCommand",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
|
@ -18,6 +18,7 @@ type GeneralConfigOptions struct {
|
|||||||
CustomConfig string
|
CustomConfig string
|
||||||
DefaultConfig []string //ordered list of Piper default configurations. Can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
|
DefaultConfig []string //ordered list of Piper default configurations. Can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
|
||||||
ParametersJSON string
|
ParametersJSON string
|
||||||
|
EnvRootPath string
|
||||||
StageName string
|
StageName string
|
||||||
StepConfigJSON string
|
StepConfigJSON string
|
||||||
StepMetadata string //metadata to be considered, can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
|
StepMetadata string //metadata to be considered, can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR'
|
||||||
@ -61,6 +62,7 @@ func addRootFlags(rootCmd *cobra.Command) {
|
|||||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.CustomConfig, "customConfig", ".pipeline/config.yml", "Path to the pipeline configuration file")
|
rootCmd.PersistentFlags().StringVar(&GeneralConfig.CustomConfig, "customConfig", ".pipeline/config.yml", "Path to the pipeline configuration file")
|
||||||
rootCmd.PersistentFlags().StringSliceVar(&GeneralConfig.DefaultConfig, "defaultConfig", []string{".pipeline/defaults.yaml"}, "Default configurations, passed as path to yaml file")
|
rootCmd.PersistentFlags().StringSliceVar(&GeneralConfig.DefaultConfig, "defaultConfig", []string{".pipeline/defaults.yaml"}, "Default configurations, passed as path to yaml file")
|
||||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.ParametersJSON, "parametersJSON", os.Getenv("PIPER_parametersJSON"), "Parameters to be considered in JSON format")
|
rootCmd.PersistentFlags().StringVar(&GeneralConfig.ParametersJSON, "parametersJSON", os.Getenv("PIPER_parametersJSON"), "Parameters to be considered in JSON format")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&GeneralConfig.EnvRootPath, "envRootPath", ".pipeline", "Root path to Piper pipeline shared environments")
|
||||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.StageName, "stageName", os.Getenv("STAGE_NAME"), "Name of the stage for which configuration should be included")
|
rootCmd.PersistentFlags().StringVar(&GeneralConfig.StageName, "stageName", os.Getenv("STAGE_NAME"), "Name of the stage for which configuration should be included")
|
||||||
rootCmd.PersistentFlags().StringVar(&GeneralConfig.StepConfigJSON, "stepConfigJSON", os.Getenv("PIPER_stepConfigJSON"), "Step configuration in JSON format")
|
rootCmd.PersistentFlags().StringVar(&GeneralConfig.StepConfigJSON, "stepConfigJSON", os.Getenv("PIPER_stepConfigJSON"), "Step configuration in JSON format")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&GeneralConfig.Verbose, "verbose", "v", false, "verbose output")
|
rootCmd.PersistentFlags().BoolVarP(&GeneralConfig.Verbose, "verbose", "v", false, "verbose output")
|
||||||
@ -71,6 +73,7 @@ func addRootFlags(rootCmd *cobra.Command) {
|
|||||||
func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName string, options interface{}, openFile func(s string) (io.ReadCloser, error)) error {
|
func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName string, options interface{}, openFile func(s string) (io.ReadCloser, error)) error {
|
||||||
|
|
||||||
filters := metadata.GetParameterFilters()
|
filters := metadata.GetParameterFilters()
|
||||||
|
resourceParams := metadata.GetResourceParameters(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
||||||
|
|
||||||
flagValues := config.AvailableFlagValues(cmd, &filters)
|
flagValues := config.AvailableFlagValues(cmd, &filters)
|
||||||
|
|
||||||
@ -108,7 +111,7 @@ func PrepareConfig(cmd *cobra.Command, metadata *config.StepData, stepName strin
|
|||||||
defaultConfig = append(defaultConfig, fc)
|
defaultConfig = append(defaultConfig, fc)
|
||||||
}
|
}
|
||||||
|
|
||||||
stepConfig, err = myConfig.GetStepConfig(flagValues, GeneralConfig.ParametersJSON, customConfig, defaultConfig, filters, metadata.Spec.Inputs.Parameters, GeneralConfig.StageName, stepName)
|
stepConfig, err = myConfig.GetStepConfig(flagValues, GeneralConfig.ParametersJSON, customConfig, defaultConfig, filters, metadata.Spec.Inputs.Parameters, resourceParams, GeneralConfig.StageName, stepName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "retrieving step configuration failed")
|
return errors.Wrap(err, "retrieving step configuration failed")
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,11 +11,11 @@ type versionOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var myVersionOptions versionOptions
|
var myVersionOptions versionOptions
|
||||||
var versionStepConfigJSON string
|
|
||||||
|
|
||||||
// VersionCommand Returns the version of the piper binary
|
// VersionCommand Returns the version of the piper binary
|
||||||
func VersionCommand() *cobra.Command {
|
func VersionCommand() *cobra.Command {
|
||||||
metadata := versionMetadata()
|
metadata := versionMetadata()
|
||||||
|
|
||||||
var createVersionCmd = &cobra.Command{
|
var createVersionCmd = &cobra.Command{
|
||||||
Use: "version",
|
Use: "version",
|
||||||
Short: "Returns the version of the piper binary",
|
Short: "Returns the version of the piper binary",
|
||||||
@ -25,6 +26,7 @@ func VersionCommand() *cobra.Command {
|
|||||||
return PrepareConfig(cmd, &metadata, "version", &myVersionOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "version", &myVersionOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return version(myVersionOptions)
|
return version(myVersionOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,11 +26,11 @@ type xsDeployOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var myXsDeployOptions xsDeployOptions
|
var myXsDeployOptions xsDeployOptions
|
||||||
var xsDeployStepConfigJSON string
|
|
||||||
|
|
||||||
// XsDeployCommand Performs xs deployment
|
// XsDeployCommand Performs xs deployment
|
||||||
func XsDeployCommand() *cobra.Command {
|
func XsDeployCommand() *cobra.Command {
|
||||||
metadata := xsDeployMetadata()
|
metadata := xsDeployMetadata()
|
||||||
|
|
||||||
var createXsDeployCmd = &cobra.Command{
|
var createXsDeployCmd = &cobra.Command{
|
||||||
Use: "xsDeploy",
|
Use: "xsDeploy",
|
||||||
Short: "Performs xs deployment",
|
Short: "Performs xs deployment",
|
||||||
@ -40,6 +41,7 @@ func XsDeployCommand() *cobra.Command {
|
|||||||
return PrepareConfig(cmd, &metadata, "xsDeploy", &myXsDeployOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "xsDeploy", &myXsDeployOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return xsDeploy(myXsDeployOptions)
|
return xsDeploy(myXsDeployOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -81,6 +83,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "deployOpts",
|
Name: "deployOpts",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -88,6 +91,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "operationIdLogPattern",
|
Name: "operationIdLogPattern",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -95,6 +99,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "mtaPath",
|
Name: "mtaPath",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -102,6 +107,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "action",
|
Name: "action",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -109,6 +115,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "mode",
|
Name: "mode",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -116,6 +123,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "operationId",
|
Name: "operationId",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -123,6 +131,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "apiUrl",
|
Name: "apiUrl",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -130,6 +139,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "user",
|
Name: "user",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -137,6 +147,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "password",
|
Name: "password",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -144,6 +155,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "org",
|
Name: "org",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -151,6 +163,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "space",
|
Name: "space",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -158,6 +171,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "loginOpts",
|
Name: "loginOpts",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -165,6 +179,7 @@ func xsDeployMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "xsSessionFile",
|
Name: "xsSessionFile",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
|
@ -82,7 +82,7 @@ func getDeepAliasValue(configMap map[string]interface{}, key string) interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetStepConfig provides merged step configuration using defaults, config, if available
|
// GetStepConfig provides merged step configuration using defaults, config, if available
|
||||||
func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON string, configuration io.ReadCloser, defaults []io.ReadCloser, filters StepFilters, parameters []StepParameters, stageName, stepName string) (StepConfig, error) {
|
func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON string, configuration io.ReadCloser, defaults []io.ReadCloser, filters StepFilters, parameters []StepParameters, envParameters map[string]interface{}, stageName, stepName string) (StepConfig, error) {
|
||||||
var stepConfig StepConfig
|
var stepConfig StepConfig
|
||||||
var d PipelineDefaults
|
var d PipelineDefaults
|
||||||
|
|
||||||
@ -126,6 +126,9 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri
|
|||||||
stepConfig.mixIn(def.Steps[stepName], filters.Steps)
|
stepConfig.mixIn(def.Steps[stepName], filters.Steps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merge parameters provided by Piper environment
|
||||||
|
stepConfig.mixIn(envParameters, filters.All)
|
||||||
|
|
||||||
// read config & merge - general -> steps -> stages
|
// read config & merge - general -> steps -> stages
|
||||||
stepConfig.mixIn(c.General, filters.General)
|
stepConfig.mixIn(c.General, filters.General)
|
||||||
stepConfig.mixIn(c.Steps[stepName], filters.Steps)
|
stepConfig.mixIn(c.Steps[stepName], filters.Steps)
|
||||||
|
@ -5,9 +5,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -145,9 +148,26 @@ steps:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "pe1",
|
||||||
|
Scope: []string{"STEPS"},
|
||||||
|
ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "test_pe1"}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
stepConfig, err := c.GetStepConfig(flags, paramJSON, myConfig, defaults, filters, parameterMetadata, "stage1", "step1")
|
stepMeta := StepData{Spec: StepSpec{Inputs: StepInputs{Parameters: parameterMetadata}}}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create temporary directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up tmp dir
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
piperenv.SetParameter(filepath.Join(dir, "commonPipelineEnvironment"), "test_pe1", "pe1_val")
|
||||||
|
|
||||||
|
stepConfig, err := c.GetStepConfig(flags, paramJSON, myConfig, defaults, filters, parameterMetadata, stepMeta.GetResourceParameters(dir, "commonPipelineEnvironment"), "stage1", "step1")
|
||||||
|
|
||||||
assert.Equal(t, nil, err, "error occured but none expected")
|
assert.Equal(t, nil, err, "error occured but none expected")
|
||||||
|
|
||||||
@ -163,7 +183,9 @@ steps:
|
|||||||
"p7": "p7_flag",
|
"p7": "p7_flag",
|
||||||
"pd1": "pd1_dependent_default",
|
"pd1": "pd1_dependent_default",
|
||||||
"pd2": "pd2_metadata_default",
|
"pd2": "pd2_metadata_default",
|
||||||
|
"pe1": "pe1_val",
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range expected {
|
for k, v := range expected {
|
||||||
t.Run(k, func(t *testing.T) {
|
t.Run(k, func(t *testing.T) {
|
||||||
if stepConfig.Config[k] != v {
|
if stepConfig.Config[k] != v {
|
||||||
@ -191,7 +213,7 @@ steps:
|
|||||||
|
|
||||||
c.openFile = customDefaultsOpenFileMock
|
c.openFile = customDefaultsOpenFileMock
|
||||||
|
|
||||||
stepConfig, err := c.GetStepConfig(nil, "", ioutil.NopCloser(strings.NewReader(testConfDefaults)), nil, StepFilters{General: []string{"p0"}}, nil, "stage1", "step1")
|
stepConfig, err := c.GetStepConfig(nil, "", ioutil.NopCloser(strings.NewReader(testConfDefaults)), nil, StepFilters{General: []string{"p0"}}, nil, nil, "stage1", "step1")
|
||||||
|
|
||||||
assert.NoError(t, err, "Error occured but no error expected")
|
assert.NoError(t, err, "Error occured but no error expected")
|
||||||
assert.Equal(t, "p0_custom_default", stepConfig.Config["p0"])
|
assert.Equal(t, "p0_custom_default", stepConfig.Config["p0"])
|
||||||
@ -204,7 +226,7 @@ steps:
|
|||||||
stepParams := []StepParameters{StepParameters{Name: "p0", Scope: []string{"GENERAL"}, Type: "string", Default: "p0_step_default", Aliases: []Alias{{Name: "p0_alias"}}}}
|
stepParams := []StepParameters{StepParameters{Name: "p0", Scope: []string{"GENERAL"}, Type: "string", Default: "p0_step_default", Aliases: []Alias{{Name: "p0_alias"}}}}
|
||||||
testConf := "general:\n p1: p1_conf"
|
testConf := "general:\n p1: p1_conf"
|
||||||
|
|
||||||
stepConfig, err := c.GetStepConfig(nil, "", ioutil.NopCloser(strings.NewReader(testConf)), nil, StepFilters{General: []string{"p0", "p1"}}, stepParams, "stage1", "step1")
|
stepConfig, err := c.GetStepConfig(nil, "", ioutil.NopCloser(strings.NewReader(testConf)), nil, StepFilters{General: []string{"p0", "p1"}}, stepParams, nil, "stage1", "step1")
|
||||||
|
|
||||||
assert.NoError(t, err, "Error occured but no error expected")
|
assert.NoError(t, err, "Error occured but no error expected")
|
||||||
assert.Equal(t, "p0_step_default", stepConfig.Config["p0"])
|
assert.Equal(t, "p0_step_default", stepConfig.Config["p0"])
|
||||||
@ -214,7 +236,7 @@ steps:
|
|||||||
t.Run("Failure case config", func(t *testing.T) {
|
t.Run("Failure case config", func(t *testing.T) {
|
||||||
var c Config
|
var c Config
|
||||||
myConfig := ioutil.NopCloser(strings.NewReader("invalid config"))
|
myConfig := ioutil.NopCloser(strings.NewReader("invalid config"))
|
||||||
_, err := c.GetStepConfig(nil, "", myConfig, nil, StepFilters{}, []StepParameters{}, "stage1", "step1")
|
_, err := c.GetStepConfig(nil, "", myConfig, nil, StepFilters{}, []StepParameters{}, nil, "stage1", "step1")
|
||||||
assert.EqualError(t, err, "failed to parse custom pipeline configuration: error unmarshalling \"invalid config\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
assert.EqualError(t, err, "failed to parse custom pipeline configuration: error unmarshalling \"invalid config\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -222,7 +244,7 @@ steps:
|
|||||||
var c Config
|
var c Config
|
||||||
myConfig := ioutil.NopCloser(strings.NewReader(""))
|
myConfig := ioutil.NopCloser(strings.NewReader(""))
|
||||||
myDefaults := []io.ReadCloser{ioutil.NopCloser(strings.NewReader("invalid defaults"))}
|
myDefaults := []io.ReadCloser{ioutil.NopCloser(strings.NewReader("invalid defaults"))}
|
||||||
_, err := c.GetStepConfig(nil, "", myConfig, myDefaults, StepFilters{}, []StepParameters{}, "stage1", "step1")
|
_, err := c.GetStepConfig(nil, "", myConfig, myDefaults, StepFilters{}, []StepParameters{}, nil, "stage1", "step1")
|
||||||
assert.EqualError(t, err, "failed to parse pipeline default configuration: error unmarshalling \"invalid defaults\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
assert.EqualError(t, err, "failed to parse pipeline default configuration: error unmarshalling \"invalid defaults\": error unmarshaling JSON: json: cannot unmarshal string into Go value of type config.Config", "default error expected")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
7
pkg/config/resources.go
Normal file
7
pkg/config/resources.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
// InfluxField is the constant for an Influx field
|
||||||
|
const InfluxField = "field"
|
||||||
|
|
||||||
|
// InfluxTag is the constant for an Influx field
|
||||||
|
const InfluxTag = "tag"
|
@ -5,6 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -25,8 +28,8 @@ type StepMetadata struct {
|
|||||||
|
|
||||||
// StepSpec defines the spec details for a step, like step inputs, containers, sidecars, ...
|
// StepSpec defines the spec details for a step, like step inputs, containers, sidecars, ...
|
||||||
type StepSpec struct {
|
type StepSpec struct {
|
||||||
Inputs StepInputs `json:"inputs"`
|
Inputs StepInputs `json:"inputs,omitempty"`
|
||||||
// Outputs string `json:"description,omitempty"`
|
Outputs StepOutputs `json:"outputs,omitempty"`
|
||||||
Containers []Container `json:"containers,omitempty"`
|
Containers []Container `json:"containers,omitempty"`
|
||||||
Sidecars []Container `json:"sidecars,omitempty"`
|
Sidecars []Container `json:"sidecars,omitempty"`
|
||||||
}
|
}
|
||||||
@ -43,6 +46,7 @@ type StepParameters struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
LongDescription string `json:"longDescription,omitempty"`
|
LongDescription string `json:"longDescription,omitempty"`
|
||||||
|
ResourceRef []ResourceReference `json:"resourceRef,omitempty"`
|
||||||
Scope []string `json:"scope"`
|
Scope []string `json:"scope"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Mandatory bool `json:"mandatory,omitempty"`
|
Mandatory bool `json:"mandatory,omitempty"`
|
||||||
@ -51,6 +55,12 @@ type StepParameters struct {
|
|||||||
Conditions []Condition `json:"conditions,omitempty"`
|
Conditions []Condition `json:"conditions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResourceReference defines the parameters of a resource reference
|
||||||
|
type ResourceReference struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Param string `json:"param"`
|
||||||
|
}
|
||||||
|
|
||||||
// Alias defines a step input parameter alias
|
// Alias defines a step input parameter alias
|
||||||
type Alias struct {
|
type Alias struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
@ -62,6 +72,7 @@ type StepResources struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
|
Parameters []map[string]interface{} `json:"params,omitempty"`
|
||||||
Conditions []Condition `json:"conditions,omitempty"`
|
Conditions []Condition `json:"conditions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,10 +83,10 @@ type StepSecrets struct {
|
|||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// StepOutputs defines the outputs of a step
|
// StepOutputs defines the outputs of a step step, typically one or multiple resources
|
||||||
//type StepOutputs struct {
|
type StepOutputs struct {
|
||||||
// Name string `json:"name"`
|
Resources []StepResources `json:"resources,omitempty"`
|
||||||
//}
|
}
|
||||||
|
|
||||||
// Container defines an execution container
|
// Container defines an execution container
|
||||||
type Container struct {
|
type Container struct {
|
||||||
@ -318,6 +329,23 @@ func (m *StepData) GetContextDefaults(stepName string) (io.ReadCloser, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetResourceParameters retrieves parameters from a named pipeline resource with a defined path
|
||||||
|
func (m *StepData) GetResourceParameters(path, name string) map[string]interface{} {
|
||||||
|
resourceParams := map[string]interface{}{}
|
||||||
|
|
||||||
|
for _, param := range m.Spec.Inputs.Parameters {
|
||||||
|
for _, res := range param.ResourceRef {
|
||||||
|
if res.Name == name {
|
||||||
|
if val := piperenv.GetParameter(filepath.Join(path, name), res.Param); len(val) > 0 {
|
||||||
|
resourceParams[param.Name] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceParams
|
||||||
|
}
|
||||||
|
|
||||||
func envVarsAsStringSlice(envVars []EnvVar) []string {
|
func envVarsAsStringSlice(envVars []EnvVar) []string {
|
||||||
e := []string{}
|
e := []string{}
|
||||||
for _, v := range envVars {
|
for _, v := range envVars {
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -442,3 +444,62 @@ func TestGetContextDefaults(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetResourceParameters(t *testing.T) {
|
||||||
|
tt := []struct {
|
||||||
|
in StepData
|
||||||
|
expected map[string]interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
in: StepData{Spec: StepSpec{Inputs: StepInputs{}}},
|
||||||
|
expected: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: StepData{
|
||||||
|
Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
|
||||||
|
{Name: "param1"},
|
||||||
|
{Name: "param2"},
|
||||||
|
}}}},
|
||||||
|
expected: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: StepData{
|
||||||
|
Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
|
||||||
|
{Name: "param1", ResourceRef: []ResourceReference{}},
|
||||||
|
{Name: "param2", ResourceRef: []ResourceReference{}},
|
||||||
|
}}}},
|
||||||
|
expected: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: StepData{
|
||||||
|
Spec: StepSpec{Inputs: StepInputs{Parameters: []StepParameters{
|
||||||
|
{Name: "param1", ResourceRef: []ResourceReference{{Name: "notAvailable", Param: "envparam1"}}},
|
||||||
|
{Name: "param2", ResourceRef: []ResourceReference{{Name: "commonPipelineEnvironment", Param: "envparam2"}}},
|
||||||
|
}}}},
|
||||||
|
expected: map[string]interface{}{"param2": "val2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create temporary directory")
|
||||||
|
}
|
||||||
|
// clean up tmp dir
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
cpeDir := filepath.Join(dir, "commonPipelineEnvironment")
|
||||||
|
err = os.MkdirAll(cpeDir, 0700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create sub directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
ioutil.WriteFile(filepath.Join(cpeDir, "envparam1"), []byte("val1"), 0700)
|
||||||
|
ioutil.WriteFile(filepath.Join(cpeDir, "envparam2"), []byte("val2"), 0700)
|
||||||
|
|
||||||
|
for run, test := range tt {
|
||||||
|
t.Run(fmt.Sprintf("Run %v", run), func(t *testing.T) {
|
||||||
|
got := test.in.GetResourceParameters(dir, "commonPipelineEnvironment")
|
||||||
|
assert.Equal(t, test.expected, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stepInfo struct {
|
type stepInfo struct {
|
||||||
@ -21,6 +22,7 @@ type stepInfo struct {
|
|||||||
Long string
|
Long string
|
||||||
Metadata []config.StepParameters
|
Metadata []config.StepParameters
|
||||||
OSImport bool
|
OSImport bool
|
||||||
|
OutputResources []map[string]string
|
||||||
Short string
|
Short string
|
||||||
StepFunc string
|
StepFunc string
|
||||||
StepName string
|
StepName string
|
||||||
@ -31,10 +33,13 @@ const stepGoTemplate = `package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
{{ if .OSImport }}"os"{{ end }}
|
{{ if .OSImport }}"os"{{ end }}
|
||||||
|
{{ if .OutputResources }}"fmt"{{ end }}
|
||||||
|
{{ if .OutputResources }}"path/filepath"{{ end }}
|
||||||
|
|
||||||
{{if .ExportPrefix}}{{ .ExportPrefix }} "github.com/SAP/jenkins-library/cmd"{{end}}
|
{{ if .ExportPrefix}}{{ .ExportPrefix }} "github.com/SAP/jenkins-library/cmd"{{ end -}}
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
{{ if .OutputResources }}"github.com/SAP/jenkins-library/pkg/piperenv"{{ end }}
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,12 +48,18 @@ type {{ .StepName }}Options struct {
|
|||||||
{{ $value.Name | golangName }} {{ $value.Type }} ` + "`json:\"{{$value.Name}},omitempty\"`" + `{{end}}
|
{{ $value.Name | golangName }} {{ $value.Type }} ` + "`json:\"{{$value.Name}},omitempty\"`" + `{{end}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{{ range $notused, $oRes := .OutputResources }}
|
||||||
|
{{ index $oRes "def"}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
var my{{ .StepName | title}}Options {{.StepName}}Options
|
var my{{ .StepName | title}}Options {{.StepName}}Options
|
||||||
var {{ .StepName }}StepConfigJSON string
|
|
||||||
|
|
||||||
// {{.CobraCmdFuncName}} {{.Short}}
|
// {{.CobraCmdFuncName}} {{.Short}}
|
||||||
func {{.CobraCmdFuncName}}() *cobra.Command {
|
func {{.CobraCmdFuncName}}() *cobra.Command {
|
||||||
metadata := {{ .StepName }}Metadata()
|
metadata := {{ .StepName }}Metadata()
|
||||||
|
{{- range $notused, $oRes := .OutputResources }}
|
||||||
|
var {{ index $oRes "name" }} {{ index $oRes "objectname" }}{{ end }}
|
||||||
|
|
||||||
var {{.CreateCmdVar}} = &cobra.Command{
|
var {{.CreateCmdVar}} = &cobra.Command{
|
||||||
Use: "{{.StepName}}",
|
Use: "{{.StepName}}",
|
||||||
Short: "{{.Short}}",
|
Short: "{{.Short}}",
|
||||||
@ -59,7 +70,15 @@ func {{.CobraCmdFuncName}}() *cobra.Command {
|
|||||||
return {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}PrepareConfig(cmd, &metadata, "{{ .StepName }}", &my{{ .StepName | title}}Options, config.OpenPiperFile)
|
return {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}PrepareConfig(cmd, &metadata, "{{ .StepName }}", &my{{ .StepName | title}}Options, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return {{.StepName}}(my{{ .StepName | title }}Options)
|
{{ if .OutputResources -}}
|
||||||
|
handler := func() {
|
||||||
|
{{- range $notused, $oRes := .OutputResources }}
|
||||||
|
{{ index $oRes "name" }}.persist(GeneralConfig.EnvRootPath, "{{ index $oRes "name" }}"){{ end }}
|
||||||
|
}
|
||||||
|
log.DeferExitHandler(handler)
|
||||||
|
defer handler()
|
||||||
|
{{- end }}
|
||||||
|
return {{.StepName}}(my{{ .StepName | title }}Options{{ range $notused, $oRes := .OutputResources}}, &{{ index $oRes "name" }}{{ end }})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +103,7 @@ func {{ .StepName }}Metadata() config.StepData {
|
|||||||
{{- range $key, $value := .Metadata }}
|
{{- range $key, $value := .Metadata }}
|
||||||
{
|
{
|
||||||
Name: "{{ $value.Name }}",
|
Name: "{{ $value.Name }}",
|
||||||
|
ResourceRef: []config.ResourceReference{{ "{" }}{{ range $notused, $ref := $value.ResourceRef }}{{ "{" }}Name: "{{ $ref.Name }}", Param: "{{ $ref.Param }}"{{ "}" }},{{ end }}{{ "}" }},
|
||||||
Scope: []string{{ "{" }}{{ range $notused, $scope := $value.Scope }}"{{ $scope }}",{{ end }}{{ "}" }},
|
Scope: []string{{ "{" }}{{ range $notused, $scope := $value.Scope }}"{{ $scope }}",{{ end }}{{ "}" }},
|
||||||
Type: "{{ $value.Type }}",
|
Type: "{{ $value.Type }}",
|
||||||
Mandatory: {{ $value.Mandatory }},
|
Mandatory: {{ $value.Mandatory }},
|
||||||
@ -116,6 +136,17 @@ func Test{{.CobraCmdFuncName}}(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const stepGoImplementationTemplate = `package cmd
|
||||||
|
import (
|
||||||
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func {{.StepName}}(config {{ .StepName }}Options{{ 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
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
// ProcessMetaFiles generates step coding based on step configuration provided in yaml files
|
// ProcessMetaFiles generates step coding based on step configuration provided in yaml files
|
||||||
func ProcessMetaFiles(metadataFiles []string, stepHelperData StepHelperData, docuHelperData DocuHelperData) error {
|
func ProcessMetaFiles(metadataFiles []string, stepHelperData StepHelperData, docuHelperData DocuHelperData) error {
|
||||||
for key := range metadataFiles {
|
for key := range metadataFiles {
|
||||||
@ -141,7 +172,8 @@ func ProcessMetaFiles(metadataFiles []string, stepHelperData StepHelperData, doc
|
|||||||
osImport, err = setDefaultParameters(&stepData)
|
osImport, err = setDefaultParameters(&stepData)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
myStepInfo := getStepInfo(&stepData, osImport, stepHelperData.ExportPrefix)
|
myStepInfo, err := getStepInfo(&stepData, osImport, stepHelperData.ExportPrefix)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
step := stepTemplate(myStepInfo)
|
step := stepTemplate(myStepInfo)
|
||||||
err = stepHelperData.WriteFile(fmt.Sprintf("cmd/%v_generated.go", stepData.Metadata.Name), step, 0644)
|
err = stepHelperData.WriteFile(fmt.Sprintf("cmd/%v_generated.go", stepData.Metadata.Name), step, 0644)
|
||||||
@ -150,6 +182,13 @@ func ProcessMetaFiles(metadataFiles []string, stepHelperData StepHelperData, doc
|
|||||||
test := stepTestTemplate(myStepInfo)
|
test := stepTestTemplate(myStepInfo)
|
||||||
err = stepHelperData.WriteFile(fmt.Sprintf("cmd/%v_generated_test.go", stepData.Metadata.Name), test, 0644)
|
err = stepHelperData.WriteFile(fmt.Sprintf("cmd/%v_generated_test.go", stepData.Metadata.Name), test, 0644)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
|
exists, _ := piperutils.FileExists(fmt.Sprintf("cmd/%v.go", stepData.Metadata.Name))
|
||||||
|
if !exists {
|
||||||
|
impl := stepImplementation(myStepInfo)
|
||||||
|
err = stepHelperData.WriteFile(fmt.Sprintf("cmd/%v.go", stepData.Metadata.Name), impl, 0644)
|
||||||
|
checkError(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = generateStepDocumentation(stepData, docuHelperData)
|
err = generateStepDocumentation(stepData, docuHelperData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -209,7 +248,9 @@ func setDefaultParameters(stepData *config.StepData) (bool, error) {
|
|||||||
return osImportRequired, nil
|
return osImportRequired, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStepInfo(stepData *config.StepData, osImport bool, exportPrefix string) stepInfo {
|
func getStepInfo(stepData *config.StepData, osImport bool, exportPrefix string) (stepInfo, error) {
|
||||||
|
oRes, err := getOutputResourceDetails(stepData)
|
||||||
|
|
||||||
return stepInfo{
|
return stepInfo{
|
||||||
StepName: stepData.Metadata.Name,
|
StepName: stepData.Metadata.Name,
|
||||||
CobraCmdFuncName: fmt.Sprintf("%vCommand", strings.Title(stepData.Metadata.Name)),
|
CobraCmdFuncName: fmt.Sprintf("%vCommand", strings.Title(stepData.Metadata.Name)),
|
||||||
@ -219,8 +260,79 @@ func getStepInfo(stepData *config.StepData, osImport bool, exportPrefix string)
|
|||||||
Metadata: stepData.Spec.Inputs.Parameters,
|
Metadata: stepData.Spec.Inputs.Parameters,
|
||||||
FlagsFunc: fmt.Sprintf("add%vFlags", strings.Title(stepData.Metadata.Name)),
|
FlagsFunc: fmt.Sprintf("add%vFlags", strings.Title(stepData.Metadata.Name)),
|
||||||
OSImport: osImport,
|
OSImport: osImport,
|
||||||
|
OutputResources: oRes,
|
||||||
ExportPrefix: exportPrefix,
|
ExportPrefix: exportPrefix,
|
||||||
|
},
|
||||||
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOutputResourceDetails(stepData *config.StepData) ([]map[string]string, error) {
|
||||||
|
outputResources := []map[string]string{}
|
||||||
|
|
||||||
|
for _, res := range stepData.Spec.Outputs.Resources {
|
||||||
|
currentResource := map[string]string{}
|
||||||
|
currentResource["name"] = res.Name
|
||||||
|
|
||||||
|
switch res.Type {
|
||||||
|
case "piperEnvironment":
|
||||||
|
var envResource PiperEnvironmentResource
|
||||||
|
envResource.Name = res.Name
|
||||||
|
envResource.StepName = stepData.Metadata.Name
|
||||||
|
for _, param := range res.Parameters {
|
||||||
|
paramSections := strings.Split(fmt.Sprintf("%v", param["name"]), "/")
|
||||||
|
category := ""
|
||||||
|
name := paramSections[0]
|
||||||
|
if len(paramSections) > 1 {
|
||||||
|
name = strings.Join(paramSections[1:], "_")
|
||||||
|
category = paramSections[0]
|
||||||
|
if !contains(envResource.Categories, category) {
|
||||||
|
envResource.Categories = append(envResource.Categories, category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
envParam := PiperEnvironmentParameter{Category: category, Name: name}
|
||||||
|
envResource.Parameters = append(envResource.Parameters, envParam)
|
||||||
|
}
|
||||||
|
def, err := envResource.StructString()
|
||||||
|
if err != nil {
|
||||||
|
return outputResources, err
|
||||||
|
}
|
||||||
|
currentResource["def"] = def
|
||||||
|
currentResource["objectname"] = envResource.StructName()
|
||||||
|
outputResources = append(outputResources, currentResource)
|
||||||
|
case "influx":
|
||||||
|
var influxResource InfluxResource
|
||||||
|
influxResource.Name = res.Name
|
||||||
|
influxResource.StepName = stepData.Metadata.Name
|
||||||
|
for _, measurement := range res.Parameters {
|
||||||
|
influxMeasurement := InfluxMeasurement{Name: fmt.Sprintf("%v", measurement["name"])}
|
||||||
|
if fields, ok := measurement["fields"].([]interface{}); ok {
|
||||||
|
for _, field := range fields {
|
||||||
|
if fieldParams, ok := field.(map[string]interface{}); ok {
|
||||||
|
influxMeasurement.Fields = append(influxMeasurement.Fields, InfluxMetric{Name: fmt.Sprintf("%v", fieldParams["name"])})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tags, ok := measurement["tags"].([]interface{}); ok {
|
||||||
|
for _, tag := range tags {
|
||||||
|
if tagParams, ok := tag.(map[string]interface{}); ok {
|
||||||
|
influxMeasurement.Tags = append(influxMeasurement.Tags, InfluxMetric{Name: fmt.Sprintf("%v", tagParams["name"])})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
influxResource.Measurements = append(influxResource.Measurements, influxMeasurement)
|
||||||
|
}
|
||||||
|
def, err := influxResource.StructString()
|
||||||
|
if err != nil {
|
||||||
|
return outputResources, err
|
||||||
|
}
|
||||||
|
currentResource["def"] = def
|
||||||
|
currentResource["objectname"] = influxResource.StructName()
|
||||||
|
outputResources = append(outputResources, currentResource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputResources, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetadataFiles provides a list of all step metadata files
|
// MetadataFiles provides a list of all step metadata files
|
||||||
@ -244,7 +356,7 @@ func stepTemplate(myStepInfo stepInfo) []byte {
|
|||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"flagType": flagType,
|
"flagType": flagType,
|
||||||
"golangName": golangName,
|
"golangName": golangNameTitle,
|
||||||
"title": strings.Title,
|
"title": strings.Title,
|
||||||
"longName": longName,
|
"longName": longName,
|
||||||
}
|
}
|
||||||
@ -263,7 +375,7 @@ func stepTestTemplate(myStepInfo stepInfo) []byte {
|
|||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"flagType": flagType,
|
"flagType": flagType,
|
||||||
"golangName": golangName,
|
"golangName": golangNameTitle,
|
||||||
"title": strings.Title,
|
"title": strings.Title,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +389,22 @@ func stepTestTemplate(myStepInfo stepInfo) []byte {
|
|||||||
return generatedCode.Bytes()
|
return generatedCode.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stepImplementation(myStepInfo stepInfo) []byte {
|
||||||
|
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"title": strings.Title,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("impl").Funcs(funcMap).Parse(stepGoImplementationTemplate)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
var generatedCode bytes.Buffer
|
||||||
|
err = tmpl.Execute(&generatedCode, myStepInfo)
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
return generatedCode.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
func longName(long string) string {
|
func longName(long string) string {
|
||||||
l := strings.ReplaceAll(long, "`", "` + \"`\" + `")
|
l := strings.ReplaceAll(long, "`", "` + \"`\" + `")
|
||||||
l = strings.TrimSpace(l)
|
l = strings.TrimSpace(l)
|
||||||
@ -290,7 +418,11 @@ func golangName(name string) string {
|
|||||||
properName = strings.Replace(properName, "Id", "ID", -1)
|
properName = strings.Replace(properName, "Id", "ID", -1)
|
||||||
properName = strings.Replace(properName, "Json", "JSON", -1)
|
properName = strings.Replace(properName, "Json", "JSON", -1)
|
||||||
properName = strings.Replace(properName, "json", "JSON", -1)
|
properName = strings.Replace(properName, "json", "JSON", -1)
|
||||||
return strings.Title(properName)
|
return properName
|
||||||
|
}
|
||||||
|
|
||||||
|
func golangNameTitle(name string) string {
|
||||||
|
return strings.Title(golangName(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func flagType(paramType string) string {
|
func flagType(paramType string) string {
|
||||||
|
@ -20,6 +20,22 @@ func configOpenFileMock(name string) (io.ReadCloser, error) {
|
|||||||
longDescription: |
|
longDescription: |
|
||||||
Long Test description
|
Long Test description
|
||||||
spec:
|
spec:
|
||||||
|
outputs:
|
||||||
|
resources:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
type: piperEnvironment
|
||||||
|
params:
|
||||||
|
- name: artifactVersion
|
||||||
|
- name: git/commitId
|
||||||
|
- name: git/branch
|
||||||
|
- name: influxTest
|
||||||
|
type: influx
|
||||||
|
params:
|
||||||
|
- name: m1
|
||||||
|
fields:
|
||||||
|
- name: f1
|
||||||
|
tags:
|
||||||
|
- name: t1
|
||||||
inputs:
|
inputs:
|
||||||
params:
|
params:
|
||||||
- name: param0
|
- name: param0
|
||||||
@ -75,6 +91,7 @@ func TestProcessMetaFiles(t *testing.T) {
|
|||||||
t.Fatalf("failed reading %v", goldenFilePath)
|
t.Fatalf("failed reading %v", goldenFilePath)
|
||||||
}
|
}
|
||||||
assert.Equal(t, expected, files["cmd/testStep_generated.go"])
|
assert.Equal(t, expected, files["cmd/testStep_generated.go"])
|
||||||
|
t.Log(string(files["cmd/testStep_generated.go"]))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("test code", func(t *testing.T) {
|
t.Run("test code", func(t *testing.T) {
|
||||||
@ -176,7 +193,9 @@ func TestGetStepInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
myStepInfo := getStepInfo(&stepData, true, "")
|
myStepInfo, err := getStepInfo(&stepData, true, "")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, "testStep", myStepInfo.StepName, "StepName incorrect")
|
assert.Equal(t, "testStep", myStepInfo.StepName, "StepName incorrect")
|
||||||
assert.Equal(t, "TestStepCommand", myStepInfo.CobraCmdFuncName, "CobraCmdFuncName incorrect")
|
assert.Equal(t, "TestStepCommand", myStepInfo.CobraCmdFuncName, "CobraCmdFuncName incorrect")
|
||||||
@ -203,7 +222,7 @@ func TestLongName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGolangName(t *testing.T) {
|
func TestGolangNameTitle(t *testing.T) {
|
||||||
tt := []struct {
|
tt := []struct {
|
||||||
input string
|
input string
|
||||||
expected string
|
expected string
|
||||||
@ -217,7 +236,7 @@ func TestGolangName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range tt {
|
for k, v := range tt {
|
||||||
assert.Equal(t, v.expected, golangName(v.input), fmt.Sprintf("wrong golang name for run %v", k))
|
assert.Equal(t, v.expected, golangNameTitle(v.input), fmt.Sprintf("wrong golang name for run %v", k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
191
pkg/generator/helper/resources.go
Normal file
191
pkg/generator/helper/resources.go
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PiperEnvironmentResource defines a piper environement resource which stores data across multiple pipeline steps
|
||||||
|
type PiperEnvironmentResource struct {
|
||||||
|
Name string
|
||||||
|
StepName string
|
||||||
|
Parameters []PiperEnvironmentParameter
|
||||||
|
Categories []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// PiperEnvironmentParameter defines a parameter within the Piper environment
|
||||||
|
type PiperEnvironmentParameter struct {
|
||||||
|
Category string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
const piperEnvStructTemplate = `type {{ .StepName }}{{ .Name | title}} struct {
|
||||||
|
{{ range $notused, $param := .Parameters }}
|
||||||
|
{{- if not $param.Category}}{{ $param.Name | golangName }} string{{ end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- range $notused, $category := .Categories }}
|
||||||
|
{{ $category }} struct {
|
||||||
|
{{- range $notused, $param := $.Parameters }}
|
||||||
|
{{- if eq $category $param.Category }}
|
||||||
|
{{ $param.Name | golangName }} string
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *{{ .StepName }}{{ .Name | title}}) persist(path, resourceName string) {
|
||||||
|
content := []struct{
|
||||||
|
category string
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
}{
|
||||||
|
{{- range $notused, $param := .Parameters }}
|
||||||
|
{{- if not $param.Category}}
|
||||||
|
{category: "", name: "{{ $param.Name }}", value: p.{{ $param.Name | golangName}}},
|
||||||
|
{{- else }}
|
||||||
|
{category: "{{ $param.Category }}", name: "{{ $param.Name }}", value: p.{{ $param.Category }}.{{ $param.Name | golangName}}},
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, param := range content {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting piper environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// StructName returns the name of the influx resource struct
|
||||||
|
func (p *PiperEnvironmentResource) StructName() string {
|
||||||
|
return fmt.Sprintf("%v%v", p.StepName, strings.Title(p.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructString returns the golang coding for the struct definition of the InfluxResource
|
||||||
|
func (p *PiperEnvironmentResource) StructString() (string, error) {
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"title": strings.Title,
|
||||||
|
"golangName": golangName,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("resources").Funcs(funcMap).Parse(piperEnvStructTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var generatedCode bytes.Buffer
|
||||||
|
err = tmpl.Execute(&generatedCode, &p)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(generatedCode.Bytes()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfluxResource defines an Influx resouece that holds measurement information for a pipeline run
|
||||||
|
type InfluxResource struct {
|
||||||
|
Name string
|
||||||
|
StepName string
|
||||||
|
Measurements []InfluxMeasurement
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfluxMeasurement defines a measurement for Influx reporting which is defined via a step resource
|
||||||
|
type InfluxMeasurement struct {
|
||||||
|
Name string
|
||||||
|
Fields []InfluxMetric
|
||||||
|
Tags []InfluxMetric
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfluxMetric defines a metric (column) in an influx measurement
|
||||||
|
type InfluxMetric struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// InfluxMetricContent defines the content of an Inflx metric
|
||||||
|
type InfluxMetricContent struct {
|
||||||
|
Measurement string
|
||||||
|
ValType string
|
||||||
|
Name string
|
||||||
|
Value *string
|
||||||
|
}
|
||||||
|
|
||||||
|
const influxStructTemplate = `type {{ .StepName }}{{ .Name | title}} struct {
|
||||||
|
{{- range $notused, $measurement := .Measurements }}
|
||||||
|
{{ $measurement.Name }} struct {
|
||||||
|
fields struct {
|
||||||
|
{{- range $notused, $field := $measurement.Fields }}
|
||||||
|
{{ $field.Name | golangName }} string
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
tags struct {
|
||||||
|
{{- range $notused, $tag := $measurement.Tags }}
|
||||||
|
{{ $tag.Name | golangName }} string
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *{{ .StepName }}{{ .Name | title}}) persist(path, resourceName string) {
|
||||||
|
measurementContent := []struct{
|
||||||
|
measurement string
|
||||||
|
valType string
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
}{
|
||||||
|
{{- range $notused, $measurement := .Measurements }}
|
||||||
|
{{- range $notused, $field := $measurement.Fields }}
|
||||||
|
{valType: config.InfluxField, measurement: "{{ $measurement.Name }}" , name: "{{ $field.Name }}", value: i.{{ $measurement.Name }}.fields.{{ $field.Name | golangName }}},
|
||||||
|
{{- end }}
|
||||||
|
{{- range $notused, $tag := $measurement.Tags }}
|
||||||
|
{valType: config.InfluxTag, measurement: "{{ $measurement.Name }}" , name: "{{ $tag.Name }}", value: i.{{ $measurement.Name }}.tags.{{ $tag.Name | golangName }}},
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, metric := range measurementContent {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(metric.measurement, fmt.Sprintf("%vs", metric.valType), metric.name), metric.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting influx environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
// StructString returns the golang coding for the struct definition of the InfluxResource
|
||||||
|
func (i *InfluxResource) StructString() (string, error) {
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"title": strings.Title,
|
||||||
|
"golangName": golangName,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl, err := template.New("resources").Funcs(funcMap).Parse(influxStructTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var generatedCode bytes.Buffer
|
||||||
|
err = tmpl.Execute(&generatedCode, &i)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(generatedCode.Bytes()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructName returns the name of the influx resource struct
|
||||||
|
func (i *InfluxResource) StructName() string {
|
||||||
|
return fmt.Sprintf("%v%v", i.StepName, strings.Title(i.Name))
|
||||||
|
}
|
94
pkg/generator/helper/resources_test.go
Normal file
94
pkg/generator/helper/resources_test.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStructString(t *testing.T) {
|
||||||
|
tt := []struct {
|
||||||
|
in InfluxResource
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
in: InfluxResource{
|
||||||
|
Name: "TestInflux",
|
||||||
|
StepName: "TestStep",
|
||||||
|
Measurements: []InfluxMeasurement{
|
||||||
|
{
|
||||||
|
Name: "m1",
|
||||||
|
Fields: []InfluxMetric{{Name: "field1_1"}, {Name: "field1_2"}},
|
||||||
|
Tags: []InfluxMetric{{Name: "tag1_1"}, {Name: "tag1_2"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "m2",
|
||||||
|
Fields: []InfluxMetric{{Name: "field2_1"}, {Name: "field2_2"}},
|
||||||
|
Tags: []InfluxMetric{{Name: "tag2_1"}, {Name: "tag2_2"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: `type TestStepTestInflux struct {
|
||||||
|
m1 struct {
|
||||||
|
fields struct {
|
||||||
|
field1_1 string
|
||||||
|
field1_2 string
|
||||||
|
}
|
||||||
|
tags struct {
|
||||||
|
tag1_1 string
|
||||||
|
tag1_2 string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m2 struct {
|
||||||
|
fields struct {
|
||||||
|
field2_1 string
|
||||||
|
field2_2 string
|
||||||
|
}
|
||||||
|
tags struct {
|
||||||
|
tag2_1 string
|
||||||
|
tag2_2 string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *TestStepTestInflux) persist(path, resourceName string) {
|
||||||
|
measurementContent := []struct{
|
||||||
|
measurement string
|
||||||
|
valType string
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
}{
|
||||||
|
{valType: config.InfluxField, measurement: "m1" , name: "field1_1", value: i.m1.fields.field1_1},
|
||||||
|
{valType: config.InfluxField, measurement: "m1" , name: "field1_2", value: i.m1.fields.field1_2},
|
||||||
|
{valType: config.InfluxTag, measurement: "m1" , name: "tag1_1", value: i.m1.tags.tag1_1},
|
||||||
|
{valType: config.InfluxTag, measurement: "m1" , name: "tag1_2", value: i.m1.tags.tag1_2},
|
||||||
|
{valType: config.InfluxField, measurement: "m2" , name: "field2_1", value: i.m2.fields.field2_1},
|
||||||
|
{valType: config.InfluxField, measurement: "m2" , name: "field2_2", value: i.m2.fields.field2_2},
|
||||||
|
{valType: config.InfluxTag, measurement: "m2" , name: "tag2_1", value: i.m2.tags.tag2_1},
|
||||||
|
{valType: config.InfluxTag, measurement: "m2" , name: "tag2_2", value: i.m2.tags.tag2_2},
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, metric := range measurementContent {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(metric.measurement, fmt.Sprintf("%vs", metric.valType), metric.name), metric.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting influx environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for run, test := range tt {
|
||||||
|
t.Run(fmt.Sprintf("Run %v", run), func(t *testing.T) {
|
||||||
|
got, err := test.in.StructString()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, test.expected, got)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/config"
|
"github.com/SAP/jenkins-library/pkg/config"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperenv"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,12 +17,83 @@ type testStepOptions struct {
|
|||||||
Param2 string `json:"param2,omitempty"`
|
Param2 string `json:"param2,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type testStepCommonPipelineEnvironment struct {
|
||||||
|
artifactVersion string
|
||||||
|
git struct {
|
||||||
|
commitID string
|
||||||
|
branch string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *testStepCommonPipelineEnvironment) persist(path, resourceName string) {
|
||||||
|
content := []struct{
|
||||||
|
category string
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
}{
|
||||||
|
{category: "", name: "artifactVersion", value: p.artifactVersion},
|
||||||
|
{category: "git", name: "commitId", value: p.git.commitID},
|
||||||
|
{category: "git", name: "branch", value: p.git.branch},
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, param := range content {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting piper environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testStepInfluxTest struct {
|
||||||
|
m1 struct {
|
||||||
|
fields struct {
|
||||||
|
f1 string
|
||||||
|
}
|
||||||
|
tags struct {
|
||||||
|
t1 string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *testStepInfluxTest) persist(path, resourceName string) {
|
||||||
|
measurementContent := []struct{
|
||||||
|
measurement string
|
||||||
|
valType string
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
}{
|
||||||
|
{valType: config.InfluxField, measurement: "m1" , name: "f1", value: i.m1.fields.f1},
|
||||||
|
{valType: config.InfluxTag, measurement: "m1" , name: "t1", value: i.m1.tags.t1},
|
||||||
|
}
|
||||||
|
|
||||||
|
errCount := 0
|
||||||
|
for _, metric := range measurementContent {
|
||||||
|
err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(metric.measurement, fmt.Sprintf("%vs", metric.valType), metric.name), metric.value)
|
||||||
|
if err != nil {
|
||||||
|
log.Entry().WithError(err).Error("Error persisting influx environment.")
|
||||||
|
errCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errCount > 0 {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var myTestStepOptions testStepOptions
|
var myTestStepOptions testStepOptions
|
||||||
var testStepStepConfigJSON string
|
|
||||||
|
|
||||||
// TestStepCommand Test description
|
// TestStepCommand Test description
|
||||||
func TestStepCommand() *cobra.Command {
|
func TestStepCommand() *cobra.Command {
|
||||||
metadata := testStepMetadata()
|
metadata := testStepMetadata()
|
||||||
|
var commonPipelineEnvironment testStepCommonPipelineEnvironment
|
||||||
|
var influxTest testStepInfluxTest
|
||||||
|
|
||||||
var createTestStepCmd = &cobra.Command{
|
var createTestStepCmd = &cobra.Command{
|
||||||
Use: "testStep",
|
Use: "testStep",
|
||||||
Short: "Test description",
|
Short: "Test description",
|
||||||
@ -31,7 +104,13 @@ func TestStepCommand() *cobra.Command {
|
|||||||
return PrepareConfig(cmd, &metadata, "testStep", &myTestStepOptions, config.OpenPiperFile)
|
return PrepareConfig(cmd, &metadata, "testStep", &myTestStepOptions, config.OpenPiperFile)
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return testStep(myTestStepOptions)
|
handler := func() {
|
||||||
|
commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment")
|
||||||
|
influxTest.persist(GeneralConfig.EnvRootPath, "influxTest")
|
||||||
|
}
|
||||||
|
log.DeferExitHandler(handler)
|
||||||
|
defer handler()
|
||||||
|
return testStep(myTestStepOptions, &commonPipelineEnvironment, &influxTest)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +135,7 @@ func testStepMetadata() config.StepData {
|
|||||||
Parameters: []config.StepParameters{
|
Parameters: []config.StepParameters{
|
||||||
{
|
{
|
||||||
Name: "param0",
|
Name: "param0",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"GENERAL","PARAMETERS",},
|
Scope: []string{"GENERAL","PARAMETERS",},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
@ -63,6 +143,7 @@ func testStepMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "param1",
|
Name: "param1",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS",},
|
Scope: []string{"PARAMETERS",},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: false,
|
Mandatory: false,
|
||||||
@ -70,6 +151,7 @@ func testStepMetadata() config.StepData {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "param2",
|
Name: "param2",
|
||||||
|
ResourceRef: []config.ResourceReference{},
|
||||||
Scope: []string{"PARAMETERS",},
|
Scope: []string{"PARAMETERS",},
|
||||||
Type: "string",
|
Type: "string",
|
||||||
Mandatory: true,
|
Mandatory: true,
|
||||||
|
@ -28,3 +28,8 @@ func SetVerbose(verbose bool) {
|
|||||||
func SetStepName(stepName string) {
|
func SetStepName(stepName string) {
|
||||||
logger = Entry().WithField("stepName", stepName)
|
logger = Entry().WithField("stepName", stepName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeferExitHandler registers a logrus exit handler to allow cleanup activities.
|
||||||
|
func DeferExitHandler(handler func()) {
|
||||||
|
logrus.DeferExitHandler(handler)
|
||||||
|
}
|
||||||
|
62
pkg/piperenv/environment.go
Normal file
62
pkg/piperenv/environment.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package piperenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This file contains functions used to read/write pipeline environment data from/to disk.
|
||||||
|
// The content of a written file is the value. For the custom parameters this could for example also be a JSON representation of a more complex value.
|
||||||
|
|
||||||
|
// SetResourceParameter sets a resource parameter in the environment stored in the file system
|
||||||
|
func SetResourceParameter(path, resourceName, paramName, value string) error {
|
||||||
|
paramPath := filepath.Join(path, resourceName, paramName)
|
||||||
|
return writeToDisk(paramPath, []byte(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetResourceParameter reads a resource parameter from the environment stored in the file system
|
||||||
|
func GetResourceParameter(path, resourceName, paramName string) string {
|
||||||
|
paramPath := filepath.Join(path, resourceName, paramName)
|
||||||
|
return readFromDisk(paramPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetParameter sets any parameter in the pipeline environment or another environment stored in the file system
|
||||||
|
func SetParameter(path, name, value string) error {
|
||||||
|
paramPath := filepath.Join(path, name)
|
||||||
|
return writeToDisk(paramPath, []byte(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetParameter reads any parameter from the pipeline environment or another environment stored in the file system
|
||||||
|
func GetParameter(path, name string) string {
|
||||||
|
paramPath := filepath.Join(path, name)
|
||||||
|
return readFromDisk(paramPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeToDisk(filename string, data []byte) error {
|
||||||
|
|
||||||
|
if _, err := os.Stat(filepath.Dir(filename)); os.IsNotExist(err) {
|
||||||
|
log.Entry().Debugf("Creating directory: %v", filepath.Dir(filename))
|
||||||
|
os.MkdirAll(filepath.Dir(filename), 0700)
|
||||||
|
}
|
||||||
|
|
||||||
|
//ToDo: make sure to not overwrite file but rather add another file? Create error if already existing?
|
||||||
|
if len(data) > 0 {
|
||||||
|
log.Entry().Debugf("Writing file to disk: %v", filename)
|
||||||
|
return ioutil.WriteFile(filename, data, 0700)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFromDisk(filename string) string {
|
||||||
|
//ToDo: if multiple files exist, read from latest file
|
||||||
|
log.Entry().Debugf("Reading file from disk: %v", filename)
|
||||||
|
v, err := ioutil.ReadFile(filename)
|
||||||
|
val := string(v)
|
||||||
|
if err != nil {
|
||||||
|
val = ""
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
51
pkg/piperenv/environment_test.go
Normal file
51
pkg/piperenv/environment_test.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package piperenv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetResourceParameter(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create temporary directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up tmp dir
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
err = SetResourceParameter(dir, "testRes", "testParam", "testVal")
|
||||||
|
|
||||||
|
assert.NoError(t, err, "Error occured but none expected")
|
||||||
|
assert.Equal(t, "testVal", GetResourceParameter(dir, "testRes", "testParam"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetParameter(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create temporary directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up tmp dir
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
err = SetParameter(dir, "testParam", "testVal")
|
||||||
|
|
||||||
|
assert.NoError(t, err, "Error occured but none expected")
|
||||||
|
assert.Equal(t, "testVal", GetParameter(dir, "testParam"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadFromDisk(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to create temporary directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up tmp dir
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
assert.Equal(t, "", GetParameter(dir, "testParamNotExistingYet"))
|
||||||
|
}
|
@ -18,6 +18,10 @@ spec:
|
|||||||
- name: githubTokenCredentialsId
|
- name: githubTokenCredentialsId
|
||||||
description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.
|
description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.
|
||||||
type: jenkins
|
type: jenkins
|
||||||
|
resources:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
resourceSpec:
|
||||||
|
type: piperEnvironment
|
||||||
params:
|
params:
|
||||||
- name: addClosedIssues
|
- name: addClosedIssues
|
||||||
description: 'If set to `true`, closed issues and merged pull-requests since the last release will added below the `releaseBodyHeader`'
|
description: 'If set to `true`, closed issues and merged pull-requests since the last release will added below the `releaseBodyHeader`'
|
||||||
@ -35,6 +39,18 @@ spec:
|
|||||||
- STEPS
|
- STEPS
|
||||||
type: bool
|
type: bool
|
||||||
default: false
|
default: false
|
||||||
|
- name: apiUrl
|
||||||
|
aliases:
|
||||||
|
- name: githubApiUrl
|
||||||
|
description: Set the GitHub API url.
|
||||||
|
scope:
|
||||||
|
- GENERAL
|
||||||
|
- PARAMETERS
|
||||||
|
- STAGES
|
||||||
|
- STEPS
|
||||||
|
type: string
|
||||||
|
default: https://api.github.com
|
||||||
|
mandatory: true
|
||||||
- name: assetPath
|
- name: assetPath
|
||||||
description: Path to a release asset which should be uploaded to the list of release assets.
|
description: Path to a release asset which should be uploaded to the list of release assets.
|
||||||
scope:
|
scope:
|
||||||
@ -57,32 +73,40 @@ spec:
|
|||||||
- STAGES
|
- STAGES
|
||||||
- STEPS
|
- STEPS
|
||||||
type: '[]string'
|
type: '[]string'
|
||||||
- name: apiUrl
|
- name: labels
|
||||||
aliases:
|
description: 'Labels to include in issue search.'
|
||||||
- name: githubApiUrl
|
|
||||||
description: Set the GitHub API url.
|
|
||||||
scope:
|
scope:
|
||||||
- GENERAL
|
|
||||||
- PARAMETERS
|
- PARAMETERS
|
||||||
- STAGES
|
- STAGES
|
||||||
- STEPS
|
- STEPS
|
||||||
type: string
|
type: '[]string'
|
||||||
default: https://api.github.com
|
|
||||||
mandatory: true
|
|
||||||
- name: owner
|
- name: owner
|
||||||
aliases:
|
aliases:
|
||||||
- name: githubOrg
|
- name: githubOrg
|
||||||
description: 'Set the GitHub organization.'
|
description: 'Set the GitHub organization.'
|
||||||
|
resourceRef:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
param: github/owner
|
||||||
scope:
|
scope:
|
||||||
- PARAMETERS
|
- PARAMETERS
|
||||||
- STAGES
|
- STAGES
|
||||||
- STEPS
|
- STEPS
|
||||||
type: string
|
type: string
|
||||||
mandatory: true
|
mandatory: true
|
||||||
|
- name: releaseBodyHeader
|
||||||
|
description: Content which will appear for the release.
|
||||||
|
scope:
|
||||||
|
- PARAMETERS
|
||||||
|
- STAGES
|
||||||
|
- STEPS
|
||||||
|
type: string
|
||||||
- name: repository
|
- name: repository
|
||||||
aliases:
|
aliases:
|
||||||
- name: githubRepo
|
- name: githubRepo
|
||||||
description: 'Set the GitHub repository.'
|
description: 'Set the GitHub repository.'
|
||||||
|
resourceRef:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
param: github/repository
|
||||||
scope:
|
scope:
|
||||||
- PARAMETERS
|
- PARAMETERS
|
||||||
- STAGES
|
- STAGES
|
||||||
@ -124,22 +148,11 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
default: https://uploads.github.com
|
default: https://uploads.github.com
|
||||||
mandatory: true
|
mandatory: true
|
||||||
- name: labels
|
|
||||||
description: 'Labels to include in issue search.'
|
|
||||||
scope:
|
|
||||||
- PARAMETERS
|
|
||||||
- STAGES
|
|
||||||
- STEPS
|
|
||||||
type: '[]string'
|
|
||||||
- name: releaseBodyHeader
|
|
||||||
description: Content which will appear for the release.
|
|
||||||
scope:
|
|
||||||
- PARAMETERS
|
|
||||||
- STAGES
|
|
||||||
- STEPS
|
|
||||||
type: string
|
|
||||||
- name: version
|
- name: version
|
||||||
description: 'Define the version number which will be written as tag as well as release name.'
|
description: 'Define the version number which will be written as tag as well as release name.'
|
||||||
|
resourceRef:
|
||||||
|
- name: commonPipelineEnvironment
|
||||||
|
param: artifactVersion
|
||||||
scope:
|
scope:
|
||||||
- PARAMETERS
|
- PARAMETERS
|
||||||
- STAGES
|
- STAGES
|
||||||
|
@ -2,20 +2,27 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
import util.BasePiperTest
|
import util.BasePiperTest
|
||||||
|
import util.JenkinsFileExistsRule
|
||||||
|
import util.JenkinsWriteFileRule
|
||||||
import util.JenkinsReadYamlRule
|
import util.JenkinsReadYamlRule
|
||||||
import util.Rules
|
import util.Rules
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is
|
import static org.hamcrest.CoreMatchers.is
|
||||||
|
import static org.hamcrest.Matchers.contains
|
||||||
import static org.hamcrest.Matchers.hasItem
|
import static org.hamcrest.Matchers.hasItem
|
||||||
import static org.junit.Assert.assertThat
|
import static org.junit.Assert.assertThat
|
||||||
|
|
||||||
class CommonPipelineEnvironmentTest extends BasePiperTest {
|
class CommonPipelineEnvironmentTest extends BasePiperTest {
|
||||||
|
|
||||||
|
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
|
||||||
|
private JenkinsFileExistsRule fileExistsRule = new JenkinsFileExistsRule(this, [])
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public RuleChain rules = Rules
|
public RuleChain rules = Rules
|
||||||
.getCommonRules(this)
|
.getCommonRules(this)
|
||||||
.around(new JenkinsReadYamlRule(this)
|
.around(new JenkinsReadYamlRule(this))
|
||||||
)
|
.around(writeFileRule)
|
||||||
|
.around(fileExistsRule)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCustomValueList() {
|
void testCustomValueList() {
|
||||||
@ -34,4 +41,14 @@ class CommonPipelineEnvironmentTest extends BasePiperTest {
|
|||||||
assertThat(nullScript.commonPipelineEnvironment.getValue('myList').key1, is('val1'))
|
assertThat(nullScript.commonPipelineEnvironment.getValue('myList').key1, is('val1'))
|
||||||
assertThat(nullScript.commonPipelineEnvironment.getValue('myList').key2, is('val2'))
|
assertThat(nullScript.commonPipelineEnvironment.getValue('myList').key2, is('val2'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWritetoDisk() {
|
||||||
|
nullScript.commonPipelineEnvironment.artifactVersion = '1.0.0'
|
||||||
|
nullScript.commonPipelineEnvironment.setValue('custom1', 'customVal1')
|
||||||
|
nullScript.commonPipelineEnvironment.writeToDisk(nullScript)
|
||||||
|
|
||||||
|
assertThat(writeFileRule.files['.pipeline/commonPipelineEnvironment/artifactVersion'], is('1.0.0'))
|
||||||
|
assertThat(writeFileRule.files['.pipeline/commonPipelineEnvironment/custom/custom1'], is('customVal1'))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import org.junit.rules.ExpectedException
|
|||||||
import org.junit.rules.RuleChain
|
import org.junit.rules.RuleChain
|
||||||
import util.BasePiperTest
|
import util.BasePiperTest
|
||||||
import util.JenkinsCredentialsRule
|
import util.JenkinsCredentialsRule
|
||||||
|
import util.JenkinsFileExistsRule
|
||||||
import util.JenkinsLoggingRule
|
import util.JenkinsLoggingRule
|
||||||
import util.JenkinsReadJsonRule
|
import util.JenkinsReadJsonRule
|
||||||
import util.JenkinsReadYamlRule
|
import util.JenkinsReadYamlRule
|
||||||
@ -23,6 +24,7 @@ class GithubPublishReleaseTest extends BasePiperTest {
|
|||||||
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
|
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
|
||||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||||
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
|
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
|
||||||
|
private JenkinsFileExistsRule fileExistsRule = new JenkinsFileExistsRule(this, [])
|
||||||
|
|
||||||
private List withEnvArgs = []
|
private List withEnvArgs = []
|
||||||
|
|
||||||
@ -35,6 +37,7 @@ class GithubPublishReleaseTest extends BasePiperTest {
|
|||||||
.around(shellCallRule)
|
.around(shellCallRule)
|
||||||
.around(stepRule)
|
.around(stepRule)
|
||||||
.around(writeFileRule)
|
.around(writeFileRule)
|
||||||
|
.around(fileExistsRule)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
void init() {
|
void init() {
|
||||||
@ -58,26 +61,6 @@ class GithubPublishReleaseTest extends BasePiperTest {
|
|||||||
// asserts
|
// asserts
|
||||||
assertThat(writeFileRule.files['metadata/githubrelease.yaml'], containsString('name: githubPublishRelease'))
|
assertThat(writeFileRule.files['metadata/githubrelease.yaml'], containsString('name: githubPublishRelease'))
|
||||||
assertThat(withEnvArgs[0], allOf(startsWith('PIPER_parametersJSON'), containsString('"testParam":"This is test content"')))
|
assertThat(withEnvArgs[0], allOf(startsWith('PIPER_parametersJSON'), containsString('"testParam":"This is test content"')))
|
||||||
assertThat(withEnvArgs[1], is('PIPER_owner='))
|
|
||||||
assertThat(withEnvArgs[2], is('PIPER_repository='))
|
|
||||||
assertThat(withEnvArgs[3], is('PIPER_version='))
|
|
||||||
assertThat(shellCallRule.shell[1], is('./piper githubPublishRelease --token thisIsATestToken'))
|
assertThat(shellCallRule.shell[1], is('./piper githubPublishRelease --token thisIsATestToken'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGithubPublishReleaseWithEnv() {
|
|
||||||
|
|
||||||
nullScript.commonPipelineEnvironment.setArtifactVersion('1.0.0')
|
|
||||||
nullScript.commonPipelineEnvironment.setGithubOrg('TestOrg')
|
|
||||||
nullScript.commonPipelineEnvironment.setGithubRepo('TestRepo')
|
|
||||||
|
|
||||||
stepRule.step.githubPublishRelease(
|
|
||||||
juStabUtils: utils,
|
|
||||||
script: nullScript
|
|
||||||
)
|
|
||||||
// asserts
|
|
||||||
assertThat(withEnvArgs[1], is('PIPER_owner=TestOrg'))
|
|
||||||
assertThat(withEnvArgs[2], is('PIPER_repository=TestRepo'))
|
|
||||||
assertThat(withEnvArgs[3], is('PIPER_version=1.0.0'))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ class JenkinsFileExistsRule implements TestRule {
|
|||||||
void evaluate() throws Throwable {
|
void evaluate() throws Throwable {
|
||||||
|
|
||||||
testInstance.helper.registerAllowedMethod('fileExists', [String.class], {s ->
|
testInstance.helper.registerAllowedMethod('fileExists', [String.class], {s ->
|
||||||
queriedFiles.add(s)
|
queriedFiles.add(s.toString())
|
||||||
return s in existingFiles
|
return s.toString() in existingFiles
|
||||||
})
|
})
|
||||||
|
|
||||||
testInstance.helper.registerAllowedMethod('fileExists', [Map.class], {m ->
|
testInstance.helper.registerAllowedMethod('fileExists', [Map.class], {m ->
|
||||||
queriedFiles.add(m.file)
|
queriedFiles.add(m.file.toString())
|
||||||
return m.file in existingFiles}
|
return m.file.toString() in existingFiles}
|
||||||
)
|
)
|
||||||
|
|
||||||
base.evaluate()
|
base.evaluate()
|
||||||
|
@ -144,8 +144,74 @@ class commonPipelineEnvironment implements Serializable {
|
|||||||
config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config)
|
config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeToDisk(script) {
|
||||||
|
|
||||||
|
def files = [
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/artifactVersion', content: artifactVersion],
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/github/owner', content: githubOrg],
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/github/repository', content: githubRepo],
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/git/branch', content: gitBranch],
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/git/commitId', content: gitCommitId],
|
||||||
|
[filename: '.pipeline/commonPipelineEnvironment/git/commitMessage', content: gitCommitMessage],
|
||||||
|
]
|
||||||
|
|
||||||
|
files.each({f ->
|
||||||
|
if (f.content && !script.fileExists(f.filename)) {
|
||||||
|
script.writeFile file: f.filename, text: f.content
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
valueMap.each({key, value ->
|
||||||
|
def fileName = ".pipeline/commonPipelineEnvironment/custom/${key}"
|
||||||
|
if (value && !script.fileExists(fileName)) {
|
||||||
|
//ToDo: check for value type and act accordingly?
|
||||||
|
script.writeFile file: fileName, text: value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFromDisk() {
|
||||||
|
def file = '.pipeline/commonPipelineEnvironment/artifactVersion'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
artifactVersion = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = '.pipeline/commonPipelineEnvironment/github/owner'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
githubOrg = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = '.pipeline/commonPipelineEnvironment/github/repository'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
githubRepo = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = '.pipeline/commonPipelineEnvironment/git/branch'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
gitBranch = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = '.pipeline/commonPipelineEnvironment/git/commitId'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
gitCommitId = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
file = '.pipeline/commonPipelineEnvironment/git/commitMessage'
|
||||||
|
if (fileExists(file)) {
|
||||||
|
gitCommitMessage = readFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
def customValues = findFiles(glob: '.pipeline/commonPipelineEnvironment/custom/*')
|
||||||
|
|
||||||
|
customValues.each({f ->
|
||||||
|
def fileName = f.getName()
|
||||||
|
def param = fileName.split('/')[fileName.split('\\/').size()-1]
|
||||||
|
valueMap[param] = readFile(f.getPath())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
List getCustomDefaults() {
|
List getCustomDefaults() {
|
||||||
DefaultValueCache.getInstance().getCustomDefaults()
|
DefaultValueCache.getInstance().getCustomDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,12 @@ void call(Map parameters = [:]) {
|
|||||||
|
|
||||||
new PiperGoUtils(this, utils).unstashPiperBin()
|
new PiperGoUtils(this, utils).unstashPiperBin()
|
||||||
utils.unstash('pipelineConfigAndTests')
|
utils.unstash('pipelineConfigAndTests')
|
||||||
|
script.commonPipelineEnvironment.writeToDisk(script)
|
||||||
|
|
||||||
writeFile(file: METADATA_FILE, text: libraryResource(METADATA_FILE))
|
writeFile(file: METADATA_FILE, text: libraryResource(METADATA_FILE))
|
||||||
|
|
||||||
withEnv([
|
withEnv([
|
||||||
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(parameters)}",
|
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(parameters)}",
|
||||||
"PIPER_owner=${script.commonPipelineEnvironment.getGithubOrg()?:''}",
|
|
||||||
"PIPER_repository=${script.commonPipelineEnvironment.getGithubRepo()?:''}",
|
|
||||||
"PIPER_version=${script.commonPipelineEnvironment.getArtifactVersion()?:''}"
|
|
||||||
]) {
|
]) {
|
||||||
// get context configuration
|
// get context configuration
|
||||||
config = readJSON (text: sh(returnStdout: true, script: "./piper getConfig --contextConfig --stepMetadata '${METADATA_FILE}'"))
|
config = readJSON (text: sh(returnStdout: true, script: "./piper getConfig --contextConfig --stepMetadata '${METADATA_FILE}'"))
|
||||||
|
Loading…
Reference in New Issue
Block a user