This plugin has the purpose to work with GoCD in order to detect if a build runs in a GoCD pipeline on a GoCD build agent. Depending on that, the project version identifier will be updated.
There are no dependencies to other plugins.
Version 0.0.1
works with Java-11 or newer, version 0.0.2
works again with Java-8 and newer.
GoCD uses pipelines to build artifacts. Each pipeline has a unique and independent environment and the pipeline instances are also versioned as well using the environment variable GO_PIPELINE_COUNTER
. With that it is possible to use the build count including the number of attempts for each build/pipeline instance within a version number.
This means, that just re-running the build pipeline, a new version number is created, which will help then to separate if a problem is caused by an erroneous build or by a bug in source code. Another point is, that when the GoCD environment GO_PIPELINE_COUNTER
is not detected, a deployment operation could be suppressed. This means, that e.g. local builds cannot be published into remote repositories.
As of now for a Java library the Gradle code (Groovy DSL) looks as follows:
plugins {
id "java-library"
id "com.palantir.git-version" version "0.15.0"
id 'net.raumzeitfalle.gradle.gocdversion' version '0.0.8'
}
// Git details are provided by git-version plugin
version = gocdVersion(versionDetails().lastTag+'.'+versionDetails().commitDistance,
versionDetails().lastTag+'.'+versionDetails().commitDistance+'-'+versionDetails().gitHash).build()
In this example I've decided to go with the gradle-git-version plugin plugin to build the basic version number for a project. A version number might look like: MAJOR.MINOR.PATCH (e.g. 2.0.11).
The idea is, that the PATCH version can be directly taken from Git history. One could tag
a specific git commit with an appropriate MAJOR.MINOR
value.
The count of commits after the last tag
then represents the PATCH
version.
As with version 0.0.6
, no 3rd party plugin is needed to obtain a version number from Git tag. When calling gocdVersion()
without arguments, the plugin will attempt to obtain the latest Git tag and also commit distance to the head. Its not tested yet with all thinkable git scenarios - its very experimental.
Approach:
- declare
MAJOR.MINOR
usinggit tag
command - use commit count after last
tag
asPATCH
version - A new, automatically created version could look like: MAJOR.MINOR.PATCH.BUILD (or MAJOR.MINOR.PATCH.GO-PIPELINE-COUNT)
The gocdVersion
function takes 2 arguments, the first one is the string to be used as version for automated builds, the second one for manual or local builds.
So the effective version for a project can be different for atomated builds and manually initiated builds.
With the configuration in the example, the created version number looks as follows:
- git tag such as
1.0
exists - there are NO commits behind
1.0
, the commit distance is 0 - the build is executed in a GoCD pipeline with
GO_PIPELINE_COUNTER=153.1
):
# (tag.commit-distance.pipeline-counter)
version = 1.0.0.153.1
- git tag such as
1.0
exists - there are NO commits behind
1.0
, the commit distance is 0 - the build is executed on a computer with name ENIAC, there is no environment variable
GO_PIPELINE_COUNTER=xyz
):
# (tag.commit-distance-hash.computername.timestamp)
version = 1.0.0-96bfec85d4.ENIAC.20210906000609
Using the gocdVersion
closure the version schema can be configured.
// Defaults
gocdVersion {
appendPipelineCounterToAutomatedBuilds = true
appendStageCounterToAutomatedBuilds = true
appendComputerNameToLocalBuilds = true
appendTimestampToLocalBuilds = true
defaultTimestampPattern = "yyyyMMddHHmmss"
timestampPattern = "yyyyMMddHHmmss"
missingGitCommitFallbackTag = "<notag>"
}
The effective version number schema can be verified using the printGocdEnvironment
task on commandline.
> ./gradlew printGocdEnvironment
---------------------------------------------------------
Gocd Pipeline Environment
---------------------------------------------------------
GO_SERVER_URL = http://192.168.1.2:8053
GO_PIPELINE_GROUP_NAME = engineering
GO_ENVIRONMENT_NAME = windows-java-20
GO_TRIGGER_USER = doejohn
GO_AGENT_RESOURCES = windows,java20,special
GO_PIPELINE_NAME = test-build
GO_PIPELINE_COUNTER = 12.1
GO_PIPELINE_LABEL = 1.12.1
GO_STAGE_NAME = build
GO_STAGE_COUNTER = 1
GO_JOB_NAME = build
COMPUTERNAME = ENIAC
---------------------------------------------------------
Project version = 20220526.2.12.1
Is automated build? = true
Automated Version using Git Tag = 20220526.2
---------------------------------------------------------
- git tag such as
20220930
exists - there were 12 commits after the tag, so the commit distance is 12
# (tag.commit-distance.pipeline-counter)
def jpkgversion = jpackageVersion(versionDetails().lastTag+'.'+versionDetails().commitDistance).build()
println(jpkgversion)
22.39.12
println( gocdEnvironmentName() )
println( gocdPipelineGroupName() )
println( gocdPipelineName() )
println( gitTagVersion() )
println( gocdPipelineCounter() )
println( gocdPipelineLabel() )
println( gocdStageName() )
println( gocdStageCounter() )
println( gocdJobName() )
println( gocdComputerName() )
println( gocdTriggerUser() )
println( isAutomatedBuild() )
println( gocdGitMaterialBranchName("GIT_MATERIAL_NAME") )
println( gocdComputerName() )
println( gocdServerUrl() )
println( gocdVersion() )
println( gocdVersion("versionForAutomatedBuilds", "versionForManualBuilds") )
- Version schema:
git tag
.commit count since tag
(e.g.1.0.9
) - The nice thing is now, that no other plug in is needed and it now works for sub-projects as well.
buildscript {
repositories {
mavenLocal()
}
dependencies {
classpath 'net.raumzeitfalle.gradle.gocd:GocdVersionPlugin:0.0.8'
}
}
plugins {
id 'java-library'
id 'net.raumzeitfalle.gradle.gocdversion' version '0.0.8'
}
version = gocdVersion().build()
println("Automatic version=" + version)
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:30.1.1-jre'
}
tasks.named('test') {
useJUnitPlatform()
}
Copyright 2021, 2024 Oliver Löffler
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.