OpenStack是如何做到在三個月內合并900個文檔修改的?我們對待文檔就像對待代碼一樣,并且持續公布了來自多個Git倉庫的評估內容。
通常持續集成(CI)意味著代碼被不斷地測試,與其他的代碼修改進行整合與合并。持續交付(CD)則意味著不斷將帶有補丁的代碼部署到整個代碼庫中。在文檔案例中,這意味著內容被不斷地測試,不斷合并每個補丁,并進行部署。對于文檔來說,部署就意味著發布。部署文檔意味著輸出文件被拷貝到了Web服務器上供所有人查閱。
針對文檔的CI/CD對包括文檔倉庫在內的任何OpenStack倉庫的修改,只能夠通過Gerrit代碼評估系統完成。Gerrit是一款由OpenStack基礎設施團隊運行、基于Web的評估工具,我們可以在代碼協作和評估中使用它們。其基本的工作流是,文檔捐獻者檢查文檔倉庫,修改文檔,在本地測試它們,將其提交給git——我們的源控制版本系統,然后將它們上傳到OpenStack的Gerrit實例中。
Gerrit隨后發布通知,告之為軟件開發提供持續性集成服務的Jenkins有了新的修改。一旦Gerrit發布了通知,Jenkins將運行多種針對倉庫配置的測試套件。實際上,OpenStack并行運行著8個Jenkins實例,通過自產的名為Zuul的工具進行協調。在Zuul 網站上,用戶可以查看所有指定版本的狀態。
只要修改被上傳到Gerrit上,評估者就可以看到修改,并且對它們進行評論。Gerrit 的Web用戶接口允許對修改進行逐行評估。因此,評估者能夠對源文件中的任何問題進行直接評論。我們還會對構建文檔展開測試,評估者可以適時地查看在HTML或PDF中構建的文檔。一旦評估者對修改進行了評論,她還可以對修改進行投票。這里的投票并不是一個民主程序,它們更多的是用于評價補丁是否應該被采用。評估者可以投支持票(即應該被采用)或者是反對票(這需要做更多的工作),也可以僅發表評論,放棄投票。
每個人都可以通過這些投票在OpenStack的Gerrit中進行評估:
0:不計分;
+1:在我看來這很好,但是還需要其他人批準;
-1:在被合并之前這些補丁需要進一步完善;
我們還需要對補丁進行評論,闡明它們為什么是錯誤的,一些問題需要被澄清,或者是說明它們為什么很好。這些評論可以幫助原作者或其他評估者更新和評估這些修改。
高級評估者,即“核心評估者”(core reviewers)能夠給予分值為2分的投票并批準修改,讓該修改能夠被發布。這些評估分值的含義是:
+2:在我看來(核心評估者)這很好。
-2:不能合并。
一旦兩名核心評估者給了+2(一名核心評估者贊同該修改,通常第二名核心評估者也給了+2)那么它們就會被并入和被發布。帶有負評論的修改是不會被批準的,在意見達成一致并通過批準后文檔才能被發布。
在評估階段,Jenkins的自動檢測也會進行一個投票。一旦修改被批準,Jenkins會再次對并入當前升級后的git倉庫的修改進行檢測,以確保不會產生倒退。如果Jenkins對修改的評價是肯定的,那么修改僅僅是被并入。
這些自動化修改是在惠普和Rackspace的公有云上進行的。OpenStack項目目前可使用950臺虛擬機展開測試工作。每一項測試工作都會啟動一臺機器,所有與測試套件有關的東西都會被安裝,然后測試套件會展開測試。是的,我們正在使用云來測試關于云的文檔。
使用文檔CI/CD會帶來哪些好處?OpenStack每天都會將多個項目與多個修改進行合并,因此文檔系統也需要能夠跟上修改的步伐。持續集成與交付使得它成為了可能。這不僅是一個優勢,也是我們環境所提出的需求。編寫者的工作流與開發者的工作流相同,他們也得到了與提供捐獻的開發者一樣的認可與獎勵。
我們還發現,盡管捐獻者仍然需要能夠在本地構建文檔,但是它們正在讓構建文檔遠離本地編寫者的環境。通過讓已經建立的草稿做好評估準備,臨時捐獻者和評估者可以避免過度下載補丁,過度復制構建環境,以及過度創建文檔。我們之所以能夠評估源和輸出,應該感謝系統的自動化。
由于在基于云的CI/CD持續運行的同時,編寫者能夠迅速致力于多個補丁,因此構建速度得到了提升。在OpenStack中,基礎設施團隊也使用了許多針對服務器管理的技術。
草稿文檔的創建和發布允許評估者在文檔被發布時快速檢查修改是如何被呈現出來的。他們不需要下載和在本地創建就能夠快速地進行評估。
我們還使用了OpenStack開發者和基礎設施團隊所使用的工作流。對于開發者來說,他們可以更輕松地捐獻文檔。隨著我們近期開始轉而將RST作為格式,由于RST在OpenStack中已成為了標記語言,這些都變得更加容易了。
自動化中的風險與陷阱考慮到編寫既是一門技術也是一門藝術,我們一直在嘗試著在自動化和手動之間實現一種平衡。一個早期的擔憂是發布過快,或是發布不完整的文檔。我們發現只要評估者采取的指導方針是“它們比我們現在的好”,“我對它們進行了測試,并知道它們是如何工作的”,或是“這個文檔解決了我調查過的已經被上報的漏洞”,那么一天發布50至100次更新所隱藏的風險將會出現下降。
我們必須要在評估者中建立起信任,在每六個月召開一次的OpenStack Summit上,我們還將會展開現場討論。我們已經編寫了評估指南,并嘗試著對評估者展開培訓,讓他們在評估補丁包時擁有最佳的判斷力。
為此我們還縮寫了一套評估指導。持續集成不僅是我們快速發布的一部分,也在促進值得信任的評估者展開最公正的評估。與此同時,讓機器人進行測試評估會讓他們相信自己不必擔心文檔無法被創建,或者是我們破壞了整個文檔站點。
文檔測試Jenkins允許執行腳本,文檔團隊擁有自己的測試腳本的倉庫。這些測試腳本多數都是由Python編寫的。我們使用與文檔相同的工作流開發這些腳本。一旦進行了重大修改,我們就會編寫一個測試工具版本,隨后這個版本就會被用于測試所有的文檔修改。在文檔倉庫中,我們會使用一個測試所需的.TXT文件,這個文件會顯示哪些openstack-文檔-工具的版本能夠與給定的系列源文件協同工作。
為了讓評估者能夠將關注點聚焦在內容上,而不是格式上,自動測試為我們處理了大部分挑錯的工作。為了發布文檔,我們不需要通過所有的自動測試。一些測試只是用于“投票”,這意味著文檔不會進行合并,除非它們通過了所有的這些測試。部分測試是用于“非投票”,這意味著即便測試失敗,我們也會允許發布補丁。
我們還對測試腳本進行了一些優化。例如,由于DocBook XML文件創建非常昂貴,一個小型的獨立創建器可以用于檢測哪些文件經過了修改,哪些指南中包括了這些文件,隨后只有指南將被創建。如語法或URL檢測等其他測試僅運行于經修改的文件。沒有必要對那些沒有經過修改的文件進行反復檢測,測試單個文件可能會非常快,而測試上千個XML文件的速度就很慢了。
這些優化沒有用于RST文件,因為RST文件非常容易分析,指南的創建也更為迅速。由于核對投票需要非常精準,因此我們也沒運行語法和拼字檢查器。我們已經就自動化拼寫展開了充分討論,不過這實際上還是需要人通過肉眼進行判斷。
CI基礎設施的其他用途我們會使用它們與我們的翻譯服務器對話。翻譯團隊會使用Transifex翻譯服務器翻譯說明。只要修改被并入,那么CI基礎設施就會自動將當前文本上傳至翻譯服務器,翻譯者可以直接對它們進行翻譯。每天CI基礎設施會從翻譯服務器定期下載所有的翻譯好的內容到文檔倉庫。隨后新的內容會作為修改被提出來。
此外,我們還使用CI基礎設施將來自一個倉庫的共享文件同步至其他倉庫中。這些文件是我們與其他翻譯共享的詞匯表和“支持附件”。在修改被并入到這些文件的主倉庫中,它們會檢測其他倉庫中的文件是否需要升級;如果需要,那么相關修改會被提出。這一過程允許在導入和最終的人工評估中運行測試工作套件。
結語本文有助于我們理解如何在OpenStack文檔處理流程中使用持續集成與持續交付。在這種方法中,我們會找到比風險更具價值的優勢。在關注開源文檔的同時關注自動化,看看哪些會讓你突然感到眼前一亮吧!