1

SpringBoot使用git-commit-id-maven-plugin打包 - Naylor

 6 months ago
source link: https://www.cnblogs.com/Naylor/p/18024689
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SpringBoot使用git-commit-id-maven-plugin打包 - Naylor - 博客园

git-commit-id-maven-plugin 是一个maven 插件,用来在打包的时候将git-commit 信息打进jar中。

这样做的好处是可以将发布的某版本和对应的代码关联起来,方便查阅和线上项目的维护。至于它的作用,用官方说法,这个功能对于大型分布式项目来说是无价的。

你是否经常遇到这样的问题:

  • 测试提交了一个bug,开发人员无法确认是哪个版本有这个问题,当前测试环境部署的是某个版本吗?生产环境会不会也有这个问题?

  • 公司内部的项目,总共几十、几百个服务,每天都有服务的生产环境部署,一个服务甚至一天上线好几次,对于项目管理来说无法清晰了解某一时刻某个服务的版本

  • 如何验证我的代码是否已经上线?

  • 。。。。。。

以上种种,都有一个共同的诉求,就是我希望在打包的时候将最后一次 git commit id 和当前 jar 关联起来并可试试查询jar对应的git commit id 。

本例SpringBoot版本为 2.7.6,java版本为11

此插件已经上传到中央仓库(https://central.sonatype.com/artifact/io.github.git-commit-id/git-commit-id-maven-plugin?smo=true)

在项目pom.xml 中引入如下插件



<project>
    ......
    <build>
        <plugins>
            <!--  git-commit-id-maven-plugin :打包的时候携带git提交信息  -->
            <plugin>
                <groupId>io.github.git-commit-id</groupId>
                <artifactId>git-commit-id-maven-plugin</artifactId>
                <version>5.0.0</version>
                <executions>
                    <execution>
                        <id>get-the-git-infos</id>
                        <goals>
                            <goal>revision</goal>
                        </goals>
                        <phase>initialize</phase>
                    </execution>
                </executions>
                <configuration>
                    <generateGitPropertiesFile>true</generateGitPropertiesFile>
                    <generateGitPropertiesFilename>${project.build.outputDirectory}/git.</generateGitPropertiesFilename>
                    <includeOnlyProperties>
                        <includeOnlyProperty>^git.build.(time|version)$</includeOnlyProperty>
                        <includeOnlyProperty>^git.commit.id.(abbrev|full)$</includeOnlyProperty>
                    </includeOnlyProperties>
                    <format>txt</format>
                    <commitIdGenerationMode>full</commitIdGenerationMode>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>



  • generateGitPropertiesFilename:用于指定生成的gitCommitInfo存放到哪个位置,后缀可以任意指定,如果不指定将使用format的值
  • format:指定文件后缀,一般为 properties , json
  • commitIdGenerationMode:记录完整信息,若format为json,此值必须为full

此外为了能成功打出jar包,还需要如下插件的配合:



<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring-boot.version}</version>
    <configuration>
        <includeSystemScope>true</includeSystemScope>
        <excludes>
            <exclude>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>repackage</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>


使用maven执行 clean and package ,将在target\classes下生成 git.json文件,内容如下:


#Generated by Git-Commit-Id-Plugin
git.build.time=2024-02-21T10\:41\:24+0800
git.build.version=0.0.1-SNAPSHOT
git.commit.id.abbrev=3fc9c80
git.commit.id.full=3fc9c8009a48e22ef171c98a97398005e9f30a4a

同时,如果我们反编译生成的jar包,将在BOOT-INF/classes下看到git.json 文件

GitCommitIdMavenPlugin插件有丰富的配置选项,更多配置参考:



