From 82a9a8e824b437aee5d26e7a7f818fbb93cdda64 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 18 Sep 2018 14:48:06 +0200 Subject: [PATCH 01/12] Enum for the backend types --- src/com/sap/piper/cm/ChangeManagement.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index 06db849ce09..ad1148f2c54 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -9,6 +9,7 @@ import hudson.AbortException public class ChangeManagement implements Serializable { + public enum BackendType {SOLMAN, CTS, NONE} private script private GitUtils gitUtils From 80572f856997544e8fe536bda0902f5da124f721 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 18 Sep 2018 14:48:47 +0200 Subject: [PATCH 02/12] Backend type in default configuration. --- resources/default_pipeline_environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index f157da12ec7..f83abea0b0e 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -3,6 +3,7 @@ general: productiveBranch: 'master' collectTelemetryData: true changeManagement: + type: 'SOLMAN' # SOLMAN, CTS transportRequestLabel: 'TransportRequest\s?:' changeDocumentLabel: 'ChangeDocument\s?:' clientOpts: '' From cfd25198b04e9eae19139dcf429518667863f423 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 18 Sep 2018 14:49:06 +0200 Subject: [PATCH 03/12] transportRequestUploadFile step --- .../TransportRequestUploadFileTest.groovy | 13 +++ vars/transportRequestUploadFile.groovy | 79 +++++++++++++------ 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/test/groovy/TransportRequestUploadFileTest.groovy b/test/groovy/TransportRequestUploadFileTest.groovy index 814ce7b26d5..5e32a02c01b 100644 --- a/test/groovy/TransportRequestUploadFileTest.groovy +++ b/test/groovy/TransportRequestUploadFileTest.groovy @@ -291,4 +291,17 @@ public class TransportRequestUploadFileTest extends BasePiperTest { cmUtils: cm) } + @Test + public void invalidBackendTypeTest() { + thrown.expect(AbortException) + thrown.expectMessage('Invalid backend type: \'DUMMY\'. Valid values: [SOLMAN, CTS, NONE]. ' + + 'Configuration: \'changeManagement/type\'.') + + jsr.step.call(script: nullScript, + applicationId: 'app', + filePath: '/path', + changeManagement: [type: 'DUMMY']) + + } + } diff --git a/vars/transportRequestUploadFile.groovy b/vars/transportRequestUploadFile.groovy index 98d3886675d..ab5a405597b 100644 --- a/vars/transportRequestUploadFile.groovy +++ b/vars/transportRequestUploadFile.groovy @@ -9,7 +9,6 @@ import com.sap.piper.cm.ChangeManagementException import hudson.AbortException - @Field def STEP_NAME = 'transportRequestUploadFile' @Field Set generalConfigurationKeys = [ @@ -45,6 +44,7 @@ def call(parameters = [:]) { .withMandatoryProperty('changeManagement/clientOpts') .withMandatoryProperty('changeManagement/credentialsId') .withMandatoryProperty('changeManagement/endpoint') + .withMandatoryProperty('changeManagement/type') .withMandatoryProperty('changeManagement/git/from') .withMandatoryProperty('changeManagement/git/to') .withMandatoryProperty('changeManagement/git/format') @@ -52,31 +52,46 @@ def call(parameters = [:]) { Map configuration = configHelper.use() - new Utils().pushToSWA([step: STEP_NAME], configuration) + new Utils().pushToSWA([step: STEP_NAME, stepParam1: configuration.changeManagement.type], configuration) - def changeDocumentId = configuration.changeDocumentId + ChangeManagement.BackendType backendType - if(changeDocumentId?.trim()) { + try { + backendType = configuration.changeManagement.type as ChangeManagement.BackendType + } catch(IllegalArgumentException e) { + error "Invalid backend type: '${configuration.changeManagement.type}'. " + + "Valid values: [${ChangeManagement.BackendType.values().join(', ')}]. " + + "Configuration: 'changeManagement/type'." + } - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." + def changeDocumentId = null - } else { + if(backendType == ChangeManagement.BackendType.SOLMAN) { - echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + - "Searching for pattern '${configuration.changeManagement.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." + changeDocumentId = configuration.changeDocumentId - try { - changeDocumentId = cm.getChangeDocumentId( - configuration.changeManagement.git.from, - configuration.changeManagement.git.to, - configuration.changeManagement.changeDocumentLabel, - configuration.changeManagement.git.format - ) + if(changeDocumentId?.trim()) { - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." - } catch(ChangeManagementException ex) { - echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + } else { + + echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + + "Searching for pattern '${configuration.changeManagement.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." + + try { + changeDocumentId = cm.getChangeDocumentId( + configuration.changeManagement.git.from, + configuration.changeManagement.git.to, + configuration.changeManagement.changeDocumentLabel, + configuration.changeManagement.git.format + ) + + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" + + } catch(ChangeManagementException ex) { + echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + } } } @@ -106,16 +121,26 @@ def call(parameters = [:]) { } } + configHelper + .mixin([changeDocumentId: changeDocumentId?.trim() ?: null, + transportRequestId: transportRequestId?.trim() ?: null], ['changeDocumentId', 'transportRequestId'] as Set) + + if(backendType == ChangeManagement.BackendType.SOLMAN) { + configHelper + .withMandatoryProperty('changeDocumentId', + "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") + } configuration = configHelper - .mixin([changeDocumentId: changeDocumentId?.trim() ?: null, - transportRequestId: transportRequestId?.trim() ?: null], ['changeDocumentId', 'transportRequestId'] as Set) - .withMandatoryProperty('changeDocumentId', - "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") - .withMandatoryProperty('transportRequestId', + .withMandatoryProperty('transportRequestId', "Transport request id not provided (parameter: \'transportRequestId\' or via commit history).") .use() - echo "[INFO] Uploading file '${configuration.filePath}' to transport request '${configuration.transportRequestId}' of change document '${configuration.changeDocumentId}'." + def uploadingMessage = ["[INFO] Uploading file '${configuration.filePath}' to transport request '${configuration.transportRequestId}'"] + if(backendType == ChangeManagement.BackendType.SOLMAN) + uploadingMessage << " of change document '${configuration.changeDocumentId}'" + uploadingMessage << '.' + + echo uploadingMessage.join() try { @@ -133,6 +158,10 @@ def call(parameters = [:]) { } - echo "[INFO] File '${configuration.filePath}' has been successfully uploaded to transport request '${configuration.transportRequestId}' of change document '${configuration.changeDocumentId}'." + def uploadedMessage = ["[INFO] File '${configuration.filePath}' has been successfully uploaded to transport request '${configuration.transportRequestId}'"] + if(backendType == ChangeManagement.BackendType.SOLMAN) + uploadedMessage << " of change document '${configuration.changeDocumentId}'" + uploadedMessage << '.' + echo uploadedMessage.join() } } From e40e3eb72f6716feb055530bd1f942427b74f9f1 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 18 Sep 2018 12:19:52 +0200 Subject: [PATCH 04/12] Introduce backendType in ChangeManagement util internally without affecting method signatures. --- src/com/sap/piper/cm/ChangeManagement.groovy | 17 +++++++++-------- .../sap/piper/cm/ChangeManagementTest.groovy | 6 ++++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index ad1148f2c54..d04ab1f24a2 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -66,7 +66,7 @@ public class ChangeManagement implements Serializable { } boolean isChangeInDevelopment(String changeId, String endpoint, String credentialsId, String clientOpts = '') { - int rc = executeWithCredentials(endpoint, credentialsId, 'is-change-in-development', ['-cID', "'${changeId}'", '--return-code'], + int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'is-change-in-development', ['-cID', "'${changeId}'", '--return-code'], clientOpts) as int if (rc == 0) { @@ -80,7 +80,7 @@ public class ChangeManagement implements Serializable { String createTransportRequest(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') { try { - def transportRequest = executeWithCredentials(endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId], + def transportRequest = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId], clientOpts) return transportRequest.trim() as String }catch(AbortException e) { @@ -90,7 +90,7 @@ public class ChangeManagement implements Serializable { void uploadFileToTransportRequest(String changeId, String transportRequestId, String applicationId, String filePath, String endpoint, String credentialsId, String cmclientOpts = '') { - int rc = executeWithCredentials(endpoint, credentialsId, 'upload-file-to-transport', ['-cID', changeId, + int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'upload-file-to-transport', ['-cID', changeId, '-tID', transportRequestId, applicationId, "\"$filePath\""], cmclientOpts) as int @@ -103,12 +103,12 @@ public class ChangeManagement implements Serializable { } - def executeWithCredentials(String endpoint, String credentialsId, String command, List args, String clientOpts = '') { + def executeWithCredentials(BackendType type, String endpoint, String credentialsId, String command, List args, String clientOpts = '') { script.withCredentials([script.usernamePassword( credentialsId: credentialsId, passwordVariable: 'password', usernameVariable: 'username')]) { - def cmScript = getCMCommandLine(endpoint, script.username, script.password, + def cmScript = getCMCommandLine(type, endpoint, script.username, script.password, command, args, clientOpts) // user and password are masked by withCredentials @@ -122,7 +122,7 @@ public class ChangeManagement implements Serializable { } void releaseTransportRequest(String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') { - int rc = executeWithCredentials( endpoint, credentialsId, 'release-transport', ['-cID', changeId, + int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'release-transport', ['-cID', changeId, '-tID', transportRequestId], clientOpts) as int if(rc == 0) { return @@ -131,7 +131,8 @@ public class ChangeManagement implements Serializable { } } - String getCMCommandLine(String endpoint, + String getCMCommandLine(BackendType type, + String endpoint, String username, String password, String command, @@ -146,7 +147,7 @@ public class ChangeManagement implements Serializable { cmclient -e '$endpoint' \ -u '$username' \ -p '$password' \ - -t SOLMAN \ + -t ${type} \ ${command} ${(args as Iterable).join(' ')} """ return cmCommandLine diff --git a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy index d0c1b964d15..ab274346482 100644 --- a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy +++ b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy @@ -130,7 +130,8 @@ public class ChangeManagementTest extends BasePiperTest { @Test public void testGetCommandLineWithoutCMClientOpts() { String commandLine = new ChangeManagement(nullScript, null) - .getCMCommandLine('https://example.org/cm', + .getCMCommandLine(ChangeManagement.BackendType.SOLMAN, + 'https://example.org/cm', "me", "topSecret", "the-command", @@ -143,7 +144,8 @@ public class ChangeManagementTest extends BasePiperTest { @Test public void testGetCommandLineWithCMClientOpts() { String commandLine = new ChangeManagement(nullScript, null) - .getCMCommandLine('https://example.org/cm', + .getCMCommandLine(ChangeManagement.BackendType.SOLMAN, + 'https://example.org/cm', "me", "topSecret", "the-command", From 141210beb278ef7f4272eb64dd7f7594399cc2e3 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 18 Sep 2018 12:29:14 +0200 Subject: [PATCH 05/12] Expose backendType for uploading files into transports --- .../TransportRequestUploadFileTest.groovy | 20 +++++++++++++------ vars/transportRequestUploadFile.groovy | 3 ++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/test/groovy/TransportRequestUploadFileTest.groovy b/test/groovy/TransportRequestUploadFileTest.groovy index 5e32a02c01b..3bc210053eb 100644 --- a/test/groovy/TransportRequestUploadFileTest.groovy +++ b/test/groovy/TransportRequestUploadFileTest.groovy @@ -112,7 +112,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { public void uploadFileToTransportRequestFailureTest() { ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, @@ -141,7 +142,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { jlr.expect("[INFO] File '/path' has been successfully uploaded to transport request '002' of change document '001'.") ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, @@ -149,6 +151,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { String credentialsId, String cmclientOpts) { + cmUtilReceivedParams.type = type cmUtilReceivedParams.changeId = changeId cmUtilReceivedParams.transportRequestId = transportRequestId cmUtilReceivedParams.applicationId = applicationId @@ -168,6 +171,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { assert cmUtilReceivedParams == [ + type: ChangeManagement.BackendType.SOLMAN, changeId: '001', transportRequestId: '002', applicationId: 'app', @@ -186,7 +190,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { [applicationId: 'AppIdfromConfig']]]) ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, @@ -215,7 +220,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { nullScript.commonPipelineEnvironment.setMtarFilePath('/path2') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, @@ -244,7 +250,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { nullScript.commonPipelineEnvironment.setMtarFilePath('/path2') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, @@ -272,7 +279,8 @@ public class TransportRequestUploadFileTest extends BasePiperTest { thrown.expectMessage('Upload failure.') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(String changeId, + void uploadFileToTransportRequest(ChangeManagement.BackendType type, + String changeId, String transportRequestId, String applicationId, String filePath, diff --git a/vars/transportRequestUploadFile.groovy b/vars/transportRequestUploadFile.groovy index ab5a405597b..08fc80b527c 100644 --- a/vars/transportRequestUploadFile.groovy +++ b/vars/transportRequestUploadFile.groovy @@ -145,7 +145,8 @@ def call(parameters = [:]) { try { - cm.uploadFileToTransportRequest(configuration.changeDocumentId, + cm.uploadFileToTransportRequest(backendType, + configuration.changeDocumentId, configuration.transportRequestId, configuration.applicationId, configuration.filePath, From f34308ffe082aecc2297aca2a0bf3c40a4a1b231 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Mon, 24 Sep 2018 14:06:48 +0200 Subject: [PATCH 06/12] upload file to transport for CTS use case --- src/com/sap/piper/cm/BackendType.groovy | 5 ++ src/com/sap/piper/cm/ChangeManagement.groovy | 27 +++++-- .../TransportRequestUploadFileTest.groovy | 75 ++++++++++++++++--- .../sap/piper/cm/ChangeManagementTest.groovy | 37 +++++++-- vars/transportRequestUploadFile.groovy | 17 +++-- 5 files changed, 130 insertions(+), 31 deletions(-) create mode 100644 src/com/sap/piper/cm/BackendType.groovy diff --git a/src/com/sap/piper/cm/BackendType.groovy b/src/com/sap/piper/cm/BackendType.groovy new file mode 100644 index 00000000000..d3a9dacae0d --- /dev/null +++ b/src/com/sap/piper/cm/BackendType.groovy @@ -0,0 +1,5 @@ +package com.sap.piper.cm; + +public enum BackendType { + SOLMAN, CTS, NONE +} diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index d04ab1f24a2..247cf1d7237 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -9,7 +9,6 @@ import hudson.AbortException public class ChangeManagement implements Serializable { - public enum BackendType {SOLMAN, CTS, NONE} private script private GitUtils gitUtils @@ -89,11 +88,27 @@ public class ChangeManagement implements Serializable { } - void uploadFileToTransportRequest(String changeId, String transportRequestId, String applicationId, String filePath, String endpoint, String credentialsId, String cmclientOpts = '') { - int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'upload-file-to-transport', ['-cID', changeId, - '-tID', transportRequestId, - applicationId, "\"$filePath\""], - cmclientOpts) as int + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, String filePath, String endpoint, String credentialsId, String cmclientOpts = '') { + + def args = null + + if(type == BackendType.SOLMAN) { + args = ['-cID', changeId, + '-tID', transportRequestId, + applicationId, "\"$filePath\""] + } else if (type == BackendType.CTS) { + args = ['-tID', transportRequestId, + "\"$filePath\""] + } else { + throw new IllegalArgumentException("Invalid backend type: ${type}") + } + + int rc = executeWithCredentials(type, + endpoint, + credentialsId, + 'upload-file-to-transport', + args, + cmclientOpts) as int if(rc == 0) { return diff --git a/test/groovy/TransportRequestUploadFileTest.groovy b/test/groovy/TransportRequestUploadFileTest.groovy index 3bc210053eb..125d1825aaa 100644 --- a/test/groovy/TransportRequestUploadFileTest.groovy +++ b/test/groovy/TransportRequestUploadFileTest.groovy @@ -6,6 +6,7 @@ import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagement import com.sap.piper.cm.ChangeManagementException @@ -51,7 +52,11 @@ public class TransportRequestUploadFileTest extends BasePiperTest { } @Test - public void changeDocumentIdNotProvidedTest() { + public void changeDocumentIdNotProvidedSOLMANTest() { + + // we expect the failure only for SOLMAN (which is the default). + // Use case for CTS without change document id is checked by the + // straight forward test case for CTS thrown.expect(IllegalArgumentException) thrown.expectMessage("Change document id not provided (parameter: 'changeDocumentId' or via commit history).") @@ -91,7 +96,11 @@ public class TransportRequestUploadFileTest extends BasePiperTest { } @Test - public void applicationIdNotProvidedTest() { + public void applicationIdNotProvidedSOLMANTest() { + + // we expect the failure only for SOLMAN (which is the default). + // Use case for CTS without applicationId is checked by the + // straight forward test case for CTS thrown.expect(IllegalArgumentException) thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR applicationId") @@ -112,7 +121,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { public void uploadFileToTransportRequestFailureTest() { ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, @@ -136,13 +145,59 @@ public class TransportRequestUploadFileTest extends BasePiperTest { } @Test - public void uploadFileToTransportRequestSuccessTest() { + public void uploadFileToTransportRequestCTSSuccessTest() { + + jlr.expect("[INFO] Uploading file '/path' to transport request '002'.") + jlr.expect("[INFO] File '/path' has been successfully uploaded to transport request '002'.") + + ChangeManagement cm = new ChangeManagement(nullScript) { + void uploadFileToTransportRequest(BackendType type, + String changeId, + String transportRequestId, + String applicationId, + String filePath, + String endpoint, + String credentialsId, + String cmclientOpts) { + + cmUtilReceivedParams.type = type + cmUtilReceivedParams.changeId = changeId + cmUtilReceivedParams.transportRequestId = transportRequestId + cmUtilReceivedParams.applicationId = applicationId + cmUtilReceivedParams.filePath = filePath + cmUtilReceivedParams.endpoint = endpoint + cmUtilReceivedParams.credentialsId = credentialsId + cmUtilReceivedParams.cmclientOpts = cmclientOpts + } + } + + jsr.step.call(script: nullScript, + changeManagement: [type: 'CTS'], + transportRequestId: '002', + filePath: '/path', + cmUtils: cm) + + assert cmUtilReceivedParams == + [ + type: BackendType.CTS, + changeId: null, + transportRequestId: '002', + applicationId: null, + filePath: '/path', + endpoint: 'https://example.org/cm', + credentialsId: 'CM', + cmclientOpts: '' + ] + } + + @Test + public void uploadFileToTransportRequestSOLMANSuccessTest() { jlr.expect("[INFO] Uploading file '/path' to transport request '002' of change document '001'.") jlr.expect("[INFO] File '/path' has been successfully uploaded to transport request '002' of change document '001'.") ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, @@ -171,7 +226,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { assert cmUtilReceivedParams == [ - type: ChangeManagement.BackendType.SOLMAN, + type: BackendType.SOLMAN, changeId: '001', transportRequestId: '002', applicationId: 'app', @@ -190,7 +245,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { [applicationId: 'AppIdfromConfig']]]) ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, @@ -220,7 +275,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { nullScript.commonPipelineEnvironment.setMtarFilePath('/path2') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, @@ -250,7 +305,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { nullScript.commonPipelineEnvironment.setMtarFilePath('/path2') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, @@ -279,7 +334,7 @@ public class TransportRequestUploadFileTest extends BasePiperTest { thrown.expectMessage('Upload failure.') ChangeManagement cm = new ChangeManagement(nullScript) { - void uploadFileToTransportRequest(ChangeManagement.BackendType type, + void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, diff --git a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy index ab274346482..1fc71ef1949 100644 --- a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy +++ b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy @@ -130,7 +130,7 @@ public class ChangeManagementTest extends BasePiperTest { @Test public void testGetCommandLineWithoutCMClientOpts() { String commandLine = new ChangeManagement(nullScript, null) - .getCMCommandLine(ChangeManagement.BackendType.SOLMAN, + .getCMCommandLine(BackendType.SOLMAN, 'https://example.org/cm', "me", "topSecret", @@ -144,7 +144,7 @@ public class ChangeManagementTest extends BasePiperTest { @Test public void testGetCommandLineWithCMClientOpts() { String commandLine = new ChangeManagement(nullScript, null) - .getCMCommandLine(ChangeManagement.BackendType.SOLMAN, + .getCMCommandLine(BackendType.SOLMAN, 'https://example.org/cm', "me", "topSecret", @@ -176,7 +176,8 @@ public void testGetCommandLineWithCMClientOpts() { thrown.expectMessage('Cannot upload file \'/path\' for change document \'001\''+ ' with transport request \'002\'. Return code from cmclient: 1.') - new ChangeManagement(nullScript).uploadFileToTransportRequest('001', + new ChangeManagement(nullScript).uploadFileToTransportRequest(BackendType.SOLMAN, + '001', '002', 'XXX', '/path', @@ -185,12 +186,14 @@ public void testGetCommandLineWithCMClientOpts() { } @Test - public void testUploadFileToTransportSucceeds() { + public void testUploadFileToTransportSucceedsSOLMAN() { // the regex provided below is an implicit check that the command line is fine. - script.setReturnValue(JenkinsShellCallRule.Type.REGEX,, 'upload-file-to-transport.*-cID 001 -tID 002 XXX "/path"', 0) + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'upload-file-to-transport.*-cID 001 -tID 002 XXX "/path"', 0) - new ChangeManagement(nullScript).uploadFileToTransportRequest('001', + new ChangeManagement(nullScript).uploadFileToTransportRequest( + BackendType.SOLMAN, + '001', '002', 'XXX', '/path', @@ -201,6 +204,25 @@ public void testGetCommandLineWithCMClientOpts() { // the command line. } + @Test + public void testUploadFileToTransportSucceedsCTS() { + + // the regex provided below is an implicit check that the command line is fine. + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS upload-file-to-transport -tID 002 "/path"', 0) + + new ChangeManagement(nullScript).uploadFileToTransportRequest( + BackendType.CTS, + null, + '002', + null, + '/path', + 'https://example.org/cm', + 'me') + + // no assert required here, since the regex registered above to the script rule is an implicit check for + // the command line. + } + @Test public void testUploadFileToTransportFails() { @@ -210,7 +232,8 @@ public void testGetCommandLineWithCMClientOpts() { script.setReturnValue(JenkinsShellCallRule.Type.REGEX,, 'upload-file-to-transport', 1) - new ChangeManagement(nullScript).uploadFileToTransportRequest('001', + new ChangeManagement(nullScript).uploadFileToTransportRequest(BackendType.SOLMAN, + '001', '002', 'XXX', '/path', diff --git a/vars/transportRequestUploadFile.groovy b/vars/transportRequestUploadFile.groovy index 08fc80b527c..26b604ad7f8 100644 --- a/vars/transportRequestUploadFile.groovy +++ b/vars/transportRequestUploadFile.groovy @@ -5,6 +5,7 @@ import groovy.transform.Field import com.sap.piper.ConfigurationHelper import com.sap.piper.ConfigurationMerger import com.sap.piper.cm.ChangeManagement +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagementException import hudson.AbortException @@ -39,7 +40,6 @@ def call(parameters = [:]) { .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, stepConfigurationKeys) .mixin(parameters, parameterKeys) .addIfEmpty('filePath', script.commonPipelineEnvironment.getMtarFilePath()) - .withMandatoryProperty('applicationId') .withMandatoryProperty('changeManagement/changeDocumentLabel') .withMandatoryProperty('changeManagement/clientOpts') .withMandatoryProperty('changeManagement/credentialsId') @@ -54,19 +54,19 @@ def call(parameters = [:]) { new Utils().pushToSWA([step: STEP_NAME, stepParam1: configuration.changeManagement.type], configuration) - ChangeManagement.BackendType backendType + BackendType backendType try { - backendType = configuration.changeManagement.type as ChangeManagement.BackendType + backendType = configuration.changeManagement.type as BackendType } catch(IllegalArgumentException e) { error "Invalid backend type: '${configuration.changeManagement.type}'. " + - "Valid values: [${ChangeManagement.BackendType.values().join(', ')}]. " + + "Valid values: [${BackendType.values().join(', ')}]. " + "Configuration: 'changeManagement/type'." } def changeDocumentId = null - if(backendType == ChangeManagement.BackendType.SOLMAN) { + if(backendType == BackendType.SOLMAN) { changeDocumentId = configuration.changeDocumentId @@ -125,10 +125,11 @@ def call(parameters = [:]) { .mixin([changeDocumentId: changeDocumentId?.trim() ?: null, transportRequestId: transportRequestId?.trim() ?: null], ['changeDocumentId', 'transportRequestId'] as Set) - if(backendType == ChangeManagement.BackendType.SOLMAN) { + if(backendType == BackendType.SOLMAN) { configHelper .withMandatoryProperty('changeDocumentId', "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") + .withMandatoryProperty('applicationId') } configuration = configHelper .withMandatoryProperty('transportRequestId', @@ -136,7 +137,7 @@ def call(parameters = [:]) { .use() def uploadingMessage = ["[INFO] Uploading file '${configuration.filePath}' to transport request '${configuration.transportRequestId}'"] - if(backendType == ChangeManagement.BackendType.SOLMAN) + if(backendType == BackendType.SOLMAN) uploadingMessage << " of change document '${configuration.changeDocumentId}'" uploadingMessage << '.' @@ -160,7 +161,7 @@ def call(parameters = [:]) { def uploadedMessage = ["[INFO] File '${configuration.filePath}' has been successfully uploaded to transport request '${configuration.transportRequestId}'"] - if(backendType == ChangeManagement.BackendType.SOLMAN) + if(backendType == BackendType.SOLMAN) uploadedMessage << " of change document '${configuration.changeDocumentId}'" uploadedMessage << '.' echo uploadedMessage.join() From ddbb09fa66cee9bd33c4c9b81dc92c8581430f52 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 25 Sep 2018 09:12:07 +0200 Subject: [PATCH 07/12] transport request create CTS --- src/com/sap/piper/cm/ChangeManagement.groovy | 22 ++++-- test/groovy/TransportRequestCreateTest.groovy | 55 ++++++++++++- .../sap/piper/cm/ChangeManagementTest.groovy | 22 +++++- vars/transportRequestCreate.groovy | 79 ++++++++++++++----- 4 files changed, 149 insertions(+), 29 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index 247cf1d7237..9013283480f 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -77,16 +77,28 @@ public class ChangeManagement implements Serializable { } } - String createTransportRequest(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') { + String createTransportRequestCTS(String transportType, String targetSystemId, String description, String endpoint, String credentialsId, String clientOpts = '') { try { - def transportRequest = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId], - clientOpts) - return transportRequest.trim() as String + def transportRequest = executeWithCredentials(BackendType.CTS, endpoint, credentialsId, 'create-transport', + ['-tt', transportType, '-ts', targetSystemId, '-d', "\"${description}\""], + clientOpts) + return transportRequest?.trim() as String }catch(AbortException e) { - throw new ChangeManagementException("Cannot create a transport request for change id '$changeId'. $e.message.") + throw new ChangeManagementException("Cannot create a transport request. $e.message.") } } + String createTransportRequestSOLMAN(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') { + + try { + def transportRequest = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'create-transport', + ['-cID', changeId, '-dID', developmentSystemId], + clientOpts) + return transportRequest?.trim() as String + }catch(AbortException e) { + throw new ChangeManagementException("Cannot create a transport request for change id '$changeId'. $e.message.") + } + } void uploadFileToTransportRequest(BackendType type, String changeId, String transportRequestId, String applicationId, String filePath, String endpoint, String credentialsId, String cmclientOpts = '') { diff --git a/test/groovy/TransportRequestCreateTest.groovy b/test/groovy/TransportRequestCreateTest.groovy index f1154cbcd6c..7dd9a356a1b 100644 --- a/test/groovy/TransportRequestCreateTest.groovy +++ b/test/groovy/TransportRequestCreateTest.groovy @@ -4,6 +4,7 @@ import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagement import com.sap.piper.cm.ChangeManagementException @@ -84,7 +85,8 @@ public class TransportRequestCreateTest extends BasePiperTest { ChangeManagement cm = new ChangeManagement(nullScript) { - String createTransportRequest(String changeId, + String createTransportRequestSOLMAN( + String changeId, String developmentSystemId, String cmEndpoint, String credentialId, @@ -102,13 +104,14 @@ public class TransportRequestCreateTest extends BasePiperTest { } @Test - public void createTransportRequestSuccessTest() { + public void createTransportRequestSuccessSOLMANTest() { def result = [:] ChangeManagement cm = new ChangeManagement(nullScript) { - String createTransportRequest(String changeId, + String createTransportRequestSOLMAN( + String changeId, String developmentSystemId, String cmEndpoint, String credentialId, @@ -137,4 +140,50 @@ public class TransportRequestCreateTest extends BasePiperTest { assert jlr.log.contains("[INFO] Creating transport request for change document '001' and development system '001'.") assert jlr.log.contains("[INFO] Transport Request '001' has been successfully created.") } + + @Test + public void createTransportRequestSuccessCTSTest() { + + def result = [:] + + ChangeManagement cm = new ChangeManagement(nullScript) { + + String createTransportRequestCTS( + String transportType, + String targetSystemId, + String description, + String endpoint, + String credentialsId, + String clientOpts +) { + result.transportType = transportType + result.targetSystemId = targetSystemId + result.description = description + result.endpoint = endpoint + result.credentialsId = credentialsId + result.clientOpts = clientOpts + return '001' + } + } + + def transportId = jsr.step.call(script: nullScript, + transportType: 'W', + targetSystem: 'XYZ', + description: 'desc', + changeManagement: [type: 'CTS'], + cmUtils: cm) + + assert transportId == '001' + assert result == [transportType: 'W', + targetSystemId: 'XYZ', + description: 'desc', + endpoint: 'https://example.org/cm', + credentialsId: 'CM', + clientOpts: '-DmyProp=myVal' + ] + + assert jlr.log.contains("[INFO] Creating transport request.") + assert jlr.log.contains("[INFO] Transport Request '001' has been successfully created.") + } + } diff --git a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy index 1fc71ef1949..9613f60b76d 100644 --- a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy +++ b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy @@ -156,10 +156,28 @@ public void testGetCommandLineWithCMClientOpts() { } @Test - public void testCreateTransportRequestSucceeds() { + public void testCreateTransportRequestSOLMANSucceeds() { script.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".*cmclient.*create-transport -cID 001 -dID 002.*", '004') - def transportRequestId = new ChangeManagement(nullScript).createTransportRequest('001', '002', '003', 'me') + def transportRequestId = new ChangeManagement(nullScript).createTransportRequestSOLMAN( '001', '002', '003', 'me') + + // the check for the transportRequestID is sufficient. This checks implicit the command line since that value is + // returned only in case the shell call matches. + assert transportRequestId == '004' + + } + + @Test + public void testCreateTransportRequestCTSSucceeds() { + + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'cmclient.* -t CTS .*create-transport -tt W -ts XYZ -d "desc 123"$', '004') + def transportRequestId = new ChangeManagement(nullScript) + .createTransportRequestCTS( + 'W', // transport type + 'XYZ', // target system + 'desc 123', // description + 'https://example.org/cm', + 'me') // the check for the transportRequestID is sufficient. This checks implicit the command line since that value is // returned only in case the shell call matches. diff --git a/vars/transportRequestCreate.groovy b/vars/transportRequestCreate.groovy index 504ee725a95..98d1c2fa9b4 100644 --- a/vars/transportRequestCreate.groovy +++ b/vars/transportRequestCreate.groovy @@ -4,6 +4,7 @@ import groovy.transform.Field import com.sap.piper.ConfigurationHelper import com.sap.piper.ConfigurationMerger +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagement import com.sap.piper.cm.ChangeManagementException @@ -14,7 +15,10 @@ import hudson.AbortException @Field Set stepConfigurationKeys = [ 'changeManagement', - 'developmentSystemId' + 'description', // CTS + 'developmentSystemId', // SOLMAN + 'targetSystem', // CTS + 'transportType', // CTS ] @Field Set parameterKeys = stepConfigurationKeys.plus(['changeDocumentId']) @@ -41,53 +45,90 @@ def call(parameters = [:]) { .withMandatoryProperty('changeManagement/git/from') .withMandatoryProperty('changeManagement/git/to') .withMandatoryProperty('changeManagement/git/format') - .withMandatoryProperty('developmentSystemId') Map configuration = configHelper.use() new Utils().pushToSWA([step: STEP_NAME], configuration) - def changeDocumentId = configuration.changeDocumentId + BackendType backendType - if(changeDocumentId?.trim()) { + try { + backendType = configuration.changeManagement.type as BackendType + } catch(IllegalArgumentException e) { + error "Invalid backend type: '${configuration.changeManagement.type}'. " + + "Valid values: [${BackendType.values().join(', ')}]. " + + "Configuration: 'changeManagement/type'." + } - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." + configHelper.withMandatoryProperty('transportType', null, { backendType == BackendType.CTS}) + configHelper.withMandatoryProperty('targetSystem', null, { backendType == BackendType.CTS}) + configHelper.withMandatoryProperty('description', null, { backendType == BackendType.CTS}) - } else { + def changeDocumentId = null - echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + - "Searching for pattern '${configuration.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." + if(backendType == BackendType.SOLMAN) { - try { + changeDocumentId = configuration.changeDocumentId + + if(changeDocumentId?.trim()) { + + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." + + } else { + + echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + + "Searching for pattern '${configuration.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." - changeDocumentId = cm.getChangeDocumentId( + try { + + changeDocumentId = cm.getChangeDocumentId( configuration.changeManagement.git.from, configuration.changeManagement.git.to, configuration.changeManagement.changeDocumentLabel, configuration.changeManagement.git.format ) - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" - } catch(ChangeManagementException ex) { - echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" + } catch(ChangeManagementException ex) { + echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + } } + configHelper.mixin([changeDocumentId: changeDocumentId?.trim() ?: null], ['changeDocumentId'] as Set) + .withMandatoryProperty('developmentSystemId') + .withMandatoryProperty('changeDocumentId', + "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") } - configuration = configHelper.mixin([changeDocumentId: changeDocumentId?.trim() ?: null], ['changeDocumentId'] as Set) - .withMandatoryProperty('changeDocumentId', - "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") - .use() + configuration = configHelper.use() def transportRequestId - echo "[INFO] Creating transport request for change document '${configuration.changeDocumentId}' and development system '${configuration.developmentSystemId}'." + def creatingMessage = ["[INFO] Creating transport request"] + if(backendType == BackendType.SOLMAN) { + creatingMessage << " for change document '${configuration.changeDocumentId}' and development system '${configuration.developmentSystemId}'" + } + creatingMessage << '.' + echo creatingMessage.join() try { - transportRequestId = cm.createTransportRequest(configuration.changeDocumentId, + if(backendType == BackendType.SOLMAN) { + transportRequestId = cm.createTransportRequestSOLMAN( + configuration.changeDocumentId, configuration.developmentSystemId, configuration.changeManagement.endpoint, configuration.changeManagement.credentialsId, configuration.changeManagement.clientOpts) + } else if(backendType == BackendType.CTS) { + transportRequestId = cm.createTransportRequestCTS( + configuration.transportType, + configuration.targetSystem, + configuration.description, + configuration.changeManagement.endpoint, + configuration.changeManagement.credentialsId, + configuration.changeManagement.clientOpts) + } else { + throw new IllegalArgumentException("Invalid backend type: '${backendType}'.") + } } catch(ChangeManagementException ex) { throw new AbortException(ex.getMessage()) } From a021f0bea93d8f59e622127ccf74a57807b3127a Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 25 Sep 2018 09:53:37 +0200 Subject: [PATCH 08/12] make sh returnStdout or returnStatus configurable inside ChangeManagement toolset --- src/com/sap/piper/cm/ChangeManagement.groovy | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index 06db849ce09..e0d6cc4eaa6 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -66,6 +66,7 @@ public class ChangeManagement implements Serializable { boolean isChangeInDevelopment(String changeId, String endpoint, String credentialsId, String clientOpts = '') { int rc = executeWithCredentials(endpoint, credentialsId, 'is-change-in-development', ['-cID', "'${changeId}'", '--return-code'], + false, clientOpts) as int if (rc == 0) { @@ -80,6 +81,7 @@ public class ChangeManagement implements Serializable { String createTransportRequest(String changeId, String developmentSystemId, String endpoint, String credentialsId, String clientOpts = '') { try { def transportRequest = executeWithCredentials(endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId], + false, clientOpts) return transportRequest.trim() as String }catch(AbortException e) { @@ -92,6 +94,7 @@ public class ChangeManagement implements Serializable { int rc = executeWithCredentials(endpoint, credentialsId, 'upload-file-to-transport', ['-cID', changeId, '-tID', transportRequestId, applicationId, "\"$filePath\""], + false, cmclientOpts) as int if(rc == 0) { @@ -102,7 +105,7 @@ public class ChangeManagement implements Serializable { } - def executeWithCredentials(String endpoint, String credentialsId, String command, List args, String clientOpts = '') { + def executeWithCredentials(String endpoint, String credentialsId, String command, List args, boolean returnStdout = false, String clientOpts = '') { script.withCredentials([script.usernamePassword( credentialsId: credentialsId, passwordVariable: 'password', @@ -110,19 +113,24 @@ public class ChangeManagement implements Serializable { def cmScript = getCMCommandLine(endpoint, script.username, script.password, command, args, clientOpts) + + Map shArgs = [:] + if(returnStdout) + shArgs.put('returnStdout', true) + else + shArgs.put('returnStatus', true) + + shArgs.put('script', cmScript) + // user and password are masked by withCredentials script.echo """[INFO] Executing command line: "${cmScript}".""" - def returnValue = script.sh(returnStatus: true, - script: cmScript) - return returnValue; - + return script.sh(shArgs) } - } void releaseTransportRequest(String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') { int rc = executeWithCredentials( endpoint, credentialsId, 'release-transport', ['-cID', changeId, - '-tID', transportRequestId], clientOpts) as int + '-tID', transportRequestId], false, clientOpts) as int if(rc == 0) { return } else { From 97edb902c5eeda0ed1187643e299c285eeeec563 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 25 Sep 2018 10:08:20 +0200 Subject: [PATCH 09/12] return stdout when creating transport requests --- src/com/sap/piper/cm/ChangeManagement.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index a0e56b7e305..767d31d2a82 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -82,9 +82,9 @@ public class ChangeManagement implements Serializable { try { def transportRequest = executeWithCredentials(BackendType.CTS, endpoint, credentialsId, 'create-transport', ['-tt', transportType, '-ts', targetSystemId, '-d', "\"${description}\""], - false, + true, clientOpts) - return transportRequest?.trim() as String + return (transportRequest as String)?.trim() }catch(AbortException e) { throw new ChangeManagementException("Cannot create a transport request. $e.message.") } @@ -94,9 +94,9 @@ public class ChangeManagement implements Serializable { try { def transportRequest = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'create-transport', ['-cID', changeId, '-dID', developmentSystemId], - false, + true, clientOpts) - return transportRequest.trim() as String + return (transportRequest as String)?.trim() }catch(AbortException e) { throw new ChangeManagementException("Cannot create a transport request for change id '$changeId'. $e.message.") } From 4d7274ee45f126b3a617fa0fa4c27748937993ce Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 25 Sep 2018 10:44:53 +0200 Subject: [PATCH 10/12] Introduce backend type for releasing transports --- src/com/sap/piper/cm/ChangeManagement.groovy | 16 ++++++++-- .../groovy/TransportRequestReleaseTest.groovy | 11 +++++-- .../sap/piper/cm/ChangeManagementTest.groovy | 30 ++++++++++++++++--- vars/transportRequestRelease.groovy | 4 ++- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index 767d31d2a82..e6aadcf4950 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -156,9 +156,19 @@ public class ChangeManagement implements Serializable { } } - void releaseTransportRequest(String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') { - int rc = executeWithCredentials(BackendType.SOLMAN, endpoint, credentialsId, 'release-transport', ['-cID', changeId, - '-tID', transportRequestId], false, clientOpts) as int + void releaseTransportRequest(BackendType type,String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') { + + List args = [] + + if(type == BackendType.SOLMAN) { + args << '-cID' + args << changeId + } + + args << '-tID' + args << transportRequestId + + int rc = executeWithCredentials(type, endpoint, credentialsId, 'release-transport', args, false, clientOpts) as int if(rc == 0) { return } else { diff --git a/test/groovy/TransportRequestReleaseTest.groovy b/test/groovy/TransportRequestReleaseTest.groovy index 304573c0317..909cad4fcce 100644 --- a/test/groovy/TransportRequestReleaseTest.groovy +++ b/test/groovy/TransportRequestReleaseTest.groovy @@ -4,6 +4,7 @@ import org.junit.Test import org.junit.rules.ExpectedException import org.junit.rules.RuleChain +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagement import com.sap.piper.cm.ChangeManagementException @@ -89,7 +90,8 @@ public class TransportRequestReleaseTest extends BasePiperTest { ChangeManagement cm = new ChangeManagement(nullScript) { - void releaseTransportRequest(String changeId, + void releaseTransportRequest(BackendType type, + String changeId, String transportRequestId, String endpoint, String credentialsId, @@ -111,12 +113,14 @@ public class TransportRequestReleaseTest extends BasePiperTest { Map receivedParams = [:] ChangeManagement cm = new ChangeManagement(nullScript) { - void releaseTransportRequest(String changeId, + void releaseTransportRequest(BackendType type, + String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts) { + receivedParams.type = type receivedParams.changeId = changeId receivedParams.transportRequestId = transportRequestId receivedParams.endpoint = endpoint @@ -127,7 +131,8 @@ public class TransportRequestReleaseTest extends BasePiperTest { jsr.step.call(script: nullScript, changeDocumentId: '001', transportRequestId: '002', cmUtils: cm) - assert receivedParams == [changeId: '001', + assert receivedParams == [type: BackendType.SOLMAN, + changeId: '001', transportRequestId: '002', endpoint: 'https://example.org/cm', credentialsId: 'CM', diff --git a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy index 9613f60b76d..d06bcaa2a0a 100644 --- a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy +++ b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy @@ -260,12 +260,32 @@ public void testGetCommandLineWithCMClientOpts() { } @Test - public void testReleaseTransportRequestSucceeds() { + public void testReleaseTransportRequestSucceedsSOLMAN() { // the regex provided below is an implicit check that the command line is fine. - script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'release-transport.*-cID 001.*-tID 002', 0) + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t SOLMAN release-transport.*-cID 001.*-tID 002', 0) - new ChangeManagement(nullScript).releaseTransportRequest('001', + new ChangeManagement(nullScript).releaseTransportRequest( + BackendType.SOLMAN, + '001', + '002', + 'https://example.org', + 'me', + 'openSesame') + + // no assert required here, since the regex registered above to the script rule is an implicit check for + // the command line. + } + + @Test + public void testReleaseTransportRequestSucceedsCTS() { + + // the regex provided below is an implicit check that the command line is fine. + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS release-transport.*-tID 002', 0) + + new ChangeManagement(nullScript).releaseTransportRequest( + BackendType.CTS, + null, '002', 'https://example.org', 'me', @@ -284,7 +304,9 @@ public void testGetCommandLineWithCMClientOpts() { // the regex provided below is an implicit check that the command line is fine. script.setReturnValue(JenkinsShellCallRule.Type.REGEX, 'release-transport.*-cID 001.*-tID 002', 1) - new ChangeManagement(nullScript).releaseTransportRequest('001', + new ChangeManagement(nullScript).releaseTransportRequest( + BackendType.SOLMAN, + '001', '002', 'https://example.org', 'me', diff --git a/vars/transportRequestRelease.groovy b/vars/transportRequestRelease.groovy index e5ecbcd9fab..594c9a17945 100644 --- a/vars/transportRequestRelease.groovy +++ b/vars/transportRequestRelease.groovy @@ -4,6 +4,7 @@ import groovy.transform.Field import com.sap.piper.ConfigurationHelper import com.sap.piper.ConfigurationMerger +import com.sap.piper.cm.BackendType import com.sap.piper.cm.ChangeManagement import com.sap.piper.cm.ChangeManagementException @@ -112,7 +113,8 @@ def call(parameters = [:]) { echo "[INFO] Closing transport request '${configuration.transportRequestId}' for change document '${configuration.changeDocumentId}'." try { - cm.releaseTransportRequest(configuration.changeDocumentId, + cm.releaseTransportRequest(BackendType.SOLMAN, + configuration.changeDocumentId, configuration.transportRequestId, configuration.changeManagement.endpoint, configuration.changeManagement.credentialsId, From 56d150932f1fcb9dcba2d3511397658d55655902 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Tue, 25 Sep 2018 11:12:04 +0200 Subject: [PATCH 11/12] release transport CTS support --- src/com/sap/piper/cm/ChangeManagement.groovy | 8 ++- .../sap/piper/cm/ChangeManagementTest.groovy | 2 +- vars/transportRequestRelease.groovy | 64 ++++++++++++------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/com/sap/piper/cm/ChangeManagement.groovy b/src/com/sap/piper/cm/ChangeManagement.groovy index e6aadcf4950..23542be5b69 100644 --- a/src/com/sap/piper/cm/ChangeManagement.groovy +++ b/src/com/sap/piper/cm/ChangeManagement.groovy @@ -158,17 +158,23 @@ public class ChangeManagement implements Serializable { void releaseTransportRequest(BackendType type,String changeId, String transportRequestId, String endpoint, String credentialsId, String clientOpts = '') { + def cmd List args = [] if(type == BackendType.SOLMAN) { + cmd = 'release-transport' args << '-cID' args << changeId + } else if(type == BackendType.CTS) { + cmd = 'export-transport' + } else { + throw new IllegalStateException("Invalid backend type: '${type}'") } args << '-tID' args << transportRequestId - int rc = executeWithCredentials(type, endpoint, credentialsId, 'release-transport', args, false, clientOpts) as int + int rc = executeWithCredentials(type, endpoint, credentialsId, cmd, args, false, clientOpts) as int if(rc == 0) { return } else { diff --git a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy index d06bcaa2a0a..cf32ab220e6 100644 --- a/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy +++ b/test/groovy/com/sap/piper/cm/ChangeManagementTest.groovy @@ -281,7 +281,7 @@ public void testGetCommandLineWithCMClientOpts() { public void testReleaseTransportRequestSucceedsCTS() { // the regex provided below is an implicit check that the command line is fine. - script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS release-transport.*-tID 002', 0) + script.setReturnValue(JenkinsShellCallRule.Type.REGEX, '-t CTS export-transport.*-tID 002', 0) new ChangeManagement(nullScript).releaseTransportRequest( BackendType.CTS, diff --git a/vars/transportRequestRelease.groovy b/vars/transportRequestRelease.groovy index 594c9a17945..93664b3c969 100644 --- a/vars/transportRequestRelease.groovy +++ b/vars/transportRequestRelease.groovy @@ -49,6 +49,16 @@ def call(parameters = [:]) { new Utils().pushToSWA([step: STEP_NAME], configuration) + BackendType backendType + + try { + backendType = configuration.changeManagement.type as BackendType + } catch(IllegalArgumentException e) { + error "Invalid backend type: '${configuration.changeManagement.type}'. " + + "Valid values: [${BackendType.values().join(', ')}]. " + + "Configuration: 'changeManagement/type'." + } + def transportRequestId = configuration.transportRequestId if(transportRequestId?.trim()) { @@ -75,45 +85,55 @@ def call(parameters = [:]) { } } - def changeDocumentId = configuration.changeDocumentId + def changeDocumentId = null - if(changeDocumentId?.trim()) { + if(backendType == BackendType.SOLMAN) { - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." + changeDocumentId = configuration.changeDocumentId - } else { + if(changeDocumentId?.trim()) { - echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + - "Searching for pattern '${configuration.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from parameters." - try { - changeDocumentId = cm.getChangeDocumentId( - configuration.changeManagement.git.from, - configuration.changeManagement.git.to, - configuration.changeManagement.changeDocumentLabel, - configuration.changeManagement.gitformat - ) + } else { - echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" + echo "[INFO] Retrieving ChangeDocumentId from commit history [from: ${configuration.changeManagement.git.from}, to: ${configuration.changeManagement.git.to}]." + + "Searching for pattern '${configuration.changeDocumentLabel}'. Searching with format '${configuration.changeManagement.git.format}'." - } catch(ChangeManagementException ex) { - echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + try { + changeDocumentId = cm.getChangeDocumentId( + configuration.changeManagement.git.from, + configuration.changeManagement.git.to, + configuration.changeManagement.changeDocumentLabel, + configuration.changeManagement.gitformat + ) + + echo "[INFO] ChangeDocumentId '${changeDocumentId}' retrieved from commit history" + + } catch(ChangeManagementException ex) { + echo "[WARN] Cannot retrieve changeDocumentId from commit history: ${ex.getMessage()}." + } } + + configHelper.mixin([changeDocumentId: changeDocumentId?.trim() ?: null], ['changeDocumentId'] as Set) + .withMandatoryProperty('changeDocumentId', + "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") + } configuration = configHelper - .mixin([transportRequestId: transportRequestId?.trim() ?: null, - changeDocumentId: changeDocumentId?.trim() ?: null], ['transportRequestId', 'changeDocumentId'] as Set) + .mixin([transportRequestId: transportRequestId?.trim() ?: null], ['transportRequestId'] as Set) .withMandatoryProperty('transportRequestId', "Transport request id not provided (parameter: \'transportRequestId\' or via commit history).") - .withMandatoryProperty('changeDocumentId', - "Change document id not provided (parameter: \'changeDocumentId\' or via commit history).") .use() - echo "[INFO] Closing transport request '${configuration.transportRequestId}' for change document '${configuration.changeDocumentId}'." + def closingMessage = ["[INFO] Closing transport request '${configuration.transportRequestId}'"] + if(backendType == BackendType.SOLMAN) closingMessage << " for change document '${configuration.changeDocumentId}'" + closingMessage << '.' + echo closingMessage.join() try { - cm.releaseTransportRequest(BackendType.SOLMAN, + cm.releaseTransportRequest(backendType, configuration.changeDocumentId, configuration.transportRequestId, configuration.changeManagement.endpoint, From 87aafb3cde83f87d2a703c662fe4f2465ace7953 Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Fri, 28 Sep 2018 10:00:59 +0200 Subject: [PATCH 12/12] Adjust docu transport request create for CTS use case --- .../docs/steps/transportRequestCreate.md | 36 ++++++++++++--- .../docs/steps/transportRequestRelease.md | 30 +++++++++---- .../docs/steps/transportRequestUploadFile.md | 44 ++++++++++++------- 3 files changed, 80 insertions(+), 30 deletions(-) diff --git a/documentation/docs/steps/transportRequestCreate.md b/documentation/docs/steps/transportRequestCreate.md index c3bd341ca21..d5ee2404207 100644 --- a/documentation/docs/steps/transportRequestCreate.md +++ b/documentation/docs/steps/transportRequestCreate.md @@ -1,7 +1,10 @@ # transportRequestCreate ## Description -Creates a Transport Request for a Change Document on the Solution Manager. +Creates + +* a Transport Request for a Change Document on the Solution Manager (type `SOLMAN`) or +* a Transport Request inside an ABAP system (type`CTS`) ## Prerequisites * **[Change Management Client 2.0.0 or compatible version](http://central.maven.org/maven2/com/sap/devops/cmclient/dist.cli/)** - available for download on Maven Central. @@ -10,7 +13,10 @@ Creates a Transport Request for a Change Document on the Solution Manager. | parameter | mandatory | default | possible values | | -----------------|-----------|--------------------------------------------------------|--------------------| | `script` | yes | | | -| `changeDocumentId` | yes | | | +| `changeDocumentId` | for `SOLMAN` | | | +| `transportType` | for `CTS` | no | | +| `targetSystem` | for `CTS` | no | | +| `description` | for `CTS` | no | | | `changeManagement/credentialsId` | yes | | | | `changeManagement/endpoint` | yes | | | | `changeManagement/clientOpts` | no | | | @@ -18,16 +24,21 @@ Creates a Transport Request for a Change Document on the Solution Manager. | `changeManagement/git/to` | no | `HEAD` | | | `changeManagement/changeDocumentLabel` | no | `ChangeDocument\s?:` | regex pattern | | `changeManagement/git/format` | no | `%b` | see `git log --help` | +| `changeManagement/type` | no | `SOLMAN` | `SOLMAN`, `CTS` | * `script` - The common script environment of the Jenkinsfile running. Typically the reference to the script calling the pipeline step is provided with the `this` parameter, as in `script: this`. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for retrieving, for example, configuration parameters. -* `changeDocumentId` - The id of the change document to transport. -* `changeManagement/credentialsId` - The credentials to connect to the Solution Manager. -* `changeManagement/endpoint` - The address of the Solution Manager. +* `changeDocumentId` - for `SOLMAN` only. The id of the change document to that the transport request is bound to. Typically this value is provided via commit message in the commit history. +* `changeManagement/type` Where/how the transport request is created (via SAP Solution Manager, ABAP). +* `changeManagement/credentialsId` - The credentials to connect to the service endpoint (Solution Manager, ABAP System). +* `changeManagement/endpoint` - The service endpoint (Solution Manager, ABAP System). * `changeManagement/clientOpts`- Options forwarded to JVM used by the CM client, like `JAVA_OPTS` * `changeManagement/git/from` - The starting point for retrieving the change document id * `changeManagement/git/to` - The end point for retrieving the change document id -* `changeManagement/changeDocumentLabel` - A pattern used for identifying lines holding the change document id. +* `changeManagement/changeDocumentLabel` - For type `SOLMAN` only. A pattern used for identifying lines holding the change document id. * `changeManagement/git/format` - Specifies what part of the commit is scanned. By default the body of the commit message is scanned. +* `description` - for `CTS` only. The description of the transport request. +* `targetSystem` - for `CTS` only. The system receiving the transport request. +* `transportType` - for type `CTS` only. Typically `W` (workbench) or `C` customizing. ## Step configuration The step is configured using a customer configuration file provided as @@ -55,6 +66,7 @@ general: changeDocumentLabel: 'ChangeDocument\s?:' cmClientOpts: '-Djavax.net.ssl.trustStore=' credentialsId: 'CM' + type: 'SOLMAN' endpoint: 'https://example.org/cm' git: from: 'HEAD~1' @@ -72,6 +84,7 @@ The properties can also be configured on a per-step basis: steps: transportRequestCreate: changeManagement: + type: 'SOLMAN' endpoint: 'https://example.org/cm' [...] ``` @@ -89,9 +102,20 @@ The id of the Transport Request that has been created. ## Example ```groovy +// SOLMAN def transportRequestId = transportRequestCreate script:this, changeDocumentId: '001,' changeManagement: [ + type: 'SOLMAN' + endpoint: 'https://example.org/cm' + ] +// CTS +def transportRequestId = transportRequestCreate script:this, + transportType: 'W', + targetSystem: 'XYZ', + description: 'the description', + changeManagement: [ + type: 'CTS' endpoint: 'https://example.org/cm' ] ``` diff --git a/documentation/docs/steps/transportRequestRelease.md b/documentation/docs/steps/transportRequestRelease.md index 1ea0a7d79ee..e4baeda2472 100644 --- a/documentation/docs/steps/transportRequestRelease.md +++ b/documentation/docs/steps/transportRequestRelease.md @@ -1,7 +1,7 @@ # transportRequestRelease ## Description -Releases a Transport Request for a Change Document on the Solution Manager. +Releases a Transport Request. ## Prerequisites * **[Change Management Client 2.0.0 or compatible version](http://central.maven.org/maven2/com/sap/devops/cmclient/dist.cli/)** - available for download on Maven Central. @@ -10,7 +10,7 @@ Releases a Transport Request for a Change Document on the Solution Manager. | parameter | mandatory | default | possible values | | -----------------|-----------|--------------------------------------------------------|--------------------| | `script` | yes | | | -| `changeDocumentId` | yes | | | +| `changeDocumentId` | `SOLMAN` only | | | | `transportRequestId`| yes | | | | `changeManagement/changeDocumentLabel` | no | `ChangeDocument\s?:` | regex pattern | | `changeManagment/transportRequestLabel` | no | `TransportRequest\s?:` | regex pattern | @@ -19,16 +19,17 @@ Releases a Transport Request for a Change Document on the Solution Manager. | `changeManagement/git/from` | no | `origin/master` | | | `changeManagement/git/to` | no | `HEAD` | | | `changeManagement/git/format` | no | `%b` | see `git log --help` | +| `changeManagement/type` | no | `SOLMAN` | `SOLMAN`, `CTS` | * `script` - The common script environment of the Jenkinsfile running. Typically the reference to the script calling the pipeline step is provided with the `this` parameter, as in `script: this`. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for retrieving, for example, configuration parameters. -* `changeDocumentId` - The id of the change document related to the transport request to release. +* `changeDocumentId` - for `SOLMAN` only. The id of the change document related to the transport request to release. * `transportRequestId` - The id of the transport request to release. -* `changeManagement/changeDocumentLabel` - A pattern used for identifying lines holding the change document id. +* `changeManagement/changeDocumentLabel` - for `SOLMAN` only. A pattern used for identifying lines holding the change document id. * `changeManagment/transportRequestLabel` - A pattern used for identifying lines holding the transport request id. -* `changeManagement/credentialsId` - The id of the credentials to connect to the Solution Manager. The credentials needs to be maintained on Jenkins. -* `changeManagement/endpoint` - The address of the Solution Manager. -* `changeManagement/git/from` - The starting point for retrieving the change document id -* `changeManagement/git/to` - The end point for retrieving the change document id +* `changeManagement/credentialsId` - The credentials to connect to the service endpoint (Solution Manager, ABAP System). +* `changeManagement/endpoint` - The service endpoint (Solution Manager, ABAP System). +* `changeManagement/git/from` - The starting point for retrieving the change document id and/or transport request id +* `changeManagement/git/to` - The end point for retrieving the change document id and/or transport request id * `changeManagement/git/format` - Specifies what part of the commit is scanned. By default the body of the commit message is scanned. ## Step configuration @@ -57,6 +58,7 @@ general: changeDocumentLabel: 'ChangeDocument\s?:' cmClientOpts: '-Djavax.net.ssl.trustStore=' credentialsId: 'CM' + type: 'SOLMAN' endpoint: 'https://example.org/cm' git: from: 'HEAD~1' @@ -73,6 +75,7 @@ The properties can also be configured on a per-step basis: steps: transportRequestRelease: changeManagement: + type: 'SOLMAN' endpoint: 'https://example.org/cm' [...] ``` @@ -84,17 +87,26 @@ None. ## Exceptions * `IllegalArgumentException`: - * If the change id is not provided. + * If the change id is not provided (`SOLMAN` only) * If the transport request id is not provided. * `AbortException`: * If the release of the transport request fails. ## Example ```groovy +// SOLMAN transportRequestRelease script:this, changeDocumentId: '001', transportRequestId: '001', changeManagement: [ + type: 'SOLMAN' + endpoint: 'https://example.org/cm' + ] +// CTS +transportRequestRelease script:this, + transportRequestId: '001', + changeManagement: [ + type: 'CTS' endpoint: 'https://example.org/cm' ] ``` diff --git a/documentation/docs/steps/transportRequestUploadFile.md b/documentation/docs/steps/transportRequestUploadFile.md index 35fa11a4500..e4a9da916c7 100644 --- a/documentation/docs/steps/transportRequestUploadFile.md +++ b/documentation/docs/steps/transportRequestUploadFile.md @@ -1,7 +1,7 @@ # transportRequestUploadFile ## Description -Uploads a file to a Transport Request for a Change Document on the Solution Manager. +Uploads a file to a Transport Request. ## Prerequisites * **[Change Management Client 2.0.0 or compatible version](http://central.maven.org/maven2/com/sap/devops/cmclient/dist.cli/)** - available for download on Maven Central. @@ -10,9 +10,9 @@ Uploads a file to a Transport Request for a Change Document on the Solution Mana | parameter | mandatory | default | possible values | | -----------------|-----------|--------------------------------------------------------|--------------------| | `script` | yes | | | -| `changeDocumentId` | yes | | | +| `changeDocumentId` | `SOLMAN` only | | | | `transportRequestId`| yes | | | -| `applicationId` | yes | | | +| `applicationId` | `SOLMAN` only | | | | `filePath` | yes | | | | `changeManagement/credentialsId` | yes | | | | `changeManagement/endpoint` | yes | | | @@ -21,18 +21,20 @@ Uploads a file to a Transport Request for a Change Document on the Solution Mana | `changeManagement/changeDocumentLabel` | no | `ChangeDocument\s?:` | regex pattern | | `changeManagement/transportRequestLabel` | no | `TransportRequest\s?:` | regex pattern | | `changeManagement/git/format` | no | `%b` | see `git log --help` | +| `changeManagement/type` | no | `SOLMAN` | `SOLMAN`, `CTS` | * `script` - The common script environment of the Jenkinsfile running. Typically the reference to the script calling the pipeline step is provided with the `this` parameter, as in `script: this`. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for retrieving, for example, configuration parameters. -* `changeDocumentId` - The id of the change document related to the transport request to release. -* `transportRequestId` - The id of the transport request to release. -* `applicationId` - The id of the application. +* `changeDocumentId` - For type `SOLMAN` only. The id of the change document related to the transport request to release. Typically provided via commit history. +* `transportRequestId` - The id of the transport request to release. Typically provided via commit history. +* `applicationId` - For type `SOLMAN` only. The id of the application. * `filePath` - The path of the file to upload. -* `changeManagement/credentialsId` - The credentials to connect to the Solution Manager. -* `changeManagement/endpoint` - The address of the Solution Manager. -* `changeManagement/git/from` - The starting point for retrieving the change document id -* `changeManagement/git/to` - The end point for retrieving the change document id -* `changeManagement/changeDocumentLabel` - A pattern used for identifying lines holding the change document id. +* `changeManagement/credentialsId` - The credentials to connect to the service endpoint (Solution Manager, ABAP System). +* `changeManagement/endpoint` - The service endpoint (Solution Manager, ABAP System). +* `changeManagement/git/from` - The starting point for retrieving the change document id and/or transport request id +* `changeManagement/git/to` - The end point for retrieving the change document id and/or transport request id +* `changeManagement/changeDocumentLabel` - For type `SOLMAN` only. A pattern used for identifying lines holding the change document id. * `changeManagement/transportRequestLabel` - A pattern used for identifying lines holding the transport request id. +* `changeManagement/type` Where/how the transport request is created (via SAP Solution Manager, ABAP). * `changeManagement/git/format` - Specifies what part of the commit is scanned. By default the body of the commit message is scanned. ## Step configuration @@ -61,6 +63,7 @@ general: changeDocumentLabel: 'ChangeDocument\s?:' cmClientOpts: '-Djavax.net.ssl.trustStore=' credentialsId: 'CM' + type: 'SOLMAN' endpoint: 'https://example.org/cm' git: from: 'HEAD~1' @@ -78,6 +81,7 @@ The properties can also be configured on a per-step basis: transportRequestUploadFile: applicationId: 'FOO' changeManagement: + type: 'SOLMAN' endpoint: 'https://example.org/cm' [...] ``` @@ -89,21 +93,31 @@ None. ## Exceptions * `IllegalArgumentException`: - * If the change id is not provided. + * If the change id is not provided (`SOLMAN` only). * If the transport request id is not provided. - * If the application id is not provided. + * If the application id is not provided (`SOLMAN` only). * If the file path is not provided. * `AbortException`: * If the upload fails. ## Example ```groovy +// SOLMAN transportRequestUploadFile script:this, - changeDocumentId: '001', - transportRequestId: '001', + changeDocumentId: '001', // typically provided via git commit history + transportRequestId: '001', // typically provided via git commit history applicationId: '001', filePath: '/path', changeManagement:[ + type: 'SOLMAN' + endpoint: 'https://example.org/cm' + ] +// CTS +transportRequestUploadFile script:this, + transportRequestId: '001', // typically provided via git commit history + filePath: '/path', + changeManagement:[ + type: 'CTS' endpoint: 'https://example.org/cm' ] ```