簡體   English   中英

如何將確定性的唯一 buildId 注入 Gradle 的 java jar 清單?

[英]How to inject a deterministic unique buildId into Gradle's java jar manifest?

我們有一個存儲在磁盤上的計算數據緩存。 我們想知道計算出的數據是來自這個版本還是來自不同版本的構建。 目前,我們使用存儲在 MANIFEST.MF 中的提交 + 時間戳作為識別構建的相對獨特的方式。 然而,時間戳會導致 gradle 中的增量構建問題,因為 gradle 知道時間已經改變,重新生成 MANIFEST.MF,並重新 jars jar,即使沒有其他任何變化。

我們希望將時間戳替換為更好的“buildId”到 MANIFEST.MF 中。 要求是:

  • 不同構建的唯一性:單獨提交是不夠的,因為在開發機器上可能有未提交的更改
  • 確定性:時間戳不起作用,因為 Gradle 會將其視為依賴項中的“更改”,即使其他依賴項未更改,也會重建 jar

我認為正確的解決方案是使用“jar”任務的實際依賴項的哈希值,即“classes”,它是將包含在 jar 中的所有已編譯類文件。

理論上,我可以創建一個任務,該任務獲取所有類的散列,並將其注入清單。

但是,Gradle 已經這樣做了,這就是它確定任務是否是最新的方式。 它獲取輸入的哈希值和輸出的哈希值,並檢查該組合是否在其數據庫中。 那么,有沒有辦法使用一些罕見的 Gradle API 或使用反射來訪問這些信息?

或者也許還有其他解決方案?

我認為您可能想退后一步,重新評估您希望通過添加到清單文件中的 buildIds 實現的目標。 具體來說,您所說的關於在開發機器上構建的第一個要求沒有多大意義。 您通常希望向清單文件添加某種 buildId 的原因是,您可以跟蹤構建 jar 的位置和時間,以便您可以確定要使用的源代碼集,並在出現問題時查看。 如果您根據開發人員的文件系統的內容生成構建,您將永遠無法返回並確定該構建的來源。 如果 buildId 是基於生成的類文件,甚至是開發人員機器上的源文件本身,那么開發人員所要做的就是更改單個文件中的單個字符,並且該構建將永遠消失並且無法重新生成除非該開發人員可以執行撤消操作,使文件系統恢復到原來的形狀。

相反,您應該將 buildId 建立在無需開發人員記住任何內容即可重新創建的內容上。 為了實現這一點,buildId 需要隨時可供團隊的所有成員搜索和隨時使用。 修訂控制提交滿足所有這些要求,而且聽上去是您已經使用的東西,因此沒有額外的開銷將其添加到您的工作流程中。

我建議忘記將 buildId 建立在文件系統的內容上,而是將其建立在提交上。 如果您擔心開發人員能夠生成不是來自 master/trunk/etc 的構建,所有主要的修訂控制系統都提供了一些創建分支的方法,這仍然允許開發人員簽入不會干擾的代碼初級生產構建。 如果您使用修訂號/哈希來跟蹤 jar 的版本,那么您就可以返回並准確地重現構建,即使它只是來自開發人員機器上的本地分支。 我不建議使用本地分支的最后一點,除非您知道構建將非常短暫,但是,因為團隊中的任何其他人都無法搜索基於單個開發機器本地分支的 buildId。 相反,如果您使用的是分布式版本控制系統,我建議您將構建中使用的任何更改推送到中央位置,以便其他任何可能對構建進行故障排除的人都可以訪問用於它的代碼。

您可以創建一個任務來生成構建 id 並使用類作為輸入,輸出是一個帶有構建 id 的文件。

構建 ID 不必是輸入的哈希值,而可以只是一個時間戳。

但是,由於生成構建 ID 的任務取決於類,因此它只會在發生更改時重新生成構建 ID 時間戳。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM