簡體   English   中英

如何使Jenkins認為Maven -SNAPSHOT jar工件的兩個不同版本與連續交付的一部分相同?

[英]How to make Jenkins consider two different builds of a Maven -SNAPSHOT jar artifact identical as part of Continuous Delivery?

編輯:這是關於與Maven進行持續交付並與Jenkins進行協調。 Maven絕對不是為此設計的,這個問題是我們在不使用Maven發行版的情況下獲得高效工作流程的一部分工作。 感謝幫助。


我們在主要版本中使用Maven -SNAPSHOT,以確保客戶始終獲得該給定版本的最新代碼,並且效果很好。 由於技術原因,我們有兩個獨立的Maven作業-一個用於將源編譯為jar,另一個用於將適當的jar組合到給定部署中。 這也很好。

然后,我們讓Jenkins編排何時調用各個步驟的步驟,這在這里有些棘手,因為如果我們在第一步中執行常規的mvn clean install ,則意味着所有快照構件都將重新編譯,這反過來又使Jenkins認為所有的快照改變 (如指紋他們-又名MD5校驗-改變),即使源用於產生偽影並沒有改變,觸發所有下游構建,而不僅僅是那些依賴關系沒有改變。

到目前為止,我發現這些問題在不同版本之間有所不同:

  • META-INF / maven /.../ pom.properties(因為它包含時間戳記)
  • META-INF / MANIFEST.MF(包含JDK和用戶)
  • jar文件中的時間戳

我已經找到了解決前兩種方法的方法,但是后者要困難一些。 似乎沒有編寫AbstractZipArchiver(在zipFile()和zipDir()中完成所有工作)來允許對生成存檔的方式進行任何形式的擴展。

現在,我可以想象四種方法(但是歡迎更多想法):

  • 創建當前maven-jar-plugin實現的派生類,允許使用timestamp=<number>屬性,然后將其用於插入jar文件的所有條目。 如果未設置,則保留當前行為。
  • 修改Jenkins指紋識別方案,使其了解jar文件,並且僅查看條目內容,而不查看其元數據。
  • 將插件附加到prepare-package階段,該階段負責用特定時間戳touch文件。 這要求當時所有文件都存在(這意味着不允許jar插件接觸MANIFEST.MF文件)
  • 將一個額外的插件附加到“打包”階段,該階段將重寫完成的jar文件,從而使該過程中的所有zip輸入時間戳歸零。

同樣,目標是使Maven SNAPSHOT工件完全獨立於時間,因此,在給定相同源的情況下,您將獲得具有相同MD5校驗和的工件。 但是,我也相信,這對於發行版本可能是有益的。

我應該如何處理?

根據我的評論,我仍然認為答案是不執行您建議的任何操作,而是優先使用發行版而不是快照來存儲實際上要發布給客戶的工件。

您描述的問題是:

  • 您有一個多模塊項目,由於您有100多個模塊,因此構建時間很長,
  • 您有兩個快照工件,您認為它們應該是相同的(因為源代碼和元數據在構建時是相同的),但是它們具有不同的校驗和。

我對Maven的經驗告訴我,如果您嘗試遵循“ Maven Way”,那么開箱即用的工具將很適合您,但是如果您偏離了范圍,那么您將很難過。 不幸的是,Maven Way有時難以捉摸:-)

當您擁有不同系列的代碼時,Maven中的多模塊項目非常有用,例如,您有一個包含一堆接口的模塊,以及一些提供實現的兄弟模塊。 在一個多模塊項目中有十幾個模塊是不尋常的。 所有模塊都應該共享父級的版本號(Maven不執行此操作,我認為這令人困惑)。

當您構建多模塊項目的快照版本時,即使未更改特定模塊中的代碼,也會構建所有模塊的快照。 因此,您可以查看存儲庫中的一系列模塊,並知道在編譯時滿足模塊間代碼引用。

例如,在域模型模塊中,您可能具有一個接口:

public interface Student {
    void study();
}

在某些同級模塊中,它們可能會在其POM中聲明對域模型的編譯作用域依賴性,因此您可能會有實現。

如果要在域模型模塊中更改接口,請執行以下操作:

public interface Student {
    void study();
    void drink(Beer beer);
}

然后重新構建多模塊項目,構建將失敗。 即使依賴模塊的代碼和POM保持不變,也將無法構建。 在多模塊項目中,只有在所有子模塊都成功構建后才能安裝或部署工件,因此重建快照通常是非常可取的-它告訴您有關模塊間依賴關系的信息。

如果:

  • 您的模塊數量過多,和/或
  • 這些模塊不能合理地共享相同的版本號,和/或
  • 您不需要保證模塊之間的代碼引用,

那么您的模塊化是不正確的。 不要將多模塊項目用作構建系統(為此使用Jenkins),而應使用它來表達代碼模塊之間的關系。

在您的評論中,您說:

當由詹金斯(Jenkins)重建時,RELEASE工件的行為方式相同。

釋放文物點的一點是,你不要重建他們-他們是明確的! 如果使用Artifactory之類的工具,您將發現不能多次部署發布工件-如果嘗試,Jenkins作業將失敗。

這是Maven的基本原則。 Maven的目標之一是,如果在不同工作站上的兩名開發人員嘗試相同的發行版,他們將構建功能相同的工件。 如果要構建一個工件,該工件表達對另一個工件的依賴關系(可能是出於編譯目的,或者因為它已被組裝為.war等),則:

  • 如果依賴項是快照,則Maven可能會從存儲庫中尋求較新的版本。
  • 如果依賴項是發行版,則假定本地存儲庫中的版本是確定的。

如果您可以重建發布工件,則可能會導致兩個開發人員在其存儲庫中使用不同版本的情況,並且根據所使用的工作站,您將擁有不同的版本。 不要這樣

另一個關鍵細節是,發布工件不能依賴快照工件,同樣,您將失去各種保證。

版本是確定的,聽起來您希望程序集依賴確定的工件。 Jenkins使標記和發布多模塊項目非常簡單。

綜上所述:

  • 檢查您的模塊化:一個巨大的多模塊項目沒有用。
  • 如果您不想持續重建快照,則需要發布。
  • 切勿向客戶發布快照。
    • 遵循組裝項目的依賴關系圖並釋放所有快照。
    • 釋放裝配項目,增加次要版本。
    • 確保您的客戶在通訊中引用組件的完整版本號。

暫無
暫無

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

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