<configuration>
    <!--
                    git文件记录,默认是
                    ${project.basedir}/.git
                    如果非默认,可以指定,例如: ${project.basedir}/../.git
                -->
    <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
    <!--
                    属性前缀,可以理解为namespace,默认是git, 例如 `${configured-prefix}.commit.id`.
                   
                    更多信息可以参考 (see
                    https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/137#issuecomment-418144756
                    for a full example).
                -->
    <prefix>git</prefix>
    <!-- @since 2.2.0 -->
    <!--
                    默认的日期格式,使用方式(e.g. `git.commit.time` and `git.build.time`).
                 -->
    <dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat>
    <!-- @since 2.2.0 -->
    <!--
                    时区(java.util.TimeZone.getDefault().getID()).
                    *Note*: 指定时区可以如下 `MAVEN_OPTS=-Duser.timezone=UTC mvn clean package`, `mvn clean package -Duser.timezone=UTC`
                   或者使用 Asia/Shanghai 直接指定,该属性会使用在
                    (e.g. `git.commit.time` and `git.build.time`).
                -->
    <dateFormatTimeZone>${user.timezone}</dateFormatTimeZone>
    <!--
                    默认false,构建时打印信息
                -->
    <verbose>false</verbose>
    <!--
                    默认false, 如果是true, 会生成properties 文件(填充文件中的属性值),文件配置在 generateGitPropertiesFilename 中, 构建时间使用如下
                    ``` git.build.time=${git.build.time}
                    ```
                -->
    <generateGitPropertiesFile>true</generateGitPropertiesFile>
    <!--
                    默认文件
                    ${project.build.outputDirectory}/git.properties
                    该路径可以使用相对于${project.basedir}的相对路径(e.g. target/classes/git.properties),或者全路径(e.g. ${project.build.outputDirectory}/git.properties)
                -->
    <generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
    <!--
                   文件格式,默认properties,可以使用json
如果将其设置为“json”,则还应该签出关于 `commitIdGenerationMode` 而且设置
                    `<commitIdGenerationMode>full</commitIdGenerationMode>`.
                -->
    <format>properties</format>
    <!--
                    默认是true,如果打包是pom(e.g. `<packaging>pom</packaging>`),则运行该插件
                -->
    <skipPoms>true</skipPoms>
    <!-- @since 2.1.4 -->
    <!--
                    告诉maven git commit id将git属性注入到所有reactor项目中,而不仅仅是现在的那个。默认情况下,属性设置为“false”,以防止重写可能与项目无关的属性。如果需要公开git属性对于另一个maven模块(例如maven antrun plugin),您需要将其设置为“true”。
                -->
    <injectAllReactorProjects>false</injectAllReactorProjects>
    <!-- @since 2.0.4 -->
    <!-- 默认false, 指定在找不到.git目录时插件是否应失败。当设置为“false”并且没有找到.git目录时,插件将跳过执行。
                -->
    <failOnNoGitDirectory>true</failOnNoGitDirectory>
    <!-- @since 2.1.5 -->
    <!--
                    默认true,默认情况下,如果插件无法获取足够的数据来完成,跳过执行该插件。
                -->
    <failOnUnableToExtractRepoInfo>true</failOnUnableToExtractRepoInfo>
    <!-- @since 2.1.8 -->
    <!--
                    默认false, 当设置为“true”时,插件执行将完全跳过。这对于配置文件激活的插件调用或使用属性来启用/禁用pom功能。在版本*2.2.3*中,您还可以使用命令行选项跳过插件`-Dmaven.gitcommitid.skip=true`
                -->
    <skip>false</skip>
    <!-- @since 3.0.1 -->
    <!--
                   默认false,当设置为“true”时,插件将不会尝试联系任何远程存储库。任何操作都将只使用回购的本地状态。如果设置为“false”,它将执行“git fetch”操作,例如确定“ahead”和“behind”分支信息。
                -->
    <offline>false</offline>
    <!-- @since 2.1.12 -->
    <!--
