2018-09-21 16:55:31 +02:00
import static com . sap . piper . Prerequisites . checkScript
2019-03-28 11:46:19 +02:00
import com.sap.piper.GenerateDocumentation
2018-03-12 23:23:10 +02:00
import com.sap.piper.ConfigurationHelper
2018-02-07 14:17:33 +02:00
import com.sap.piper.GitUtils
import com.sap.piper.Utils
import com.sap.piper.versioning.ArtifactVersioning
2018-03-12 23:19:45 +02:00
import groovy.transform.Field
2018-02-07 14:17:33 +02:00
import groovy.text.SimpleTemplateEngine
2018-11-29 10:54:05 +02:00
@Field String STEP_NAME = getClass ( ) . getName ( )
2018-08-08 22:21:26 +02:00
@Field Map CONFIG_KEY_COMPATIBILITY = [ gitSshKeyCredentialsId: 'gitCredentialsId' ]
2018-10-25 14:11:11 +02:00
@Field Set GENERAL_CONFIG_KEYS = STEP_CONFIG_KEYS
2018-03-12 23:19:45 +02:00
@Field Set STEP_CONFIG_KEYS = [
2019-03-28 11:46:19 +02:00
/ * *
* Defines the type of the artifact .
* @possibleValues ` appContainer `
* /
2018-03-12 23:19:45 +02:00
'artifactType' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines the tool which is used for building the artifact .
2019-07-03 11:27:07 +02:00
* @possibleValues ` dub ` , ` docker ` , ` golang ` , ` maven ` , ` mta ` , ` npm ` , ` pip ` , ` sbt `
2019-03-28 11:46:19 +02:00
* /
2018-03-12 23:19:45 +02:00
'buildTool' ,
2019-03-28 11:46:19 +02:00
/ * *
* 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 ` .
* @possibleValues ` true ` , ` false `
* /
2018-03-12 23:19:45 +02:00
'commitVersion' ,
2019-03-28 11:46:19 +02:00
/ * *
* 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 `
* * Alternatively the name of an environment variable defined in the Docker image can be used which contains the version number , e . g . ` ENV MY_VERSION 1.2 . 3 `
* * The third option ` appVersion ` applies only to the artifactType ` appContainer ` . Here the version of the app which is packaged into the container will be used as version for the container itself .
* @possibleValues FROM , ( ENV name ) , appVersion
* /
2018-03-12 23:19:45 +02:00
'dockerVersionSource' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines a custom path to the descriptor file .
* /
2018-03-12 23:19:45 +02:00
'filePath' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines the ssh git credentials to be used for writing the tag .
* /
2018-08-08 22:21:26 +02:00
'gitSshKeyCredentialsId' ,
2019-03-28 11:46:19 +02:00
/ * *
* Allows to overwrite the global git setting 'user.email' available on your Jenkins server .
* /
2018-03-12 23:19:45 +02:00
'gitUserEMail' ,
2019-03-28 11:46:19 +02:00
/ * *
* Allows to overwrite the global git setting 'user.name' available on your Jenkins server .
* /
2018-03-12 23:19:45 +02:00
'gitUserName' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines the git ssh url to the source code repository .
* /
2018-03-12 23:19:45 +02:00
'gitSshUrl' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines the prefix which is used for the git tag which is written during the versioning run .
* /
2018-03-12 23:19:45 +02:00
'tagPrefix' ,
2019-03-28 11:46:19 +02:00
/ * *
* Defines the timestamp to be used in the automatic version string . You could overwrite the default behavior by explicitly setting this string .
* /
2018-03-12 23:19:45 +02:00
'timestamp' ,
2019-03-28 11:46:19 +02:00
/** Defines the template for the timestamp which will be part of the created version. */
2018-03-12 23:19:45 +02:00
'timestampTemplate' ,
2019-03-28 11:46:19 +02:00
/** Defines the template for the automatic version which will be created. */
2018-03-12 23:19:45 +02:00
'versioningTemplate'
]
2018-10-25 14:11:11 +02:00
2019-03-28 11:46:19 +02:00
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS . plus (
/ * *
* 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: `' ' ` .
* /
'gitCommitId'
)
2018-02-07 14:17:33 +02:00
2019-03-28 11:46:19 +02:00
/ * *
* The continuous delivery process requires that each build is done with a unique version number .
*
* The version generated using this step will contain:
*
* * Version ( major . minor . patch ) from descriptor file in master repository is preserved . Developers should be able to autonomously decide on increasing either part of this version number .
* * Timestamp
* * CommitId ( by default the long version of the hash )
*
* 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 .
* /
@GenerateDocumentation
2018-08-30 16:33:07 +02:00
void call ( Map parameters = [ : ] , Closure body = null ) {
2018-02-07 14:17:33 +02:00
2018-03-12 23:19:45 +02:00
handlePipelineStepErrors ( stepName: STEP_NAME , stepParameters: parameters ) {
2018-02-07 14:17:33 +02:00
2018-09-21 16:55:31 +02:00
def script = checkScript ( this , parameters )
2018-08-06 08:57:36 +02:00
def gitUtils = parameters . juStabGitUtils ? : new GitUtils ( )
2018-02-07 14:17:33 +02:00
2018-09-13 14:34:26 +02:00
if ( gitUtils . isWorkTreeDirty ( ) ) {
2018-03-12 23:19:45 +02:00
error "[${STEP_NAME}] Files in the workspace have been changed previously - aborting ${STEP_NAME}"
2018-03-05 10:04:53 +02:00
}
2018-02-07 14:17:33 +02:00
if ( script = = null )
2018-04-05 11:36:51 +02:00
script = this
2018-03-12 23:19:45 +02:00
// load default & individual configuration
2018-10-17 11:05:20 +02:00
ConfigurationHelper configHelper = ConfigurationHelper . newInstance ( this )
2018-09-07 10:08:16 +02:00
. loadStepDefaults ( )
2018-10-25 14:11:11 +02:00
. mixinGeneralConfig ( script . commonPipelineEnvironment , GENERAL_CONFIG_KEYS , CONFIG_KEY_COMPATIBILITY )
2018-09-06 16:45:30 +02:00
. mixinStepConfig ( script . commonPipelineEnvironment , STEP_CONFIG_KEYS , CONFIG_KEY_COMPATIBILITY )
. mixinStageConfig ( script . commonPipelineEnvironment , parameters . stageName ? : env . STAGE_NAME , STEP_CONFIG_KEYS , CONFIG_KEY_COMPATIBILITY )
2018-03-12 23:19:45 +02:00
. mixin ( gitCommitId: gitUtils . getGitCommitIdOrNull ( ) )
2018-09-06 16:45:30 +02:00
. mixin ( parameters , PARAMETER_KEYS , CONFIG_KEY_COMPATIBILITY )
2018-08-06 08:57:36 +02:00
. withMandatoryProperty ( 'buildTool' )
2018-08-08 22:21:26 +02:00
. dependingOn ( 'buildTool' ) . mixin ( 'filePath' )
. dependingOn ( 'buildTool' ) . mixin ( 'versioningTemplate' )
2018-03-14 13:29:21 +02:00
2018-08-16 09:43:32 +02:00
Map config = configHelper . use ( )
config = configHelper . addIfEmpty ( 'timestamp' , getTimestamp ( config . timestampTemplate ) )
. use ( )
2018-02-07 14:17:33 +02:00
2019-01-21 09:47:34 +02:00
new Utils ( ) . pushToSWA ( [
step: STEP_NAME ,
stepParamKey1: 'buildTool' ,
stepParam1: config . buildTool ,
stepParamKey2: 'artifactType' ,
stepParam2: config . artifactType ,
stepParamKey3: 'scriptMissing' ,
stepParam3: parameters ? . script = = null
] , config )
2018-02-07 14:17:33 +02:00
2018-08-06 08:57:36 +02:00
def artifactVersioning = ArtifactVersioning . getArtifactVersioning ( config . buildTool , script , config )
2018-08-08 22:21:26 +02:00
def currentVersion = artifactVersioning . getVersion ( )
2018-02-07 14:17:33 +02:00
2018-08-08 22:21:26 +02:00
def newVersion
if ( config . artifactType = = 'appContainer' & & config . dockerVersionSource = = 'appVersion' ) {
newVersion = currentVersion
2018-02-07 14:17:33 +02:00
} else {
2018-08-08 22:21:26 +02:00
def binding = [ version: currentVersion , timestamp: config . timestamp , commitId: config . gitCommitId ]
newVersion = new SimpleTemplateEngine ( ) . createTemplate ( config . versioningTemplate ) . make ( binding ) . toString ( )
2018-02-07 14:17:33 +02:00
}
artifactVersioning . setVersion ( newVersion )
2018-08-08 22:21:26 +02:00
if ( body ! = null ) {
body ( newVersion )
}
2018-02-07 14:17:33 +02:00
2018-08-06 08:57:36 +02:00
if ( config . commitVersion ) {
2018-10-17 11:37:40 +02:00
config = ConfigurationHelper . newInstance ( this , config )
2018-08-16 09:43:32 +02:00
. addIfEmpty ( 'gitSshUrl' , isAppContainer ( config )
? script . commonPipelineEnvironment . getAppContainerProperty ( 'gitSshUrl' )
: script . commonPipelineEnvironment . getGitSshUrl ( ) )
. withMandatoryProperty ( 'gitSshUrl' )
. use ( )
2019-01-21 09:47:34 +02:00
2018-09-03 13:39:59 +02:00
def gitConfig = [ ]
2018-02-07 14:17:33 +02:00
2018-09-03 13:39:59 +02:00
if ( config . gitUserEMail ) gitConfig . add ( "-c user.email=\"${config.gitUserEMail}\"" )
if ( config . gitUserName ) gitConfig . add ( "-c user.name=\"${config.gitUserName}\"" )
gitConfig = gitConfig . join ( ' ' )
try {
sh "" " # ! /bin/ bash
2019-05-17 13:20:13 +02:00
git add .
git $ { gitConfig } commit - m 'update version ${newVersion}'
git tag $ { config . tagPrefix } $ { newVersion } "" "
2018-08-08 22:21:26 +02:00
config . gitCommitId = gitUtils . getGitCommitIdOrNull ( )
2018-09-03 13:39:59 +02:00
} catch ( e ) {
2018-09-05 11:44:40 +02:00
error "[${STEP_NAME}]git commit and tag failed: ${e}"
2018-09-03 13:39:59 +02:00
}
sshagent ( [ config . gitSshKeyCredentialsId ] ) {
sh "git push ${config.gitSshUrl} ${config.tagPrefix}${newVersion}"
2018-03-05 10:04:53 +02:00
}
2018-02-07 14:17:33 +02:00
}
2018-08-16 09:43:32 +02:00
if ( isAppContainer ( config ) ) {
2018-02-07 14:17:33 +02:00
script . commonPipelineEnvironment . setAppContainerProperty ( 'artifactVersion' , newVersion )
2018-08-08 22:21:26 +02:00
script . commonPipelineEnvironment . setAppContainerProperty ( 'gitCommitId' , config . gitCommitId )
2018-02-07 14:17:33 +02:00
} else {
//standard case
script . commonPipelineEnvironment . setArtifactVersion ( newVersion )
2018-08-08 22:21:26 +02:00
script . commonPipelineEnvironment . setGitCommitId ( config . gitCommitId )
2018-02-07 14:17:33 +02:00
}
2018-03-05 10:04:53 +02:00
2018-03-12 23:19:45 +02:00
echo "[${STEP_NAME}]New version: ${newVersion}"
2018-02-07 14:17:33 +02:00
}
}
2018-08-16 09:43:32 +02:00
def isAppContainer ( config ) {
return config . buildTool = = 'docker' & & config . artifactType = = 'appContainer'
}
2018-02-07 14:17:33 +02:00
def getTimestamp ( pattern ) {
2019-04-02 15:59:33 +02:00
return sh ( returnStdout: true , script: "date --utc +'${pattern}'" ) . trim ( )
2018-02-07 14:17:33 +02:00
}