Bamboo 開發工程師
代碼為王
就如同DevOps 工程師喜歡Jenkins 一樣,近些年,我幾乎很少聽到有開發工程師會熱衷於除了GitHub Actions 或者GitLab CI 以外的自動化工具。
一方面,像代碼一樣管理CI/CD 對於開發工程師來說更舒適,另一方面,使用代碼倉庫平臺本身的CI/CD 會使開發工程師的工作體驗更優雅,界面也毫無割裂感。在他們心中,代碼才是王道,畢竟“Talk is cheap. Show me the code“ 是刻在基因裡的。
雖然Jenkins 的Jenkinsfile 也支持像代碼一樣管理流水線,但始終不能入開發工程師的法眼。Bamboo 也會面臨一樣的境遇,因此,Bamboo 上的構建流水線大概率是由DevOps 工程師來運作,這主要看團隊文化。
CI/CD 工具除非界面操作足夠簡潔,通過下拉菜單勾選就能夠完成配置,否則很難說服開發工程師使用,更何況Bamboo 對權限還進行了管控,雖然這對企業是一件意義非凡的事,但對於開發工程師來說就是噩夢。
不管現實中由誰來負責配置開發任務的流水線,在本文中,我們把它整理到開發工程師的段落中來。
構建任務的設計
代碼克隆
代碼克隆是原生自帶的任務類型,一般在新建Bamboo 計劃的時候,就可以對其進行配置了。項目中若已經事先關聯好代碼倉庫,那麼只需要通過下拉菜單選擇倉庫名就可以了。
![](../__attachments/337379526/image-20220729-051830.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
不過,要注意,我接觸的很多CI/CD 平台,默認都是不開啟git 的submodule 功能的,所以使用submodule 的團隊,需要告訴你的Bamboo 管理員。
單元測試
克隆之後,一般都會從單元測試開始。由於我們期望每個任務環境足夠獨立,所以不同的階段(Stage) 都是在各自容器中執行,而每個階段裡面只包含一個任務好讓它獨占容器環境。
需要了解的是,Bamboo 本身並不一定具備這些單元測試框架,雖然你能夠在任務類型中看到很多熟悉的名稱。
![](../__attachments/337379526/image-20220729-054855.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
一部分單元測試類型的截圖
但實際上,這都需要係統管理員提前準備好代理,或者像我們使用的方案一樣,將其置於對應的開發語言容器環境中。這樣,即使不同任務需要使用不同版本的依賴也不用擔心衝突,更不用擔心環境中多餘的軟件包和配置,任務環境足夠純粹。
![](../__attachments/337379526/image-20220729-062118.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
編譯
如果代碼需要編譯,那這一步是必不可少的。當然,如果最終我們需要構建成容器鏡像,也可以直接使用多階段構建一步到位。這取決於中間我們是否要做一些更細緻的測試,比如靜態代碼掃描。
雖然理論上來說,代碼相同的情況下,兩次編譯的結果應該相同,但一來沒有必要編譯兩次,二來雖然看起來一樣,但實際你永遠無法踏進同一條河流。
所以,為編譯工作單獨設計一個任務,並且保留編譯製品,是比較明智的做法。
對於編譯任務,Bamboo 提供了一些內置的任務模板,使用起來不算優雅,但還算方便。
![](../__attachments/337379526/image-20220729-054700.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
一部分構建類型的截圖
代碼掃描
代碼掃描的工具也不少,靜態代碼掃描工具SonarQube 還是值得接入的。我接觸過不少開發工程師利用了它,實實在在地提升了自己的代碼質量。
![](../__attachments/337379526/image-20220729-055305.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
鏡像構建
如果我們最終以容器鏡像的形式作為交付物,Bamboo 內置的Docker 任務模板會讓體驗更友好一些。
原本Docker 任務大可不必另啟一個容器環境,但我們的設計是所有任務均在各自的容器環境中執行,這使得任務的工作目錄需要通過掛載卷的方式傳遞到不同的容器中,以保證不同階段任務的連續性。
這其實與Bamboo 對階段的設計不太吻合,Bamboo 期望不同的階段完全解偶,所以如果以默認方式配置一個階段,你會發現每個階段都會要求做一次代碼克隆。這在多人協作的場景下,容易發生一些不必要的衝突。
比如,流水線正在執行的時候,代碼有新的提交,這條流水線如果在不同階段使用不同的代碼,其最終結果,可能會造成工程師們的誤判。
但Docker 任務存在其特殊性,工具人學堂的顧問都是自己定制的任務容器鏡像來執行該系列任務。
![](../__attachments/337379526/image-20220729-061916.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
而我們依舊利用Bamboo 自帶的Docker 任務類型來完成其餘的工作,效果更好。
![](../__attachments/337379526/image-20220729-061954.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
觸發規則
代碼提交
代碼提交時觸發構建任務自動執行,是最基礎的場景之一,幾乎每個團隊都需要這樣的場景。
在Atlassian 生態中,BitBucket 和Bamboo 是天然集成的,所以這個場景的觸發策略會默認開啟。其他的代碼倉庫平台就需要手動配置網勾,或者輪詢。
![](../__attachments/337379526/image-20220729-063012.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
請求代碼合併
在標準的代碼分支管理中,有個很重要的行為就是”請求代碼合併” (Pull Request / Merge Request)。
這象徵著代碼經過了開發工程師的自測,有了一定質量把握,從而請求合併到公共分支。
基於這一信號,觸發構建自動化任務,對於一些公用的構建流水線任務,將更為合理。
不過,Bamboo 並沒有這種觸發規則,雖然我們可以在流水線中設置判斷條件來達到這種效果,但它不如觸發規則上的體驗優雅。當然,不管是哪種方式,都需要軟件研發團隊科學的做好代碼分支管理,讓重要的分支只允許請求代碼合併,從而更好的利用流水線的執行結果。
測試報告
單元測試
Bamboo 對於單元測試也做了一些定制化設計,只要流水線結果中包含單元測試的結果,就會顯示在獨立的測試標籤頁中。
我們且不論僅這樣列表展示是否科學,但它至少提供了一個查看測試報告的入口。
![](../__attachments/337379526/image-20220729-085020.png?inst-v=aaeeaf4e-ecea-4ee7-a3fe-a3b12ffc3fbc)
代碼掃描
如果執行了代碼掃描任務,通常情況下是不會有報告的。
比如SonarQube 就是需要訪問SonarQube 服務器查看掃描報告的,所以你必須對這些任務加以定制,讓團隊以方便的方式查看詳情。