默认 false,如果为true,只在一个模块中运行一次。这意味着插件的效果对执行图中的第一个项目执行一次
                -->
    <runOnlyOnce>false</runOnlyOnce>
    <!-- @since 2.1.9 -->
    <!--
                    排除属性                    
                -->
    <excludeProperties>
        <!-- <excludeProperty>git.user.*</excludeProperty> -->
    </excludeProperties>
    <!-- @since 2.1.14 -->
    <!--
                    只包含某类属性,和excludeProperties相对
                -->
    <includeOnlyProperties>
        <!-- <includeOnlyProperty>^git.commit.id.full$</includeOnlyProperty> -->
    </includeOnlyProperties>
    <!-- @since 2.2.3 -->
    <!--
                    属性替换,匹配到规则的属性值在某个阶段替换为另外的属性值
                -->
    <replacementProperties>
        <!--
                      example:
                      apply replacement only to the specific property git.branch and replace '/' with '-'
                      see also [issue 138](https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/138)
                  <replacementProperty>
                    <property>git.branch</property>
                    <propertyOutputSuffix>something</propertyOutputSuffix>
                    <token>^([^\/]*)\/([^\/]*)$</token>
                    <value>$1-$2</value>
                    <regex>true</regex>
                    <forceValueEvaluation>false</forceValueEvaluation>
                    <transformationRules>
                      <transformationRule>
                        <apply>BEFORE</apply>
                        <action>UPPER_CASE</action>
                      </transformationRule>
                      <transformationRule>
                        <apply>AFTER</apply>
                        <action>LOWER_CASE</action>
                      </transformationRule>
                    </transformationRules>
                  </replacementProperty>
                  -->
    </replacementProperties>
    <!-- @since 2.1.10 -->
    <!--
                    默认false,此插件附带自定义的“jgit”实现,用于获取所有相关信息。如果设置为“true”,则此插件将使用本机“git”二进制文件而不是自定义的“jgit”, 也可以使用以下命令开启 `-Dmaven.gitcommitid.nativegit=true`
                -->
    <useNativeGit>false</useNativeGit>
    <!-- @since 3.0.0 -->
    <!--
                    默认情况下,此超时设置为30000(30秒),允许指定使用本机获取信息的超时(毫秒)
                -->
    <nativeGitTimeoutInMs>30000</nativeGitTimeoutInMs>
    <!-- @since v2.0.4 -->
    <!--
