簡介 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
引用
- https://search.maven.org/artifact/io.github.git-commit-id/git-commit-id-maven-plugin
- https://github.com/git-commit-id/git-commit-id-maven-plugin