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