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

来源:https://www.cnblogs.com/Naylor/p/18024689
-Advertisement-
Play Games

簡介 git-commit-id-maven-plugin 是一個maven 插件,用來在打包的時候將git-commit 信息打進jar中。 這樣做的好處是可以將發佈的某版本和對應的代碼關聯起來,方便查閱和線上項目的維護。至於它的作用,用官方說法,這個功能對於大型分散式項目來說是無價的。 功能 你 ...


簡介

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

引用

郵箱:[email protected] 技術交流QQ群:1158377441 歡迎關註我的微信公眾號【TechnologyRamble】,後續博文將在公眾號首發: pSr8iCD.png
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 集合與映射類型 集合類型(Set Type) 集合類型對象是由具有唯一性的可哈希對象所組成的無序多項集。 由於集合類型是無序的,它並不記錄元素位置或插入順序,因此集合類型不支持索引、切片或其他序列類的操作。 類型 對應關鍵字 構造函數 是否可變 是否可哈希 set set set() 可變 不可哈希 ...
  • friend_function 成員變數和函數的存儲 c++實現了封裝,數據和處理數據的操作(函數)是分開存儲的。 c++中的非靜態數據成員直接內含在類對象中,就像c語言的struct一樣。 成員函數並不會出現在對象中,而是作為類的一部分存儲在代碼段中,需要通過對象或對象指針進行調用。成員函數可以訪 ...
  • 我們一般在底層寫方法時,如果方法顯示throws異常,那麼在調用時,也需要將這個異常throws出來,例如 public RetOps<T> assertCode(Integer expect, Function<? super R<T>, ? extends Exception> func) th ...
  • Solana 開發學習之Solana 基礎知識 Install the Solana CLI 相關鏈接 https://docs.solanalabs.com/cli/install https://solanacookbook.com/zh/getting-started/installation ...
  • 前言 當前,微服務架構在很多公司都已經落地實施了,下麵用一張圖簡要概述下微服務架構設計中常用組件。不能說已經使用微服務好幾年了,結果對微服務架構沒有一個整體的認知,一個只懂搬磚的程式員不是一個好碼農。 流量入口Nginx 在上圖中可以看到,Nginx作為整個架構的流量入口,可以理解為一個外部的網關, ...
  • 之前給大家推薦過一些油管上的免費學習資源,如果您還沒有看過的話可以點擊這裡前往。 今天再給大家推薦一批Udemy上超高質量並且免費的編程課程,有需要的小伙伴可以學起來了。 1. JavaScript Essentials 第一門免費課程是:JavaScript Essentials。顧名思義,本課程 ...
  • 在 Java 中,LocalDateTime、Date 和 Instant 分別代表了不同的日期時間類型,它們之間有一些區別和適用場景。 Date: java.util.Date 是 Java 早期的日期時間類,它包含了日期和時間信息,但是在設計上存在一些問題,因此並不推薦在新的代碼中使用。 Dat ...
  • 序言 在數字時代,圖像生成技術正日益成為人工智慧領域的熱點。 本討論將重點聚焦於兩個備受矚目的模型:DALL-E和其他主流AI繪圖方法。 我們將探討它們的優勢、局限性以及未來的發展方向。通過比較分析,我們期望能夠更全面地瞭解這些技術,為未來的研究和應用提供啟示。 Q: 介紹一下 dall-e Ope ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...