默认7,配置缩写git提交id的长度(`git.commit.id.abbrev`)到长度至少为N。`0'具有特殊含义(签出git/git文档描述-描述.md)对于特殊情况,缩写为0)。最大值为“40”,因为最大SHA-1长度。
                 -->
    <abbrevLength>7</abbrevLength>
    <!-- @since v2.2.0 -->
    <!--
                    目前,交换机允许两种不同的选择:1默认情况下,此属性设置为“flat”,并将生成以前已知的财产`git.commit.id`就像以前版本的插件一样。保持默认情况下,它将“flat”保留向后兼容性,不需要进一步的操作最终用户调整。2如果将此开关设置为“full”,则插件将导出以前已知的属性`git.commit.id`作为`git.commit.id.full`因此将生成完全有效的导出机制中的json对象。
                -->
    <commitIdGenerationMode>flat</commitIdGenerationMode>
    <!-- @since 2.1.0 -->
    <!--
                    可以用作非常强大的版本控制助手, 可以参考https://git-scm.com/docs/git-describe
                -->
    <gitDescribe>
        <!--
                        默认false, 如果true,则不使用该配置
                    -->
        <skip>false</skip>
        <!--
                       默认true,
在某些情况下,在提交附近找不到标记(例如,通常在执行浅克隆)。如果将其设置为“true”,并且未找到标记,则此属性将改为回退到提交的id(当“true”时,此属性不会变为空)
                    -->
        <always>true</always>
        <!--
                        在describe输出中,哈希的对象id总是缩写为N个字母(默认为7)
                    -->
        <abbrev>7</abbrev>
        <!--
                        Default (optional):
                        -dirty
                        在处于“脏状态”(未提交)的存储库上运行“描述”时更改),说明输出将包含一个附加后缀
                    -->
        <dirty>-dirty</dirty>
        <!--
                        默认:*,包含所有信息,
Git describe可能包含标记名的信息。将此配置设置为仅考虑与给定模式匹配的标记。这可以用来避免从存储库泄漏私有标记。
                    -->
        <match>*</match>
        <!--
默认false,运行git describe时,默认情况下只查找*带注释的标记*。如果您希望在描述中也考虑*轻量级标记*,则需要把这个转换成'true'。
                        depth here: https://github.com/git-commit-id/git-commit-id-maven-plugin/#git-describe-and-a-small-gotcha-with-tags
                    -->
        <tags>false</tags>
        <!--
默认情况下,如果当前提交被标记,git descripe只返回标记名。将此选项设置为“true”以强制它使用典型的describe格式化输出格式(“${tag name}-${committes_from_tag}-g${commit_id-maybe_dirty}”),即使是“on”标记
                    -->
        <forceLongFormat>false</forceLongFormat>
    </gitDescribe>
    <!-- @since 2.2.2 -->
    <!--
附加的验证实用程序,可用于验证项目属性是否设置
                -->
    <validationProperties>
        <validationProperty>
            <!--
用于识别验证的描述性名称,不匹配(将显示在错误消息中)
                        -->
            <name>validating project version</name>
            <!--
                             需要验证的值*注意*:为了能够验证在pom本身您可能需要设置配置`<injectAllReactorProjects>true</injectAllReactorProjects>`。
                        -->
            <value>${project.version}</value>
            <!--
                            the expected value
                        -->
            <shouldMatchTo><![CDATA[^.*(?<!-SNAPSHOT)$]]></shouldMatchTo>
        </validationProperty>
        <!-- the next validationProperty you would like to validate -->
    </validationProperties>
    <!-- @since 2.2.2 -->
    <!--
                    默认true,如果有与预期不符,则校验失败
                -->
    <validationShouldFailIfNoMatch>true</validationShouldFailIfNoMatch>
    <!-- @since 2.2.4 -->
    <!--默认值(可选):默认情况下,此属性只需设置为“HEAD”,它应该引用最新的在存储库中提交。
说明:
允许告诉插件应该使用什么提交作为生成属性来自。
一般情况下,可以将此属性设置为“HEAD^1”或指向分支或标记名称。为了支持任何类型或用例,也可以设置此配置整个提交哈希或它的缩写版本。
                -->
    <evaluateOnCommit>HEAD</evaluateOnCommit>
    <!-- @since 3.0.0 -->
    <!--
默认true,当设置为“true”时,此插件将尝试使用生成环境中的分支名称。
                -->
           useBranchNameFromBuildEnvironment>true</useBranchNameFromBuildEnvironment>

<!-- @since 3.0.0 -->
<!--
默认true,说明:
当设置为“true”时,此插件将尝试将生成的属性公开到`System.getProperties()`. 设置为{@code'false'}以避免此曝光。 -->
<injectIntoSysProperties>true</injectIntoSysProperties>
</configuration>



查询gitCommitInfo

通过编写一个接口,用来查询生成的GitCommitInfo,核心代码如下:


import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.*;

@Slf4j
@RestController
@RequestMapping("/version")
public class VersionController {

    /**
     * 获取 git.json 中的内容
     * @return
     * @throws IOException
     */
    @GetMapping("/gitCommitId")
    public String getGitCommitId() throws IOException {
        //git.json  or  git.properties
        File file = ResourceUtils.getFile("classpath:git.json");
        if (file.exists()) {
            String s = "";
            InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8");
            BufferedReader br = new BufferedReader(in);
            StringBuffer content = new StringBuffer();
            while ((s = br.readLine()) != null) {
                content = content.append(s);
            }
            return content.toString();
        } else {
            return "";
        }
    }
}

 

与java的兼容性

  • java8:插件版本=4.x
  • java11:插件版本>=5

与maven的兼容性

  • maven3:插件版本=4.x
  • maven3.2.x:插件版本>=7

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK