diff --git a/documentation/docs/steps/artifactSetVersion.md b/documentation/docs/steps/artifactSetVersion.md index 95f8c9520..18a1e9c27 100644 --- a/documentation/docs/steps/artifactSetVersion.md +++ b/documentation/docs/steps/artifactSetVersion.md @@ -23,19 +23,19 @@ none | ----------|-----------|---------|-----------------| | script | no | empty `commonPipelineEnvironment` | | | artifactType | no | | 'appContainer' | -| buildTool | no | maven | maven, docker | +| buildTool | no | maven | docker, dlang, golang, maven, mta, npm, pip, sbt | | commitVersion | no | `true` | `true`, `false` | | dockerVersionSource | no | `''` | FROM, (ENV name),appVersion | -| filePath | no | buildTool=`maven`: pom.xml
docker: Dockerfile | | +| filePath | no | buildTool=`docker`: Dockerfile
buildTool=`dlang`: dub.json
buildTool=`golang`: VERSION
buildTool=`maven`: pom.xml
buildTool=`mta`: mta.yaml
buildTool=`npm`: package.json
buildTool=`pip`: version.txt
buildTool=`sbt`: sbtDescriptor.json| | | gitCommitId | no | `GitUtils.getGitCommitId()` | | -| gitCredentialsId | If `commitVersion` is `true` | as defined in custom configuration | | +| gitSshCredentialsId | If `commitVersion` is `true` | as defined in custom configuration | | | gitUserEMail | no | | | | gitUserName | no | | | | gitSshUrl | If `commitVersion` is `true` | | | | tagPrefix | no | 'build_' | | | timestamp | no | current time in format according to `timestampTemplate` | | | timestampTemplate | no | `%Y%m%d%H%M%S` | | -| versioningTemplate | no | depending on `buildTool`
maven: `${version}-${timestamp}${commitId?"_"+commitId:""}` | | +| versioningTemplate | no |buildTool=`docker`: `${version}-${timestamp}${commitId?"_"+commitId:""}`
/>buildTool=`dlang`: `${version}-${timestamp}${commitId?"+"+commitId:""}`
buildTool=`golang`:`${version}-${timestamp}${commitId?"+"+commitId:""}`
buildTool=`maven`: `${version}-${timestamp}${commitId?"_"+commitId:""}`
buildTool=`mta`: `${version}-${timestamp}${commitId?"+"+commitId:""}`
buildTool=`npm`: `${version}-${timestamp}${commitId?"+"+commitId:""}`
buildTool=`pip`: `${version}.${timestamp}${commitId?"."+commitId:""}`
buildTool=`sbt`: `${version}-${timestamp}${commitId?"+"+commitId:""}`| | * `script` defines the global script environment of the Jenkinsfile run. Typically `this` is passed to this parameter. This allows the function to access the [`commonPipelineEnvironment`](commonPipelineEnvironment.md) for retrieving e.g. configuration parameters. * `artifactType` defines the type of the artifact. @@ -49,7 +49,7 @@ none * Using `filePath` you could define a custom path to the descriptor file. * `gitCommitId` defines the version prefix of the automatically generated version. By default it will take the long commitId hash. You could pass any other string (e.g. the short commitId hash) to be used. In case you don't want to have the gitCommitId added to the automatic versioning string you could set the value to an empty string: `''`. -* `gitCredentialsId`defines the ssh git credentials to be used for writing the tag. +* `gitSshCredentialsId`defines the ssh git credentials to be used for writing the tag. * The parameters `gitUserName` and `gitUserEMail` allow to overwrite the global git settings available on your Jenkins server * `gitSshUrl` defines the git ssh url to the source code repository. * `tagPrefix` defines the prefix wich is used for the git tag which is written during the versioning run. diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index a0c9101d7..39eb1de79 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -11,21 +11,37 @@ general: from: 'origin/master' to: 'HEAD' format: '%b' + gitSshKeyCredentialsId: '' #needed to allow sshagent to run with local ssh key #Steps Specific Configuration steps: artifactSetVersion: timestampTemplate: '%Y%m%d%H%M%S' tagPrefix: 'build_' commitVersion: true + dlang: + filePath: 'dub.json' + versioningTemplate: '${version}-${timestamp}${commitId?"+"+commitId:""}' docker: filePath: 'Dockerfile' versioningTemplate: '${version}-${timestamp}${commitId?"_"+commitId:""}' + golang: + filePath: 'VERSION' + versioningTemplate: '${version}-${timestamp}${commitId?"+"+commitId:""}' maven: filePath: 'pom.xml' versioningTemplate: '${version}-${timestamp}${commitId?"_"+commitId:""}' mta: filePath: 'mta.yaml' versioningTemplate: '${version}-${timestamp}${commitId?"+"+commitId:""}' + npm: + filePath: 'package.json' + versioningTemplate: '${version}-${timestamp}${commitId?"+"+commitId:""}' + pip: + filePath: 'version.txt' + versioningTemplate: '${version}.${timestamp}${commitId?"."+commitId:""}' + sbt: + filePath: 'sbtDescriptor.json' + versioningTemplate: '${version}-${timestamp}${commitId?"+"+commitId:""}' checksPublishResults: aggregation: active: true diff --git a/src/com/sap/piper/versioning/ArtifactVersioning.groovy b/src/com/sap/piper/versioning/ArtifactVersioning.groovy index 7cdfa744b..91168430e 100644 --- a/src/com/sap/piper/versioning/ArtifactVersioning.groovy +++ b/src/com/sap/piper/versioning/ArtifactVersioning.groovy @@ -12,12 +12,22 @@ abstract class ArtifactVersioning implements Serializable { public static getArtifactVersioning(buildTool, script, configuration) { switch (buildTool) { - case 'mta': - return new MtaArtifactVersioning(script, configuration) - case 'maven': - return new MavenArtifactVersioning(script, configuration) + case 'dlang': + return new DlangArtifactVersioning(script, configuration) case 'docker': return new DockerArtifactVersioning(script, configuration) + case 'golang': + return new GolangArtifactVersioning(script, configuration) + case 'maven': + return new MavenArtifactVersioning(script, configuration) + case 'mta': + return new MtaArtifactVersioning(script, configuration) + case 'npm': + return new NpmArtifactVersioning(script, configuration) + case 'pip': + return new PipArtifactVersioning(script, configuration) + case 'sbt': + return new SbtArtifactVersioning(script, configuration) default: throw new IllegalArgumentException("No versioning implementation for buildTool: ${buildTool} available.") } diff --git a/src/com/sap/piper/versioning/DlangArtifactVersioning.groovy b/src/com/sap/piper/versioning/DlangArtifactVersioning.groovy new file mode 100644 index 000000000..f8ff5da41 --- /dev/null +++ b/src/com/sap/piper/versioning/DlangArtifactVersioning.groovy @@ -0,0 +1,20 @@ +package com.sap.piper.versioning + +class DlangArtifactVersioning extends ArtifactVersioning { + protected DlangArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + def descriptor = script.readJSON file: configuration.filePath + return descriptor.version + } + + @Override + def setVersion(version) { + def descriptor = script.readJSON file: configuration.filePath + descriptor.version = new String(version) + script.writeJSON file: configuration.filePath, json: descriptor + } +} diff --git a/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy b/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy index 65cd4eabf..80faf20f1 100644 --- a/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy +++ b/src/com/sap/piper/versioning/DockerArtifactVersioning.groovy @@ -5,13 +5,29 @@ class DockerArtifactVersioning extends ArtifactVersioning { super(script, configuration) } - @Override def getVersion() { - if (configuration.dockerVersionSource == 'FROM') - return getVersionFromDockerBaseImageTag(configuration.filePath) - else - //standard assumption: version is assigned to an env variable - return getVersionFromDockerEnvVariable(configuration.filePath, configuration.dockerVersionSource) + if(configuration.artifactType == 'appContainer' && configuration.dockerVersionSource == 'appVersion'){ + //replace + sign if available since + is not allowed in a Docker tag + if (script.commonPipelineEnvironment.getArtifactVersion()){ + return script.commonPipelineEnvironment.getArtifactVersion().replace('+', '_') + }else{ + throw new IllegalArgumentException("No artifact version available for 'dockerVersionSource: appVersion' -> executeBuild needs to run for the application artifact first to set the appVersion attribute.'") + } + } else if (configuration.dockerVersionSource == 'FROM') { + def version = getVersionFromDockerBaseImageTag(configuration.filePath) + if (version) { + return getVersionFromDockerBaseImageTag(configuration.filePath) + } else { + throw new IllegalArgumentException("No version information available in FROM statement") + } + } else { + def version = getVersionFromDockerEnvVariable(configuration.filePath, configuration.dockerVersionSource) + if (version) { + return version + } else { + throw new IllegalArgumentException("ENV variable '${configuration.dockerVersionSource}' not found.") + } + } } @Override diff --git a/src/com/sap/piper/versioning/GolangArtifactVersioning.groovy b/src/com/sap/piper/versioning/GolangArtifactVersioning.groovy new file mode 100644 index 000000000..17c7a6229 --- /dev/null +++ b/src/com/sap/piper/versioning/GolangArtifactVersioning.groovy @@ -0,0 +1,17 @@ +package com.sap.piper.versioning + +class GolangArtifactVersioning extends ArtifactVersioning { + protected GolangArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + return script.readFile(configuration.filePath).split('\n')[0].trim() + } + + @Override + def setVersion(version) { + script.writeFile file: configuration.filePath, text: version + } +} diff --git a/src/com/sap/piper/versioning/NpmArtifactVersioning.groovy b/src/com/sap/piper/versioning/NpmArtifactVersioning.groovy new file mode 100644 index 000000000..7f82e5736 --- /dev/null +++ b/src/com/sap/piper/versioning/NpmArtifactVersioning.groovy @@ -0,0 +1,20 @@ +package com.sap.piper.versioning + +class NpmArtifactVersioning extends ArtifactVersioning { + protected NpmArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + def packageJson = script.readJSON file: configuration.filePath + return packageJson.version + } + + @Override + def setVersion(version) { + def packageJson = script.readJSON file: configuration.filePath + packageJson.version = new String(version) + script.writeJSON file: configuration.filePath, json: packageJson + } +} diff --git a/src/com/sap/piper/versioning/PipArtifactVersioning.groovy b/src/com/sap/piper/versioning/PipArtifactVersioning.groovy new file mode 100644 index 000000000..920a934c9 --- /dev/null +++ b/src/com/sap/piper/versioning/PipArtifactVersioning.groovy @@ -0,0 +1,17 @@ +package com.sap.piper.versioning + +class PipArtifactVersioning extends ArtifactVersioning { + protected PipArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + return script.readFile(configuration.filePath).split('\n')[0].trim() + } + + @Override + def setVersion(version) { + script.writeFile file: configuration.filePath, text: version + } +} diff --git a/src/com/sap/piper/versioning/SbtArtifactVersioning.groovy b/src/com/sap/piper/versioning/SbtArtifactVersioning.groovy new file mode 100644 index 000000000..c3de70fec --- /dev/null +++ b/src/com/sap/piper/versioning/SbtArtifactVersioning.groovy @@ -0,0 +1,20 @@ +package com.sap.piper.versioning + +class SbtArtifactVersioning extends ArtifactVersioning { + protected SbtArtifactVersioning(script, configuration) { + super(script, configuration) + } + + @Override + def getVersion() { + def sbtDescriptorJson = script.readJSON file: configuration.filePath + return sbtDescriptorJson.version + } + + @Override + def setVersion(version) { + def sbtDescriptorJson = script.readJSON file: configuration.filePath + sbtDescriptorJson.version = new String(version) + script.writeJSON file: configuration.filePath, json: sbtDescriptorJson + } +} diff --git a/test/groovy/ArtifactSetVersionTest.groovy b/test/groovy/ArtifactSetVersionTest.groovy index 25717cad7..8d1ec8916 100644 --- a/test/groovy/ArtifactSetVersionTest.groovy +++ b/test/groovy/ArtifactSetVersionTest.groovy @@ -47,6 +47,9 @@ class ArtifactSetVersionTest extends BasePiperTest { void init() throws Throwable { dockerParameters = [:] + nullScript.commonPipelineEnvironment.setArtifactVersion(null) + nullScript.commonPipelineEnvironment.setGitSshUrl('git@test.url') + helper.registerAllowedMethod("sshagent", [List.class, Closure.class], { list, closure -> sshAgentList = list return closure() @@ -64,7 +67,7 @@ class ArtifactSetVersionTest extends BasePiperTest { @Test void testVersioning() { - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl') + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl') assertEquals('1.2.3-20180101010203_testCommitId', jer.env.getArtifactVersion()) assertEquals('testCommitId', jer.env.getGitCommitId()) @@ -79,7 +82,7 @@ class ArtifactSetVersionTest extends BasePiperTest { @Test void testVersioningWithoutCommit() { - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false) + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false) assertEquals('1.2.3-20180101010203_testCommitId', jer.env.getArtifactVersion()) assertThat(jscr.shell, hasItem("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn versions:set -DnewVersion=1.2.3-20180101010203_testCommitId")) @@ -87,7 +90,7 @@ class ArtifactSetVersionTest extends BasePiperTest { @Test void testVersioningWithoutScript() { - jsr.step.call(juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false) + jsr.step.artifactSetVersion(juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false) assertEquals('1.2.3-20180101010203_testCommitId', jer.env.getArtifactVersion()) assertThat(jscr.shell, hasItem("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn versions:set -DnewVersion=1.2.3-20180101010203_testCommitId")) @@ -95,14 +98,14 @@ class ArtifactSetVersionTest extends BasePiperTest { @Test void testVersioningCustomGitUserAndEMail() { - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl', gitUserEMail: 'test@test.com', gitUserName: 'test') + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl', gitUserEMail: 'test@test.com', gitUserName: 'test') assertThat(jscr.shell, hasItem("git -c user.email=\"test@test.com\" -c user.name=\"test\" commit -m 'update version 1.2.3-20180101010203_testCommitId'")) } @Test void testVersioningWithTimestamp() { - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', timestamp: '2018') + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', timestamp: '2018') assertEquals('1.2.3-2018_testCommitId', jer.env.getArtifactVersion()) } @@ -110,23 +113,35 @@ class ArtifactSetVersionTest extends BasePiperTest { void testVersioningNoBuildTool() { thrown.expect(Exception) thrown.expectMessage('ERROR - NO VALUE AVAILABLE FOR buildTool') - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils) + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils) } @Test void testVersioningWithCustomTemplate() { - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', versioningTemplate: '${version}-xyz') + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'maven', versioningTemplate: '${version}-xyz') assertEquals('1.2.3-xyz', jer.env.getArtifactVersion()) } @Test void testVersioningWithTypeAppContainer() { + nullScript.commonPipelineEnvironment.setAppContainerProperty('gitSshUrl', 'git@test.url') jer.env.setArtifactVersion('1.2.3-xyz') - jsr.step.call(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'docker', artifactType: 'appContainer', dockerVersionSource: 'appVersion') + jsr.step.artifactSetVersion(script: jsr.step, juStabGitUtils: gitUtils, buildTool: 'docker', artifactType: 'appContainer', dockerVersionSource: 'appVersion') assertEquals('1.2.3-xyz', jer.env.getArtifactVersion()) assertEquals('1.2.3-xyz', jwfr.files['VERSION']) } + @Test + void testCredentialCompatibility() { + jsr.step.artifactSetVersion ( + script: nullScript, + buildTool: 'maven', + gitCredentialsId: 'testCredentials', + juStabGitUtils: gitUtils + ) + assertThat(sshAgentList, hasItem('testCredentials')) + } + void prepareObjectInterceptors(object) { object.metaClass.invokeMethod = helper.getMethodInterceptor() object.metaClass.static.invokeMethod = helper.getMethodInterceptor() diff --git a/test/groovy/com/sap/piper/versioning/DlangArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/DlangArtifactVersioningTest.groovy new file mode 100644 index 000000000..06f0e9a9b --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/DlangArtifactVersioningTest.groovy @@ -0,0 +1,32 @@ +package com.sap.piper.versioning + +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadJsonRule +import util.JenkinsWriteJsonRule +import util.Rules + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +class DlangArtifactVersioningTest extends BasePiperTest{ + + JenkinsReadJsonRule jrjr = new JenkinsReadJsonRule(this, 'test/resources/versioning/DlangArtifactVersioning/') + JenkinsWriteJsonRule jwjr = new JenkinsWriteJsonRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrjr) + .around(jwjr) + + @Test + void testVersioning() { + DlangArtifactVersioning av = new DlangArtifactVersioning(nullScript, [filePath: 'dub.json']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertTrue(jwjr.files['dub.json'].contains('1.2.3-20180101')) + } +} diff --git a/test/groovy/com/sap/piper/versioning/GolangArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/GolangArtifactVersioningTest.groovy new file mode 100644 index 000000000..4c12bd269 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/GolangArtifactVersioningTest.groovy @@ -0,0 +1,31 @@ +package com.sap.piper.versioning + +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadFileRule +import util.JenkinsWriteFileRule +import util.Rules + +import static org.junit.Assert.assertEquals + +class GolangArtifactVersioningTest extends BasePiperTest{ + + JenkinsReadFileRule jrfr = new JenkinsReadFileRule(this, 'test/resources/versioning/GolangArtifactVersioning/') + JenkinsWriteFileRule jwfr = new JenkinsWriteFileRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrfr) + .around(jwfr) + + @Test + void testVersioning() { + GolangArtifactVersioning av = new GolangArtifactVersioning(nullScript, [filePath: 'VERSION']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertEquals('1.2.3-20180101', jwfr.files['VERSION']) + } +} diff --git a/test/groovy/com/sap/piper/versioning/NpmArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/NpmArtifactVersioningTest.groovy new file mode 100644 index 000000000..8e0e25305 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/NpmArtifactVersioningTest.groovy @@ -0,0 +1,32 @@ +package com.sap.piper.versioning + +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadJsonRule +import util.JenkinsWriteJsonRule +import util.Rules + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +class NpmArtifactVersioningTest extends BasePiperTest{ + + JenkinsReadJsonRule jrjr = new JenkinsReadJsonRule(this, 'test/resources/versioning/NpmArtifactVersioning/') + JenkinsWriteJsonRule jwjr = new JenkinsWriteJsonRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrjr) + .around(jwjr) + + @Test + void testVersioning() { + NpmArtifactVersioning av = new NpmArtifactVersioning(nullScript, [filePath: 'package.json']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertTrue(jwjr.files['package.json'].contains('1.2.3-20180101')) + } +} diff --git a/test/groovy/com/sap/piper/versioning/PipArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/PipArtifactVersioningTest.groovy new file mode 100644 index 000000000..8332ee4cf --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/PipArtifactVersioningTest.groovy @@ -0,0 +1,31 @@ +package com.sap.piper.versioning + +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadFileRule +import util.JenkinsWriteFileRule +import util.Rules + +import static org.junit.Assert.assertEquals + +class PipArtifactVersioningTest extends BasePiperTest{ + + JenkinsReadFileRule jrfr = new JenkinsReadFileRule(this, 'test/resources/versioning/PipArtifactVersioning/') + JenkinsWriteFileRule jwfr = new JenkinsWriteFileRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrfr) + .around(jwfr) + + @Test + void testVersioning() { + PipArtifactVersioning av = new PipArtifactVersioning(nullScript, [filePath: 'version.txt']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertEquals('1.2.3-20180101', jwfr.files['version.txt']) + } +} diff --git a/test/groovy/com/sap/piper/versioning/SbtArtifactVersioningTest.groovy b/test/groovy/com/sap/piper/versioning/SbtArtifactVersioningTest.groovy new file mode 100644 index 000000000..e94b4ba88 --- /dev/null +++ b/test/groovy/com/sap/piper/versioning/SbtArtifactVersioningTest.groovy @@ -0,0 +1,32 @@ +package com.sap.piper.versioning + +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import util.BasePiperTest +import util.JenkinsReadJsonRule +import util.JenkinsWriteJsonRule +import util.Rules + +import static org.junit.Assert.assertEquals +import static org.junit.Assert.assertTrue + +class SbtArtifactVersioningTest extends BasePiperTest{ + + JenkinsReadJsonRule jrjr = new JenkinsReadJsonRule(this, 'test/resources/versioning/SbtArtifactVersioning/') + JenkinsWriteJsonRule jwjr = new JenkinsWriteJsonRule(this) + + @Rule + public RuleChain ruleChain = Rules + .getCommonRules(this) + .around(jrjr) + .around(jwjr) + + @Test + void testVersioning() { + SbtArtifactVersioning av = new SbtArtifactVersioning(nullScript, [filePath: 'sbtDescriptor.json']) + assertEquals('1.2.3', av.getVersion()) + av.setVersion('1.2.3-20180101') + assertTrue(jwjr.files['sbtDescriptor.json'].contains('1.2.3-20180101')) + } +} diff --git a/test/groovy/util/JenkinsWriteJsonRule.groovy b/test/groovy/util/JenkinsWriteJsonRule.groovy new file mode 100644 index 000000000..3c012a4bd --- /dev/null +++ b/test/groovy/util/JenkinsWriteJsonRule.groovy @@ -0,0 +1,34 @@ +package util + +import com.lesfurets.jenkins.unit.BasePipelineTest +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement + +class JenkinsWriteJsonRule implements TestRule { + + final BasePipelineTest testInstance + + Map files = [:] + + JenkinsWriteJsonRule(BasePipelineTest testInstance) { + this.testInstance = testInstance + } + + @Override + Statement apply(Statement base, Description description) { + return statement(base) + } + + private Statement statement(final Statement base) { + return new Statement() { + @Override + void evaluate() throws Throwable { + + testInstance.helper.registerAllowedMethod( 'writeJSON', [Map.class], {m -> files[m.file] = m.json.toString()}) + + base.evaluate() + } + } + } +} diff --git a/test/resources/versioning/DlangArtifactVersioning/dub.json b/test/resources/versioning/DlangArtifactVersioning/dub.json new file mode 100644 index 000000000..acfc33694 --- /dev/null +++ b/test/resources/versioning/DlangArtifactVersioning/dub.json @@ -0,0 +1,5 @@ +{ + "name": "sap-pipeline-test", + "version": "1.2.3", + "description": "package.json for testing", +} diff --git a/test/resources/versioning/GolangArtifactVersioning/VERSION b/test/resources/versioning/GolangArtifactVersioning/VERSION new file mode 100644 index 000000000..0495c4a88 --- /dev/null +++ b/test/resources/versioning/GolangArtifactVersioning/VERSION @@ -0,0 +1 @@ +1.2.3 diff --git a/test/resources/versioning/NpmArtifactVersioning/package.json b/test/resources/versioning/NpmArtifactVersioning/package.json new file mode 100644 index 000000000..05122c999 --- /dev/null +++ b/test/resources/versioning/NpmArtifactVersioning/package.json @@ -0,0 +1,15 @@ +{ + "name": "sap-pipeline-test", + "version": "1.2.3", + "private": false, + "description": "package.json for testing", + "engines": { + "node": "6.x" + }, + "dependencies": { + "apn": "1.7.8" + }, + "devDependencies": { + "chai": "^3.4.1" + } +} diff --git a/test/resources/versioning/PipArtifactVersioning/version.txt b/test/resources/versioning/PipArtifactVersioning/version.txt new file mode 100644 index 000000000..0495c4a88 --- /dev/null +++ b/test/resources/versioning/PipArtifactVersioning/version.txt @@ -0,0 +1 @@ +1.2.3 diff --git a/test/resources/versioning/SbtArtifactVersioning/sbtDescriptor.json b/test/resources/versioning/SbtArtifactVersioning/sbtDescriptor.json new file mode 100644 index 000000000..ea5c8cb34 --- /dev/null +++ b/test/resources/versioning/SbtArtifactVersioning/sbtDescriptor.json @@ -0,0 +1,4 @@ +{ + "name": "sap-pipeline-test", + "version": "1.2.3", +} diff --git a/vars/artifactSetVersion.groovy b/vars/artifactSetVersion.groovy index 587f5fd34..4b46a536d 100644 --- a/vars/artifactSetVersion.groovy +++ b/vars/artifactSetVersion.groovy @@ -8,13 +8,14 @@ import groovy.text.SimpleTemplateEngine @Field String STEP_NAME = 'artifactSetVersion' @Field Set GENERAL_CONFIG_KEYS = ['collectTelemetryData'] +@Field Map CONFIG_KEY_COMPATIBILITY = [gitSshKeyCredentialsId: 'gitCredentialsId'] @Field Set STEP_CONFIG_KEYS = [ 'artifactType', 'buildTool', 'commitVersion', 'dockerVersionSource', 'filePath', - 'gitCredentialsId', + 'gitSshKeyCredentialsId', 'gitUserEMail', 'gitUserName', 'gitSshUrl', @@ -25,7 +26,7 @@ import groovy.text.SimpleTemplateEngine ] @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus('gitCommitId') -def call(Map parameters = [:]) { +def call(Map parameters = [:], Closure body = null) { handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters) { @@ -43,49 +44,45 @@ def call(Map parameters = [:]) { // load default & individual configuration Map config = ConfigurationHelper .loadStepDefaults(this) - .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS) - .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS) - .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS) + .mixinGeneralConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, this, CONFIG_KEY_COMPATIBILITY) + .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, this, CONFIG_KEY_COMPATIBILITY) + .mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS, this, CONFIG_KEY_COMPATIBILITY) .mixin(gitCommitId: gitUtils.getGitCommitIdOrNull()) - .mixin(parameters, PARAMETER_KEYS) + .mixin(parameters, PARAMETER_KEYS, this, CONFIG_KEY_COMPATIBILITY) .withMandatoryProperty('buildTool') + .dependingOn('buildTool').mixin('filePath') + .dependingOn('buildTool').mixin('versioningTemplate') + .use() + + config = new ConfigurationHelper(config) + .addIfEmpty('gitSshUrl', (config.buildTool == 'docker' && config.artifactType == 'appContainer')?script.commonPipelineEnvironment.getAppContainerProperty('gitSshUrl'):script.commonPipelineEnvironment.getGitSshUrl()) + .addIfEmpty('timestamp', getTimestamp(config.timestampTemplate)) + .withMandatoryProperty('gitSshUrl') .use() new Utils().pushToSWA([step: STEP_NAME, stepParam1: config.buildTool], config) - if (!config.filePath) - config.filePath = config[config.buildTool].filePath //use default configuration + def artifactVersioning = ArtifactVersioning.getArtifactVersioning(config.buildTool, script, config) + def currentVersion = artifactVersioning.getVersion() def newVersion - def artifactVersioning = ArtifactVersioning.getArtifactVersioning(config.buildTool, script, config) - - if(config.artifactType == 'appContainer' && config.dockerVersionSource == 'appVersion'){ - if (script.commonPipelineEnvironment.getArtifactVersion()) - //replace + sign if available since + is not allowed in a Docker tag - newVersion = script.commonPipelineEnvironment.getArtifactVersion().replace('+', '_') - else - error ("[${STEP_NAME}] No artifact version available for 'dockerVersionSource: appVersion' -> executeBuild needs to run for the application artifact first to set the artifactVersion for the application artifact.'") + if (config.artifactType == 'appContainer' && config.dockerVersionSource == 'appVersion'){ + newVersion = currentVersion } else { - def currentVersion = artifactVersioning.getVersion() - - def timestamp = config.timestamp ? config.timestamp : getTimestamp(config.timestampTemplate) - - def versioningTemplate = config.versioningTemplate ? config.versioningTemplate : config[config.buildTool].versioningTemplate - //defined in default configuration - def binding = [version: currentVersion, timestamp: timestamp, commitId: config.gitCommitId] - def templatingEngine = new SimpleTemplateEngine() - def template = templatingEngine.createTemplate(versioningTemplate).make(binding) - newVersion = template.toString() + def binding = [version: currentVersion, timestamp: config.timestamp, commitId: config.gitCommitId] + newVersion = new SimpleTemplateEngine().createTemplate(config.versioningTemplate).make(binding).toString() } artifactVersioning.setVersion(newVersion) - def gitCommitId + if(body != null){ + body(newVersion) + } if (config.commitVersion) { sh 'git add .' - sshagent([config.gitCredentialsId]) { + sshagent([config.gitSshKeyCredentialsId]) { def gitUserMailConfig = '' if (config.gitUserName && config.gitUserEMail) gitUserMailConfig = "-c user.email=\"${config.gitUserEMail}\" -c user.name=\"${config.gitUserName}\"" @@ -99,17 +96,17 @@ def call(Map parameters = [:]) { sh "git tag ${config.tagPrefix}${newVersion}" sh "git push origin ${config.tagPrefix}${newVersion}" - gitCommitId = gitUtils.getGitCommitIdOrNull() + config.gitCommitId = gitUtils.getGitCommitIdOrNull() } } if (config.buildTool == 'docker' && config.artifactType == 'appContainer') { script.commonPipelineEnvironment.setAppContainerProperty('artifactVersion', newVersion) - script.commonPipelineEnvironment.setAppContainerProperty('gitCommitId', gitCommitId) + script.commonPipelineEnvironment.setAppContainerProperty('gitCommitId', config.gitCommitId) } else { //standard case script.commonPipelineEnvironment.setArtifactVersion(newVersion) - script.commonPipelineEnvironment.setGitCommitId(gitCommitId) + script.commonPipelineEnvironment.setGitCommitId(config.gitCommitId) } echo "[${STEP_NAME}]New version: ${newVersion}"