1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Make commit of new version optional in artifactSetVersion step (#112)

* Make commit of new version optional in `artifactSetVersion` step

You might not want to add a new commit for each version, when versions
are automatically created. This commit makes this feature optional, but
enabled by default to maintain API compatibility.

* Set `gitCommitId` if null

* Improve documentation of `commitVersion` parameter

* Allow to operate in a code checkout without `.git` directory
This commit is contained in:
Florian Wilhelm 2018-03-05 09:04:53 +01:00 committed by Oliver Nocon
parent f18f11fafe
commit ff46bb0f00
6 changed files with 64 additions and 35 deletions

View File

@ -9,7 +9,10 @@ The version generated using this step will contain:
* Timestamp
* CommitId (by default the long version of the hash)
After conducting automatic versioning the new version is pushed as a new tag into the source code repository (e.g. GitHub)
Optionally, but enabled by default, the new version is pushed as a new tag into the source code repository (e.g. GitHub).
If this option is chosen, git credentials and the repository URL needs to be provided.
Since you might not want to configure the git credentials in Jenkins, committing and pushing can be disabled using the `commitVersion` parameter as described below.
If you require strict reproducibility of your builds, this should be used.
## Prerequsites
none
@ -20,13 +23,14 @@ none
| ----------|-----------|---------|-----------------|
| script | no | empty `commonPipelineEnvironment` | |
| buildTool | no | maven | maven, docker |
| commitVersion | no | `true` | `true`, `false` |
| dockerVersionSource | no | `''` | FROM, (ENV name),appVersion |
| filePath | no | buildTool=`maven`: pom.xml <br />docker: Dockerfile | |
| gitCommitId | no | `GitUtils.getGitCommitId()` | |
| gitCredentialsId | yes | as defined in custom configuration | |
| gitCredentialsId | If `commitVersion` is `true` | as defined in custom configuration | |
| gitUserEMail | no | | |
| gitUserName | no | | |
| gitSshUrl | yes | | |
| 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` | |
@ -34,6 +38,7 @@ none
* `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.
* `buildTool` defines the tool which is used for building the artifact.
* `commitVersion` controls if the changed version is committed and pushed to the git repository. If this is enabled (which is the default), you need to provide `gitCredentialsId` and `gitSshUrl`.
* `dockerVersionSource` specifies the source to be used for the main version which is used for generating the automatic version.
* This can either be the version of the base image - as retrieved from the `FROM` statement within the Dockerfile, e.g. `FROM jenkins:2.46.2`
@ -53,6 +58,7 @@ Following parameters can also be specified as step parameters using the global c
* `artifactType`
* `buildTool`
* `commitVersion`
* `dockerVersionSource`
* `filePath`
* `gitCredentialsId`

View File

@ -7,6 +7,7 @@ steps:
artifactSetVersion:
timestampTemplate: '%Y%m%d%H%M%S'
tagPrefix: 'build_'
commitVersion: true
maven:
filePath: 'pom.xml'
versioningTemplate: '${version}-${timestamp}${commitId?"_"+commitId:""}'

View File

@ -1,6 +1,12 @@
package com.sap.piper
import com.cloudbees.groovy.cps.NonCPS
def getGitCommitIdOrNull() {
if (fileExists('.git')) {
return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
} else {
return null
}
}
def getGitCommitId() {
return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()

View File

@ -6,13 +6,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import util.JenkinsLoggingRule
import util.JenkinsReadMavenPomRule
import util.JenkinsShellCallRule
import util.JenkinsWriteFileRule
import util.JenkinsStepRule
import util.JenkinsEnvironmentRule
import util.Rules
import util.*
import static org.junit.Assert.assertEquals
@ -51,6 +45,8 @@ class ArtifactSetVersionTest extends BasePipelineTest {
gitUtils = new GitUtils()
prepareObjectInterceptors(gitUtils)
this.helper.registerAllowedMethod('fileExists', [String.class], {true})
}
@Test
@ -68,6 +64,14 @@ class ArtifactSetVersionTest extends BasePipelineTest {
assertEquals ("git push origin build_1.2.3-20180101010203_testCommitId", jscr.shell[8])
}
@Test
void testVersioningWithoutCommit() {
jsr.step.call(script: [commonPipelineEnvironment: jer.env], juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false)
assertEquals('1.2.3-20180101010203_testCommitId', jer.env.getArtifactVersion())
assertEquals('mvn versions:set -DnewVersion=1.2.3-20180101010203_testCommitId --file pom.xml', jscr.shell[3])
}
@Test
void testVersioningCustomGitUserAndEMail() {
jsr.step.call(script: [commonPipelineEnvironment: jer.env], juStabGitUtils: gitUtils, buildTool: 'maven', gitSshUrl: 'myGitSshUrl', gitUserEMail: 'test@test.com', gitUserName: 'test')

View File

@ -6,12 +6,12 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import util.JenkinsReadMavenPomRule
import util.JenkinsShellCallRule
import util.MockHelper
import util.Rules
import util.SharedLibraryCreator
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNull
class GitUtilsTest extends BasePipelineTest {
@ -27,6 +27,7 @@ class GitUtilsTest extends BasePipelineTest {
void init() throws Exception {
gitUtils = new GitUtils()
prepareObjectInterceptors(gitUtils)
gitUtils.fileExists = MockHelper
jscr.setReturnValue('git rev-parse HEAD', 'testCommitId')
}
@ -39,9 +40,14 @@ class GitUtilsTest extends BasePipelineTest {
@Test
void testGetGitCommitId() {
this.helper.registerAllowedMethod('fileExists', [String.class], {true})
assertEquals('testCommitId', gitUtils.getGitCommitIdOrNull())
}
assertEquals('testCommitId', gitUtils.getGitCommitId())
@Test
void testGetGitCommitIdNotAGitRepo() {
this.helper.registerAllowedMethod('fileExists', [String.class], {false})
assertNull(gitUtils.getGitCommitIdOrNull())
}
}

View File

@ -15,8 +15,10 @@ def call(Map parameters = [:]) {
gitUtils = new GitUtils()
}
if (sh(returnStatus: true, script: 'git diff --quiet HEAD') != 0)
error "[${stepName}] Files in the workspace have been changed previously - aborting ${stepName}"
if (fileExists('.git')) {
if (sh(returnStatus: true, script: 'git diff --quiet HEAD') != 0)
error "[${stepName}] Files in the workspace have been changed previously - aborting ${stepName}"
}
def script = parameters.script
if (script == null)
@ -27,6 +29,7 @@ def call(Map parameters = [:]) {
Set parameterKeys = [
'artifactType',
'buildTool',
'commitVersion',
'dockerVersionSource',
'filePath',
'gitCommitId',
@ -40,11 +43,12 @@ def call(Map parameters = [:]) {
'versioningTemplate'
]
Map pipelineDataMap = [
gitCommitId: gitUtils.getGitCommitId()
gitCommitId: gitUtils.getGitCommitIdOrNull()
]
Set stepConfigurationKeys = [
'artifactType',
'buildTool',
'commitVersion',
'dockerVersionSource',
'filePath',
'gitCredentialsId',
@ -89,29 +93,30 @@ def call(Map parameters = [:]) {
artifactVersioning.setVersion(newVersion)
sh 'git add .'
def gitCommitId
sshagent([configuration.gitCredentialsId]) {
def gitUserMailConfig = ''
if (configuration.gitUserName && configuration.gitUserEMail)
gitUserMailConfig = "-c user.email=\"${configuration.gitUserEMail}\" -c user.name \"${configuration.gitUserName}\""
if (configuration.commitVersion) {
sh 'git add .'
try {
sh "git ${gitUserMailConfig} commit -m 'update version ${newVersion}'"
} catch (e) {
error "[${stepName}]git commit failed: ${e}"
sshagent([configuration.gitCredentialsId]) {
def gitUserMailConfig = ''
if (configuration.gitUserName && configuration.gitUserEMail)
gitUserMailConfig = "-c user.email=\"${configuration.gitUserEMail}\" -c user.name \"${configuration.gitUserName}\""
try {
sh "git ${gitUserMailConfig} commit -m 'update version ${newVersion}'"
} catch (e) {
error "[${stepName}]git commit failed: ${e}"
}
sh "git remote set-url origin ${configuration.gitSshUrl}"
sh "git tag ${configuration.tagPrefix}${newVersion}"
sh "git push origin ${configuration.tagPrefix}${newVersion}"
gitCommitId = gitUtils.getGitCommitIdOrNull()
}
sh "git remote set-url origin ${configuration.gitSshUrl}"
sh "git tag ${configuration.tagPrefix}${newVersion}"
sh "git push origin ${configuration.tagPrefix}${newVersion}"
gitCommitId = gitUtils.getGitCommitId()
}
if(buildTool == 'docker' && configuration.artifactType == 'appContainer') {
if (buildTool == 'docker' && configuration.artifactType == 'appContainer') {
script.commonPipelineEnvironment.setAppContainerProperty('artifactVersion', newVersion)
script.commonPipelineEnvironment.setAppContainerProperty('gitCommitId', gitCommitId)
} else {
@ -119,6 +124,7 @@ def call(Map parameters = [:]) {
script.commonPipelineEnvironment.setArtifactVersion(newVersion)
script.commonPipelineEnvironment.setGitCommitId(gitCommitId)
}
echo "[${stepName}]New version: ${newVersion}"
}
}