Webhook 通用觸發插件

這篇文章將介紹我在 Jenkins 上遇到的一些常見問題,以及如何通過開發通用 Webhook 觸發插件來解決這些問題。

問題

在使用 Jenkins 工作時,我經常遇到同樣的問題:

  • 程式碼重複和安全性-每個倉庫中的 Jenkinsfiles
  • 分支不是功能-master 上的參數化任務通常會混合與不同功能相關的參數。
  • 記錄不良的觸發器插件-記錄正常服務但記錄不佳的使用插件

程式碼重複和安全性

每個 Git 倉庫中都有 Jenkinsfiles,使開發人員可以使這些文件分開。開發人員 push 他們的項目,並且很難維護共享程式碼的模式。

我幾乎用共享庫解決了程式碼重複問題,但是它不允許我設置必須遵循的嚴格模式。任何開發人員仍然可以決定不調用共享庫提供的功能。

還允許開發人員運行 Jenkinsfiles 中的任何程式碼的安全性方面。例如,開發人員可能會列印從憑據收集的密碼。讓開發人員在 Jenkins 節點上執行任何程式碼對我來說似乎不合適。

分支不是功能

在 Bitbucket 中有項目,每個項目都有 git 倉庫的集合。像這樣:

  • PROJ_1
    • REPO_1
    • REPO_2
  • PROJ_2
    • REPO_3

讓我們考慮一下我們要為這些倉庫提供的一些功能:

  • pull request 驗證
  • 構建快照(如果需要的話,也可以預發布)
  • 構建發布

如果開發人員習慣於在 Bitbucket 中像這樣組織倉庫,我們是否應該在 Jenkins 中以同樣的方式組織它們?而且,如果他們瀏覽 Jenkins,是否不應該為每種功能(例如 pull-requestsnapshotrelease)找到一份構建任務?每個具有僅與該功能相關的參數的任務。我認同!像這樣:

  • / – Jenkins root
    • /PROJ_1/REPO_1 – 一個文件夾,列出與該倉庫相關的任務。
    • /PROJ_1/REPO_1/release – 一份構建任務,執行發布。
    • /PROJ_1/REPO_1/snapshot – 一份構建任務,執行快照發布。
    • /PROJ_1/REPO_1/pull-request – 一份構建任務,驗證 pull-request。
    • /PROJ_1 – 一個文件夾,列出 git 倉庫。

在此示例中,snapshotrelease 任務都可以在同一 git 分支上工作。不同之處在於它們提供的功能。它們的參數可以很好地記錄下來,因為您不必混合與發行版和快照相關的參數。使用多分支流水線插件無法做到這一點,在多分支流水線插件中,您將參數指定為每個分支的 properties

文獻資料

Webhooks 通常在提供它們的服務中有據可查。例如:

  • Bitbucket Cloud
  • Bitbucket Server
  • GitHub
  • GitLab
  • Gogs 和 Gitea
  • Assembla
  • Jira

令我困擾的是,即使我理解了這些 webhooks,我也無法使用它們。因為我需要在所使用的插件中進行開發,以便提供從 Webhook 到構建的任何值。從 PR 到實際發布,該過程可能需要幾個月的時間。這樣簡單的事情實際上應該不是問題。

解決方案

我的解決方案幾乎可以追溯到基本知識:我們有一個自動化服務(Jenkins),我們想在外部 Webhooks 上觸發它。我們想從該 Webhook 收集資訊並將其提供給我們的構建。為了支援它,我創建了通用 Webhook 觸發器插件。

倉庫中提供了最新文檔,並且有一個完整的示例,其中使用 configuration-as-code 實現了 GitLab。在這裡查看倉庫。

程式碼重複和安全性

我制定了所有開發人員都必須遵循的約定。而不是讓開發人員從 Jenkinsfiles 顯式調用基礎結構。遵循一些規則,例如:

  • 所有的 git 倉庫都應該從倉庫的根開始構建。
  • 如果包含 gradlew
    • 使用 ./gradlew build 完成構建
    • 使用 ./gradlew release 完成發布
    • ……等等
  • 如果包含 package.json
    • 使用 npm run build 完成構建
    • 使用 npm run release 完成發布
    • ……等等

有了這些規則,流水線就可以完全通用,並且在倉庫中不需要 Jenkinsfiles。由於某些原因,某些 git 倉庫可能需要禁用測試用例。這可以通過允許倉庫添加一個特殊文件,也就是 jenkins-settings.json 來解決,讓基礎架構發現其內容並對其採取行動。

即使沒有執行 CI,這也可以幫助開發人員。當他們克隆一個新的,未知的倉庫時,他們將知道可以發出哪些命令及其語義。

分支不是功能

我實現:

  • Jenkins 任務配置-使用任務 DSL。
  • Jenkins 的構建過程-使用 Pipelines 和共享庫。

通過與 Job DSL 中的 git 服務集成,我可以自動找到 git 倉庫。我創建動態組織在文件夾中的任務。還調用 git 服務來設置觸發這些任務的 webhooks。任務是普通的流水線,不是多分支,它們不使用 Git 中的 Jenkinsfile,而是使用 Job DSL 在任務中配置的 Jenksinfile。因此,所有任務配置和流水線均受版本控制。這一切都在這裡發生。

文獻資料

該插件使用 JSONPath 以及 XPath 從 JSON 提取值並將其提供給構建。讓用戶從 webhook 中選擇所需的內容。它還具有一個正則表達式過濾器,以允許在某些情況下不觸發。

該插件不是很大,只是 webhook、JSONPath/XPath 和正則表達式之間的粘合劑。所有這些部分都已被很好地記錄下來,我會儘力維護該插件。這是一個非常有據可查的解決方案!