mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
Merge remote-tracking branch 'mholl/pr/cts' into HEAD
This commit is contained in:
commit
776cfdf50b
@ -6,13 +6,13 @@ sudo: required
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- docker pull squidfunk/mkdocs-material
|
||||
- docker pull squidfunk/mkdocs-material:3.0.4
|
||||
script:
|
||||
- mvn clean test --batch-mode
|
||||
- |
|
||||
if [[ "${TRAVIS_PULL_REQUEST}" != "false" ]]
|
||||
then
|
||||
docker run --rm -it -v ${TRAVIS_BUILD_DIR}:/docs -w /docs/documentation squidfunk/mkdocs-material build --clean --verbose --strict
|
||||
docker run --rm -it -v ${TRAVIS_BUILD_DIR}:/docs -w /docs/documentation squidfunk/mkdocs-material:3.0.4 build --clean --verbose --strict
|
||||
else
|
||||
# Only in case we are in master branch of the leading SAP repo we would like to deploy,
|
||||
# not from the forks.
|
||||
@ -22,7 +22,7 @@ script:
|
||||
PRIVATE_KEY="cfg/id_rsa"
|
||||
openssl aes-256-cbc -K $encrypted_12c8071d2874_key -iv $encrypted_12c8071d2874_iv -in cfg/id_rsa.enc -out "${PRIVATE_KEY}" -d
|
||||
chmod a+x gh-pages-deploy.sh
|
||||
docker run --rm -it --entrypoint "./gh-pages-deploy.sh" -e "TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG}" -v ${TRAVIS_BUILD_DIR}:/docs -w /docs squidfunk/mkdocs-material
|
||||
docker run --rm -it --entrypoint "./gh-pages-deploy.sh" -e "TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG}" -v ${TRAVIS_BUILD_DIR}:/docs -w /docs squidfunk/mkdocs-material:3.0.4
|
||||
else
|
||||
echo "Publishing documentation skipped."
|
||||
fi
|
||||
|
@ -30,7 +30,7 @@ Proxy environment variables defined on the Jenkins machine are also available in
|
||||
* `containerPortMappings`: Map which defines per docker image the port mappings, like `containerPortMappings: ['selenium/standalone-chrome': [[name: 'selPort', containerPort: 4444, hostPort: 4444]]]`
|
||||
* `dockerEnvVars`: Environment variables to set in the container, e.g. [http_proxy:'proxy:8080']
|
||||
* `dockerImage`: Name of the docker image that should be used. If empty, Docker is not used and the command is executed directly on the Jenkins system.
|
||||
* `dockerName`: only relevant for Kubernetes case: Name of the container launching `dockerImage`
|
||||
* `dockerName`: Kubernetes case: Name of the container launching `dockerImage`, SideCar: Name of the container in local network
|
||||
* `dockerOptions` Docker options to be set when starting the container. It can be a list or a string.
|
||||
* `dockerVolumeBind` Volumes that should be mounted into the container.
|
||||
* `dockerWorkspace`: only relevant for Kubernetes case: specifies a dedicated user home directory for the container which will be passed as value for environment variable `HOME`
|
||||
|
@ -45,7 +45,7 @@ The following parameters can also be specified as step parameters using the glob
|
||||
* `applicationName`
|
||||
|
||||
## Return value
|
||||
The file name of the resulting archive is returned with this step. The file name is extracted from the key `ID` defined in `mta.yaml`.
|
||||
none
|
||||
|
||||
## Side effects
|
||||
1. The file name of the resulting archive is written to the `commonPipelineEnvironment` with variable name `mtarFileName`.
|
||||
|
16
pom.xml
16
pom.xml
@ -132,7 +132,6 @@
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
@ -140,8 +139,21 @@
|
||||
<version>1.12</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-test-source</id>
|
||||
<id>add-groovy-sources</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>src</source>
|
||||
<source>vars</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add-groovy-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
|
21
resources/com.sap.piper/templates/error.log
Normal file
21
resources/com.sap.piper/templates/error.log
Normal file
@ -0,0 +1,21 @@
|
||||
----------------------------------------------------------
|
||||
--- ERROR OCCURRED IN LIBRARY STEP: ${stepName}
|
||||
----------------------------------------------------------
|
||||
|
||||
FOLLOWING PARAMETERS WERE AVAILABLE TO THIS STEP:
|
||||
***
|
||||
${stepParameters}
|
||||
***
|
||||
|
||||
ERROR WAS:
|
||||
***
|
||||
${error}
|
||||
***
|
||||
|
||||
FURTHER INFORMATION:
|
||||
* Documentation of library step ${stepName}: https://sap.github.io/jenkins-library/steps/${stepName}/
|
||||
* Source code of library step ${stepName}: https://github.com/SAP/jenkins-library/blob/master/vars/${stepName}.groovy
|
||||
* Library documentation: https://sap.github.io/jenkins-library/
|
||||
* Library repository: https://github.com/SAP/jenkins-library
|
||||
|
||||
----------------------------------------------------------
|
@ -233,7 +233,6 @@ steps:
|
||||
'selenium/standalone-chrome':
|
||||
- containerPort: 4444
|
||||
hostPort: 4444
|
||||
dockerLinkAlias: 'selenium'
|
||||
failOnError: true
|
||||
sidecarImage: 'selenium/standalone-chrome'
|
||||
sidecarName: 'selenium'
|
||||
|
@ -44,6 +44,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
|
||||
ChangeManagement cm = getChangeManagementUtils(true)
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [
|
||||
type: 'SOLMAN',
|
||||
@ -68,6 +69,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
|
||||
ChangeManagement cm = getChangeManagementUtils(false)
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [type: 'SOLMAN',
|
||||
endpoint: 'https://example.org/cm'])
|
||||
@ -78,6 +80,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
|
||||
ChangeManagement cm = getChangeManagementUtils(false)
|
||||
boolean inDevelopment = jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [endpoint: 'https://example.org/cm'],
|
||||
failIfStatusIsNotInDevelopment: false)
|
||||
@ -89,6 +92,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
ChangeManagement cm = getChangeManagementUtils(true, '0815')
|
||||
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
changeDocumentId: '42',
|
||||
cmUtils: cm,
|
||||
changeManagement: [type: 'SOLMAN',
|
||||
@ -102,6 +106,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
ChangeManagement cm = getChangeManagementUtils(true, '0815')
|
||||
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement : [type: 'SOLMAN',
|
||||
endpoint: 'https://example.org/cm'])
|
||||
@ -128,6 +133,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
}
|
||||
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [type: 'SOLMAN',
|
||||
endpoint: 'https://example.org/cm'])
|
||||
@ -143,6 +149,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
|
||||
ChangeManagement cm = getChangeManagementUtils(false, null)
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [endpoint: 'https://example.org/cm',
|
||||
type: 'SOLMAN'])
|
||||
@ -158,6 +165,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
|
||||
ChangeManagement cm = getChangeManagementUtils(false, '')
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
cmUtils: cm,
|
||||
changeManagement: [type: 'SOLMAN',
|
||||
endpoint: 'https://example.org/cm'])
|
||||
@ -169,6 +177,7 @@ class CheckChangeInDevelopmentTest extends BasePiperTest {
|
||||
jlr.expect('[INFO] Change management integration intentionally switched off.')
|
||||
|
||||
jsr.step.checkChangeInDevelopment(
|
||||
script: nullScript,
|
||||
changeManagement: [type: 'NONE'])
|
||||
|
||||
}
|
||||
|
@ -115,17 +115,6 @@ class DockerExecuteTest extends BasePiperTest {
|
||||
assertTrue(bodyExecuted)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteInsideDockerNoScript() throws Exception {
|
||||
jsr.step.dockerExecute(dockerImage: 'maven:3.5-jdk-8-alpine') {
|
||||
bodyExecuted = true
|
||||
}
|
||||
assertEquals('maven:3.5-jdk-8-alpine', docker.getImageName())
|
||||
assertTrue(docker.isImagePulled())
|
||||
assertEquals('--env http_proxy --env https_proxy --env no_proxy --env HTTP_PROXY --env HTTPS_PROXY --env NO_PROXY', docker.getParameters().trim())
|
||||
assertTrue(bodyExecuted)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteInsideDockerContainerWithParameters() throws Exception {
|
||||
jsr.step.dockerExecute(script: nullScript,
|
||||
@ -172,6 +161,7 @@ class DockerExecuteTest extends BasePiperTest {
|
||||
void testSidecarDefault(){
|
||||
jsr.step.dockerExecute(
|
||||
script: nullScript,
|
||||
dockerName: 'maven',
|
||||
dockerImage: 'maven:3.5-jdk-8-alpine',
|
||||
sidecarEnvVars: ['testEnv':'testVal'],
|
||||
sidecarImage: 'selenium/standalone-chrome',
|
||||
@ -186,9 +176,14 @@ class DockerExecuteTest extends BasePiperTest {
|
||||
assertThat(docker.imagePullCount, is(2))
|
||||
assertThat(docker.sidecarParameters, allOf(
|
||||
containsString('--env testEnv=testVal'),
|
||||
containsString('--volume /dev/shm:/dev/shm')
|
||||
containsString('--volume /dev/shm:/dev/shm'),
|
||||
containsString('--network sidecar-'),
|
||||
containsString('--network-alias testAlias')
|
||||
))
|
||||
assertThat(docker.parameters, allOf(
|
||||
containsString('--network sidecar-'),
|
||||
containsString('--network-alias maven')
|
||||
))
|
||||
assertThat(docker.parameters, containsString('--link uniqueId:testAlias'))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -217,8 +212,7 @@ class DockerExecuteTest extends BasePiperTest {
|
||||
sidecarEnvVars: ['testEnv':'testVal'],
|
||||
sidecarImage: 'selenium/standalone-chrome',
|
||||
sidecarName: 'selenium',
|
||||
sidecarVolumeBind: ['/dev/shm':'/dev/shm'],
|
||||
dockerLinkAlias: 'testAlias',
|
||||
sidecarVolumeBind: ['/dev/shm':'/dev/shm']
|
||||
) {
|
||||
bodyExecuted = true
|
||||
}
|
||||
|
82
test/groovy/HandlePipelineStepErrorTest.groovy
Normal file
82
test/groovy/HandlePipelineStepErrorTest.groovy
Normal file
@ -0,0 +1,82 @@
|
||||
#!groovy
|
||||
import static org.hamcrest.Matchers.is
|
||||
import static org.hamcrest.Matchers.not
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsLoggingRule
|
||||
import util.JenkinsStepRule
|
||||
import util.Rules
|
||||
|
||||
class HandlePipelineStepErrorsTest extends BasePiperTest {
|
||||
private JenkinsStepRule jsr = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule jlr = new JenkinsLoggingRule(this)
|
||||
private ExpectedException thrown = ExpectedException.none()
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(jlr)
|
||||
.around(jsr)
|
||||
.around(thrown)
|
||||
|
||||
@Test
|
||||
void testBeginAndEndMessage() {
|
||||
def isExecuted
|
||||
jsr.step.handlePipelineStepErrors([
|
||||
stepName: 'testStep',
|
||||
stepParameters: ['something': 'anything']
|
||||
]) {
|
||||
isExecuted = true
|
||||
}
|
||||
// asserts
|
||||
assertThat(isExecuted, is(true))
|
||||
assertThat(jlr.log, containsString('--- BEGIN LIBRARY STEP: testStep'))
|
||||
assertThat(jlr.log, containsString('--- END LIBRARY STEP: testStep'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNonVerbose() {
|
||||
try {
|
||||
jsr.step.handlePipelineStepErrors([
|
||||
stepName: 'testStep',
|
||||
stepParameters: ['something': 'anything'],
|
||||
echoDetails: false
|
||||
]) {
|
||||
throw new Exception('TestError')
|
||||
}
|
||||
} catch (ignore) {
|
||||
} finally {
|
||||
// asserts
|
||||
assertThat(jlr.log, not(containsString('--- BEGIN LIBRARY STEP: testStep')))
|
||||
assertThat(jlr.log, not(containsString('--- END LIBRARY STEP: testStep')))
|
||||
assertThat(jlr.log, not(containsString('--- ERROR OCCURRED IN LIBRARY STEP: testStep')))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorsMessage() {
|
||||
def isReported
|
||||
try {
|
||||
jsr.step.handlePipelineStepErrors([
|
||||
stepName: 'testStep',
|
||||
stepParameters: ['something': 'anything']
|
||||
]) {
|
||||
throw new Exception('TestError')
|
||||
}
|
||||
} catch (ignore) {
|
||||
isReported = true
|
||||
} finally {
|
||||
// asserts
|
||||
assertThat(isReported, is(true))
|
||||
assertThat(jlr.log, containsString('--- ERROR OCCURRED IN LIBRARY STEP: testStep'))
|
||||
assertThat(jlr.log, containsString('[something:anything]'))
|
||||
}
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishNothingWithDefaultSettings() throws Exception {
|
||||
jsr.step.testsPublishResults()
|
||||
jsr.step.testsPublishResults(script: nullScript)
|
||||
|
||||
// ensure nothing is published
|
||||
assertTrue('WarningsPublisher options not empty', publisherStepOptions.junit == null)
|
||||
@ -59,7 +59,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishNothingWithAllDisabled() throws Exception {
|
||||
jsr.step.testsPublishResults(junit: false, jacoco: false, cobertura: false, jmeter: false)
|
||||
jsr.step.testsPublishResults(script: nullScript, junit: false, jacoco: false, cobertura: false, jmeter: false)
|
||||
|
||||
// ensure nothing is published
|
||||
assertTrue('WarningsPublisher options not empty', publisherStepOptions.junit == null)
|
||||
@ -70,7 +70,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishUnitTestsWithDefaultSettings() throws Exception {
|
||||
jsr.step.testsPublishResults(junit: true)
|
||||
jsr.step.testsPublishResults(script: nullScript, junit: true)
|
||||
|
||||
assertTrue('JUnit options are empty', publisherStepOptions.junit != null)
|
||||
// ensure default patterns are set
|
||||
@ -84,7 +84,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishCoverageWithDefaultSettings() throws Exception {
|
||||
jsr.step.testsPublishResults(jacoco: true, cobertura: true)
|
||||
jsr.step.testsPublishResults(script: nullScript, jacoco: true, cobertura: true)
|
||||
|
||||
assertTrue('JaCoCo options are empty', publisherStepOptions.jacoco != null)
|
||||
assertTrue('Cobertura options are empty', publisherStepOptions.cobertura != null)
|
||||
@ -99,7 +99,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishJMeterWithDefaultSettings() throws Exception {
|
||||
jsr.step.testsPublishResults(jmeter: true)
|
||||
jsr.step.testsPublishResults(script: nullScript, jmeter: true)
|
||||
|
||||
assertTrue('JMeter options are empty', publisherStepOptions.jmeter != null)
|
||||
assertEquals('JMeter default pattern not set',
|
||||
@ -113,7 +113,7 @@ class TestsPublishResultsTest extends BasePiperTest {
|
||||
|
||||
@Test
|
||||
void testPublishUnitTestsWithCustomSettings() throws Exception {
|
||||
jsr.step.testsPublishResults(junit: [pattern: 'fancy/file/path', archive: true, active: true])
|
||||
jsr.step.testsPublishResults(script: nullScript, junit: [pattern: 'fancy/file/path', archive: true, active: true])
|
||||
|
||||
assertTrue('JUnit options are empty', publisherStepOptions.junit != null)
|
||||
// ensure default patterns are set
|
||||
|
@ -17,9 +17,9 @@ import groovy.transform.Field
|
||||
'dockerOptions',
|
||||
'dockerWorkspace',
|
||||
'dockerVolumeBind',
|
||||
'sidecarName',
|
||||
'sidecarEnvVars',
|
||||
'sidecarImage',
|
||||
'sidecarName',
|
||||
'sidecarOptions',
|
||||
'sidecarWorkspace',
|
||||
'sidecarVolumeBind'
|
||||
@ -111,15 +111,27 @@ void call(Map parameters = [:], body) {
|
||||
body()
|
||||
}
|
||||
} else {
|
||||
def sidecarImage = docker.image(config.sidecarImage)
|
||||
sidecarImage.pull()
|
||||
sidecarImage.withRun(getDockerOptions(config.sidecarEnvVars, config.sidecarVolumeBind, config.sidecarOptions)) { c ->
|
||||
config.dockerOptions = config.dockerOptions?:[]
|
||||
config.dockerOptions.add("--link ${c.id}:${config.sidecarName}")
|
||||
image.inside(getDockerOptions(config.dockerEnvVars, config.dockerVolumeBind, config.dockerOptions)) {
|
||||
echo "[INFO][${STEP_NAME}] Running with sidecar container."
|
||||
body()
|
||||
def networkName = "sidecar-${UUID.randomUUID()}"
|
||||
sh "docker network create ${networkName}"
|
||||
try{
|
||||
def sidecarImage = docker.image(config.sidecarImage)
|
||||
sidecarImage.pull()
|
||||
config.sidecarOptions = config.sidecarOptions?:[]
|
||||
if(config.sidecarName)
|
||||
config.sidecarOptions.add("--network-alias ${config.sidecarName}")
|
||||
config.sidecarOptions.add("--network ${networkName}")
|
||||
sidecarImage.withRun(getDockerOptions(config.sidecarEnvVars, config.sidecarVolumeBind, config.sidecarOptions)) { c ->
|
||||
config.dockerOptions = config.dockerOptions?:[]
|
||||
if(config.dockerName)
|
||||
config.dockerOptions.add("--network-alias ${config.dockerName}")
|
||||
config.dockerOptions.add("--network ${networkName}")
|
||||
image.inside(getDockerOptions(config.dockerEnvVars, config.dockerVolumeBind, config.dockerOptions)) {
|
||||
echo "[INFO][${STEP_NAME}] Running with sidecar container."
|
||||
body()
|
||||
}
|
||||
}
|
||||
}finally{
|
||||
sh "docker network remove ${networkName}"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1,50 +1,34 @@
|
||||
import groovy.text.SimpleTemplateEngine
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field STEP_NAME = 'handlePipelineStepErrors'
|
||||
|
||||
|
||||
void call(Map parameters = [:], body) {
|
||||
|
||||
def stepParameters = parameters.stepParameters //mandatory
|
||||
def stepName = parameters.stepName //mandatory
|
||||
def echoDetails = parameters.get('echoDetails', true)
|
||||
|
||||
def verbose = parameters.get('echoDetails', true)
|
||||
def message = ''
|
||||
try {
|
||||
|
||||
if (stepParameters == null && stepName == null)
|
||||
error "step handlePipelineStepErrors requires following mandatory parameters: stepParameters, stepName"
|
||||
|
||||
if (echoDetails)
|
||||
echo "--- BEGIN LIBRARY STEP: ${stepName}.groovy ---"
|
||||
if (verbose)
|
||||
echo "--- BEGIN LIBRARY STEP: ${stepName} ---"
|
||||
|
||||
body()
|
||||
|
||||
} catch (Throwable err) {
|
||||
if (echoDetails)
|
||||
echo """----------------------------------------------------------
|
||||
--- ERROR OCCURRED IN LIBRARY STEP: ${stepName}
|
||||
----------------------------------------------------------
|
||||
|
||||
FOLLOWING PARAMETERS WERE AVAILABLE TO THIS STEP:
|
||||
***
|
||||
${stepParameters?.toString()}
|
||||
***
|
||||
|
||||
ERROR WAS:
|
||||
***
|
||||
${err}
|
||||
***
|
||||
|
||||
FURTHER INFORMATION:
|
||||
* Documentation of library step ${stepName}: https://sap.github.io/jenkins-library/steps/${stepName}/
|
||||
* Source code of library step ${stepName}: https://github.com/SAP/jenkins-library/blob/master/vars/${stepName}.groovy
|
||||
* Library documentation: https://sap.github.io/jenkins-library/
|
||||
* Library repository: https://github.com/SAP/jenkins-library
|
||||
|
||||
----------------------------------------------------------"""
|
||||
if (verbose)
|
||||
message += SimpleTemplateEngine.newInstance()
|
||||
.createTemplate(libraryResource('com.sap.piper/templates/error.log'))
|
||||
.make([
|
||||
stepName: stepName,
|
||||
stepParameters: stepParameters?.toString(),
|
||||
error: err
|
||||
]).toString()
|
||||
throw err
|
||||
} finally {
|
||||
if (echoDetails)
|
||||
echo "--- END LIBRARY STEP: ${stepName}.groovy ---"
|
||||
if (verbose)
|
||||
message += "--- END LIBRARY STEP: ${stepName} ---"
|
||||
echo message
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user