如何在代码存储库中包含 Gradle 自动递增版本号?



我的github公共存储库中有spring-boot应用程序。我使用gradle作为这个spring-boot应用程序的构建工具。我正在使用詹金斯作为CI/CD。

我在build.gradle文件中有以下任务,该文件用于自动递增构建号,以便我生成的可执行jar在生成的jar文件中具有唯一的版本名。

task versionIncr {
Properties props = new Properties()
File propsFile = new File('gradle.properties')
props.load(propsFile.newDataInputStream())
Integer nextbuildnum = ( ((props.getProperty('artifactBuildNumber')) as BigDecimal) + 1 )
props.setProperty('artifactBuildNumber', nextbuildnum.toString())
props.store(propsFile.newWriter(), null)
props.load(propsFile.newDataInputStream())
}

我把詹金斯的这项任务称为如下。

"versionIncr bootJar docker——警告模式=全部";

此任务运行良好。由于以下任务正在詹金斯服务器中进行

  1. jenkins将git$分支拉入jenkins服务器工作区
  2. 任务=>versionIncr正在执行,增加版本号,并更新詹金斯服务器中工作区中的"gradle.properties"文件
  3. 生成可执行jar文件
  4. 使用新生成的可执行jar文件创建docker映像

问题::对";CCD_ 3";文件保留在jenkins服务器工作区中,更新后的版本号不会反映在github分支中。由于jenkins在本地进行了更改,所以当我将任何更改推送到github并运行jenkins作业时,"gradle.properties"文件中的版本号仍然保持不变。我不想每次推送提交时手动更新版本号。我想让詹金斯帮我处理版本变更。

有没有任何方法或gradle插件或jenkins插件可以用来将修改后的"gradle.properties"文件从jenkins工作区推回到"github"存储库。如果可能的话,我也想知道使用github username/password或使用SSH的方法。

如果我需要在这里发布更多信息,请告诉我。

更新::发布我的build.gradle文件,以防有人对我的工作方式感兴趣。build.gradle

