Skip to content

Commit 0b8b6f2

Browse files
stippi2daniel-kurzynskifgeck
authored
Migrate stage artifact deployment from Cloud SDK Pipeline-Lib (#1324)
Co-authored-by: Daniel Kurzynski <[email protected]> Co-authored-by: Florian Geckeler <[email protected]>
1 parent 0c6dabb commit 0b8b6f2

10 files changed

+149
-89
lines changed

cmd/nexusUpload.go

+11-17
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,12 @@ func uploadMTA(utils nexusUploadUtils, uploader nexus.Uploader, options *nexusUp
135135
// This will fail anyway if the file doesn't exist
136136
mtaPath = "mta.yml"
137137
}
138-
version, err := getVersionFromMtaFile(utils, mtaPath)
139-
var artifactID = options.ArtifactID
140-
if artifactID == "" {
141-
artifactID = utils.getEnvParameter(".pipeline/commonPipelineEnvironment/configuration", "artifactId")
142-
if artifactID == "" {
143-
err = fmt.Errorf("the 'artifactId' parameter was not provided and could not be retrieved from the Common Pipeline Environment")
144-
} else {
145-
log.Entry().Debugf("mtar artifact id from CPE: '%s'", artifactID)
146-
}
147-
}
138+
mtaInfo, err := getInfoFromMtaFile(utils, mtaPath)
148139
if err == nil {
149-
err = uploader.SetInfo(options.GroupID, artifactID, version)
140+
if options.ArtifactID != "" {
141+
mtaInfo.ID = options.ArtifactID
142+
}
143+
err = uploader.SetInfo(options.GroupID, mtaInfo.ID, mtaInfo.Version)
150144
if err == nexus.ErrEmptyVersion {
151145
err = fmt.Errorf("the project descriptor file 'mta.yaml' has an invalid version: %w", err)
152146
}
@@ -170,25 +164,25 @@ type mtaYaml struct {
170164
Version string `json:"version"`
171165
}
172166

173-
func getVersionFromMtaFile(utils nexusUploadUtils, filePath string) (string, error) {
167+
func getInfoFromMtaFile(utils nexusUploadUtils, filePath string) (*mtaYaml, error) {
174168
mtaYamlContent, err := utils.fileRead(filePath)
175169
if err != nil {
176-
return "", fmt.Errorf("could not read from required project descriptor file '%s'",
170+
return nil, fmt.Errorf("could not read from required project descriptor file '%s'",
177171
filePath)
178172
}
179-
return getVersionFromMtaYaml(mtaYamlContent, filePath)
173+
return getInfoFromMtaYaml(mtaYamlContent, filePath)
180174
}
181175

182-
func getVersionFromMtaYaml(mtaYamlContent []byte, filePath string) (string, error) {
176+
func getInfoFromMtaYaml(mtaYamlContent []byte, filePath string) (*mtaYaml, error) {
183177
var mtaYaml mtaYaml
184178
err := yaml.Unmarshal(mtaYamlContent, &mtaYaml)
185179
if err != nil {
186180
// Eat the original error as it is unhelpful and confusingly mentions JSON, while the
187181
// user thinks it should parse YAML (it is transposed by the implementation).
188-
return "", fmt.Errorf("failed to parse contents of the project descriptor file '%s'",
182+
return nil, fmt.Errorf("failed to parse contents of the project descriptor file '%s'",
189183
filePath)
190184
}
191-
return mtaYaml.Version, nil
185+
return &mtaYaml, nil
192186
}
193187

194188
func createMavenExecuteOptions(options *nexusUploadOptions) maven.ExecuteOptions {

cmd/nexusUpload_generated.go

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/nexusUpload_test.go

+6-28
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,20 @@ func TestUploadMTAProjects(t *testing.T) {
166166
assert.Equal(t, 0, len(uploader.GetArtifacts()))
167167
assert.Equal(t, 0, len(uploader.uploadedArtifacts))
168168
})
169-
t.Run("Uploading MTA project without artifactId parameter fails", func(t *testing.T) {
169+
t.Run("Uploading MTA project without artifactId parameter works", func(t *testing.T) {
170170
utils := newMockUtilsBundle(true, false)
171171
utils.files["mta.yaml"] = testMtaYml
172+
utils.files["test.mtar"] = []byte("contentsOfMtar")
172173
utils.cpe[".pipeline/commonPipelineEnvironment/mtarFilePath"] = "test.mtar"
173174
uploader := mockUploader{}
174175
options := createOptions()
175176
options.ArtifactID = ""
176177

177178
err := runNexusUpload(&utils, &uploader, &options)
178-
assert.EqualError(t, err, "the 'artifactId' parameter was not provided and could not be retrieved from the Common Pipeline Environment")
179-
assert.Equal(t, 0, len(uploader.GetArtifacts()))
180-
assert.Equal(t, 0, len(uploader.uploadedArtifacts))
179+
if assert.NoError(t, err) {
180+
assert.Equal(t, 2, len(uploader.uploadedArtifacts))
181+
assert.Equal(t, "test", uploader.GetArtifactsID())
182+
}
181183
})
182184
t.Run("Uploading MTA project fails due to missing yaml file", func(t *testing.T) {
183185
utils := newMockUtilsBundle(true, false)
@@ -274,30 +276,6 @@ func TestUploadMTAProjects(t *testing.T) {
274276
assert.Equal(t, "0.3.0", uploader.GetArtifactsVersion())
275277
assert.Equal(t, "artifact.id", uploader.GetArtifactsID())
276278

277-
artifacts := uploader.uploadedArtifacts
278-
if assert.Equal(t, 2, len(artifacts)) {
279-
assert.Equal(t, "mta.yml", artifacts[0].File)
280-
assert.Equal(t, "yaml", artifacts[0].Type)
281-
282-
assert.Equal(t, "test.mtar", artifacts[1].File)
283-
assert.Equal(t, "mtar", artifacts[1].Type)
284-
}
285-
})
286-
t.Run("Test uploading mta.yml project works with artifactID from CPE", func(t *testing.T) {
287-
utils := newMockUtilsBundle(true, false)
288-
utils.files["mta.yml"] = testMtaYml
289-
utils.files["test.mtar"] = []byte("contentsOfMtar")
290-
utils.cpe[".pipeline/commonPipelineEnvironment/mtarFilePath"] = "test.mtar"
291-
utils.cpe[".pipeline/commonPipelineEnvironment/configuration/artifactId"] = "my-artifact-id"
292-
uploader := mockUploader{}
293-
options := createOptions()
294-
// Clear artifact ID to trigger reading it from the CPE
295-
options.ArtifactID = ""
296-
297-
err := runNexusUpload(&utils, &uploader, &options)
298-
assert.NoError(t, err, "expected mta.yml project upload to work")
299-
assert.Equal(t, "my-artifact-id", uploader.GetArtifactsID())
300-
301279
artifacts := uploader.uploadedArtifacts
302280
if assert.Equal(t, 2, len(artifacts)) {
303281
assert.Equal(t, "mta.yml", artifacts[0].File)

pkg/nexus/nexus.go

+30-26
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@ func (nexusUpload *Upload) SetRepoURL(nexusURL, nexusVersion, repository string)
4848
return nil
4949
}
5050

51+
func getBaseURL(nexusURL, nexusVersion, repository string) (string, error) {
52+
if nexusURL == "" {
53+
return "", errors.New("nexusURL must not be empty")
54+
}
55+
nexusURL = strings.ToLower(nexusURL)
56+
var protocols = []string{"http://", "https://"}
57+
for _, protocol := range protocols {
58+
if strings.HasPrefix(nexusURL, protocol) {
59+
nexusURL = strings.TrimPrefix(nexusURL, protocol)
60+
break
61+
}
62+
}
63+
if repository == "" {
64+
return "", errors.New("repository must not be empty")
65+
}
66+
baseURL := nexusURL
67+
switch nexusVersion {
68+
case "nexus2":
69+
baseURL += "/content/repositories/"
70+
case "nexus3":
71+
baseURL += "/repository/"
72+
default:
73+
return "", fmt.Errorf("unsupported Nexus version '%s', must be 'nexus2' or 'nexus3'", nexusVersion)
74+
}
75+
baseURL += repository + "/"
76+
// Replace any double slashes, as nexus does not like them
77+
baseURL = strings.ReplaceAll(baseURL, "//", "/")
78+
return baseURL, nil
79+
}
80+
5181
// GetRepoURL returns the base URL for the nexus repository.
5282
func (nexusUpload *Upload) GetRepoURL() string {
5383
return nexusUpload.repoURL
@@ -144,29 +174,3 @@ func (nexusUpload *Upload) GetArtifacts() []ArtifactDescription {
144174
func (nexusUpload *Upload) Clear() {
145175
nexusUpload.artifacts = []ArtifactDescription{}
146176
}
147-
148-
func getBaseURL(nexusURL, nexusVersion, repository string) (string, error) {
149-
if nexusURL == "" {
150-
return "", errors.New("nexusURL must not be empty")
151-
}
152-
nexusURL = strings.ToLower(nexusURL)
153-
if strings.HasPrefix(nexusURL, "http://") || strings.HasPrefix(nexusURL, "https://") {
154-
return "", errors.New("nexusURL must not start with 'http://' or 'https://'")
155-
}
156-
if repository == "" {
157-
return "", errors.New("repository must not be empty")
158-
}
159-
baseURL := nexusURL
160-
switch nexusVersion {
161-
case "nexus2":
162-
baseURL += "/content/repositories/"
163-
case "nexus3":
164-
baseURL += "/repository/"
165-
default:
166-
return "", fmt.Errorf("unsupported Nexus version '%s', must be 'nexus2' or 'nexus3'", nexusVersion)
167-
}
168-
baseURL += repository + "/"
169-
// Replace any double slashes, as nexus does not like them
170-
baseURL = strings.ReplaceAll(baseURL, "//", "/")
171-
return baseURL, nil
172-
}

pkg/nexus/nexus_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,16 @@ func TestSetBaseURL(t *testing.T) {
110110
t.Run("Test host wrongly includes protocol http://", func(t *testing.T) {
111111
nexusUpload := Upload{}
112112
err := nexusUpload.SetRepoURL("htTp://localhost:8081", "nexus3", "maven-releases")
113-
assert.Error(t, err, "Expected SetRepoURL() to fail (invalid host)")
113+
if assert.NoError(t, err, "Expected SetRepoURL() to work") {
114+
assert.Equal(t, "localhost:8081/repository/maven-releases/", nexusUpload.repoURL)
115+
}
114116
})
115117
t.Run("Test host wrongly includes protocol https://", func(t *testing.T) {
116118
nexusUpload := Upload{}
117119
err := nexusUpload.SetRepoURL("htTpS://localhost:8081", "nexus3", "maven-releases")
118-
assert.Error(t, err, "Expected SetRepoURL() to fail (invalid host)")
120+
if assert.NoError(t, err, "Expected SetRepoURL() to work") {
121+
assert.Equal(t, "localhost:8081/repository/maven-releases/", nexusUpload.repoURL)
122+
}
119123
})
120124
t.Run("Test invalid version provided", func(t *testing.T) {
121125
nexusUpload := Upload{}

resources/metadata/nexusUpload.yaml

+12-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ spec:
1212
- name: nexusCredentialsId
1313
description: The technical username/password credential for accessing the nexus endpoint.
1414
type: jenkins
15+
aliases:
16+
- name: nexus/credentialsId
1517
params:
1618
- name: version
1719
type: string
@@ -22,6 +24,8 @@ spec:
2224
- STEPS
2325
mandatory: false
2426
default: nexus3
27+
aliases:
28+
- name: nexus/version
2529
- name: url
2630
type: string
2731
description: URL of the nexus. The scheme part of the URL will not be considered, because only http is supported.
@@ -30,6 +34,8 @@ spec:
3034
- STAGES
3135
- STEPS
3236
mandatory: true
37+
aliases:
38+
- name: nexus/url
3339
- name: repository
3440
type: string
3541
description: Name of the nexus repository.
@@ -38,22 +44,22 @@ spec:
3844
- STAGES
3945
- STEPS
4046
mandatory: true
41-
default:
47+
aliases:
48+
- name: nexus/repository
4249
- name: groupId
4350
type: string
4451
description: Group ID of the artifacts. Only used in MTA projects, ignored for Maven.
4552
scope:
4653
- PARAMETERS
4754
- STAGES
4855
- STEPS
49-
mandatory: false
56+
aliases:
57+
- name: nexus/groupId
5058
- name: artifactId
5159
type: string
5260
description: The artifact ID used for both the .mtar and mta.yaml files deployed for MTA projects, ignored for Maven.
5361
scope:
5462
- PARAMETERS
55-
- STAGES
56-
- STEPS
5763
- name: globalSettingsFile
5864
type: string
5965
description: Path to the mvn settings file that should be used as global settings file.
@@ -81,20 +87,18 @@ spec:
8187
- PARAMETERS
8288
- STAGES
8389
- STEPS
90+
aliases:
91+
- name: nexus/additionalClassifiers
8492
- name: user
8593
type: string
8694
description: User
8795
scope:
8896
- PARAMETERS
89-
- STAGES
90-
- STEPS
9197
- name: password
9298
type: string
9399
description: Password
94100
scope:
95101
- PARAMETERS
96-
- STAGES
97-
- STEPS
98102
containers:
99103
- name: mvn
100104
image: maven:3.6-jdk-8

test/groovy/CommonStepsTest.groovy

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public class CommonStepsTest extends BasePiperTest{
133133
'nexusUpload', //implementing new golang pattern without fields
134134
'mavenBuild', //implementing new golang pattern without fields
135135
'mavenExecuteStaticCodeChecks', //implementing new golang pattern without fields
136+
'piperPipelineStageArtifactDeployment', //stage without step flags
136137
]
137138

138139
@Test

vars/nexusUpload.groovy

+11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
1+
import com.sap.piper.DownloadCacheUtils
12
import groovy.transform.Field
23

4+
import static groovy.json.JsonOutput.toJson
5+
36
@Field String STEP_NAME = getClass().getName()
47
@Field String METADATA_FILE = 'metadata/nexusUpload.yaml'
58

69
//Metadata maintained in file project://resources/metadata/nexusUpload.yaml
710

811
void call(Map parameters = [:]) {
12+
// Replace 'additionalClassifiers' List with JSON encoded String.
13+
// This is currently necessary, since the go code doesn't support complex/arbitrary parameter types.
14+
// TODO: Support complex/structured types of parameters in piper-go
15+
if (parameters.additionalClassifiers) {
16+
parameters.additionalClassifiers = "${toJson(parameters.additionalClassifiers as List)}"
17+
}
18+
parameters = DownloadCacheUtils.injectDownloadCacheInMavenParameters(parameters.script, parameters)
19+
920
List credentials = [[type: 'usernamePassword', id: 'nexusCredentialsId', env: ['PIPER_username', 'PIPER_password']]]
1021
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
1122
}

vars/piperExecuteBin.groovy

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static String getCustomDefaultConfigsArg() {
6868

6969
static String getCustomConfigArg(def script) {
7070
if (script?.commonPipelineEnvironment?.configurationFile
71+
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yml'
7172
&& script.commonPipelineEnvironment.configurationFile != '.pipeline/config.yaml') {
7273
return " --customConfig ${BashUtils.quoteAndEscape(script.commonPipelineEnvironment.configurationFile)}"
7374
}

0 commit comments

Comments
 (0)