buildscript {
repositories {
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
}
}
plugins {
id 'org.springframework.boot' version '2.2.7.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
id 'maven-publish'
id 'com.palantir.docker' version '0.25.0'
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
//apply plugin: 'io.spring.gradle.dependencymanagement.DependencyManagementPlugin'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
//apply plugin: 'org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin'
group 'com.javasree'
version project.properties.containsKey("releaseVersion") ? "${artifactMajorVersion}" : "${artifactMajorVersion}-${artifactBuildNumber}"
sourceCompatibility = 1.8
ext {
springCloudVersion ='Greenwich.RELEASE'
artifactName ='<artifact>'
artifactory = 'http://localhost:8081/artifactory/'
artifactoryRepo = 'gradle-lib-release'
artifactorySnapShotRepo = 'gradle-lib-snashot'
artifactoryRepo3pp = 'pub-gradle-remote'
artifactoryUser = System.getProperty("user", "")
artifactoryPassword = System.getProperty("password", "")
}
repositories {
mavenCentral()
maven {
url "${artifactory}${artifactoryRepo3pp}"
allowInsecureProtocol = true
credentials {               // Optional resolver credentials (leave out to use anonymous resolution)
username = "admin" // Artifactory user name
password = "password" // Password or API Key
}
}
}
publishing.publications {
maven(MavenPublication) {
artifact bootJar
//      groupId 'gatewayengine'
//      artifactId artifactName
//      version '1.0-SNAPSHOT'
from components.java
}
}
publishing.repositories {
maven {
allowInsecureProtocol = true
credentials {
username = "admin" // Artifactory user name
password = "password" // Password or API Key
}
if(project.version.endsWith('-SNAPSHOT')) {
url "${artifactory}${artifactorySnapShotRepo}"
} else {
url "${artifactory}${artifactoryRepo}"
}
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
//mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
}
}
docker {
name "localhost:5000/${project.name}:${project.version}"
files tasks.bootJar.outputs
//tag 'localhost:5000/${project.name}:${project.version}'
dockerfile file('Dockerfile')
//buildArgs([HOST_APP_JAR_LOC: 'version'])
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web',
'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.2.2.RELEASE',
'org.springframework.cloud:spring-cloud-starter-netflix-zuul:2.2.2.RELEASE'
}


task versionIncr {
Properties props = new Properties()
File propsFile = new File('gradle.properties')
props.load(propsFile.newDataInputStream())
Integer nextbuildnum = ( ((props.getProperty('artifactBuildNumber')) as BigDecimal) + 1 )
props.setProperty('artifactBuildNumber', nextbuildnum.toString())
props.store(propsFile.newWriter(), null)
props.load(propsFile.newDataInputStream())
}

我之前已经通过两种不同的方式解决了您提出的问题。首先,使用Gradle插件,类似于上面链接的nebula-release插件@sghill。

然而,该插件的工作原理是计算补丁版本的所有提交,通过Gradle扩展配置主要和次要,并附加元数据信息,例如分支名称和是否脏。对于我的需求来说,这似乎是一个过于复杂的工作流程,对没有使用Gradle的项目没有用处。然而,对于您的案例,这是一个现成的快速解决方案。

在我的案例中,我所需要的只是在合并到developmaster的PR上自动标记的唯一版本号,以及分支上每个提交的唯一版本编号。为了做到这一点,我确实使用了Git标签,并为此编写了一个脚本

版本控制的3种情况是:

  • 一个新的、未初始化的repo=>生成一个带有默认分支的新版本.json文件(主文件,但每个repo可以更改,一个主要版本和一个次要版本来配置这些bump)
  • 任何合并到默认分支中的提交都会生成一个新版本并对其进行标记。如果version.json中的主要或次要版本已更改,则会发生主要或次要冲突,补丁版本将重置为0
  • 分支上的唯一版本:git describe的输出和分支名称,例如0.1.0-x-branch-name,其中x是默认分支之前的提交数

你可以在这里找到它,在这里找到码头集装箱

至于将Jenkins配置为具有对repo的写访问权限,您是否遵循了此处的说明?这就是我在所有回购中成功做到的:使用声明性管道中的jenkins凭据进行Git推送

nebula.release Gradle插件能够使用git标记自动递增版本。开始:

plugins {
id 'nebula.release' version '15.0.0' // or current latest
}

该插件为发布类型添加了几个任务,并为哪个版本组件增加了选项。默认情况下,它将递增次要版本。以下是一个如何在单个分支上增加版本的示例:

$ ./gradlew final                       # releases 0.1.0; tags repo v0.1.0
$ ./gradlew final                       # releases 0.2.0; tags repo v0.2.0
$ ./gradlew final -Prelease.scope=minor # releases 0.2.1; tags repo v0.2.1

由于版本是在找到上一个git标记后递增的,因此可以通过在最近的提交中手动创建git标记来调整起始版本。

注意事项:

  1. Jenkins需要对repo进行写访问以推送标签
  2. 该插件假设回购中的所有内容都将使用相同的版本发布
  3. 它非常喜欢类似semver的版本

如果这不符合您的用例,Gradle插件门户网站上还有更多版本控制插件可供选择。

版本号几乎不是自动增量,但构建号是。

Jenkins为每个项目公开了自己的自动递增${BUILD_NUMBER}

使用System.getenv("BUILD_NUMBER")可以在构建时获得:

// $BUILD_NUMBER only exists when building with Jenkins
project.ext.set('BUILD_NUMBER', System.getenv("BUILD_NUMBER") ?: "0")

昨天在Google Cloud Build中,我还定义了一个BUILD_NUMBER
因为我需要在手动构建和自动构建之间有所不同
。。。不同的构建器可以提供不同的环境变量。

Jenkins通常在分支发生变化时构建。因此,可以通过Git更新version.properties文件(本地pre-commit钩子可以递增)
如果您真的想在每次提交到Github时增加版本。

最新更新