開始學習持續集成所要了解的知識:分支策略,測試自動化,工具和最佳實踐。git
持續集成的目的是將代碼傳遞到存儲庫的主分支:github
持續集成有點關於工具以及團隊中的思惟方式和文化。你但願在開發的過程當中可以保持主分支的同時快速集成新代碼。此工做主分支將在以後啓用持續交付或持續部署(的操做)。可是,這些不是本文的內容。讓咱們先來關注下持續集成。後端
實現持續集成有兩大支柱。緩存
想象一下,一個五人組成的團隊致力於一個SaaS產品。每一個人都開發一個單獨的新功能。每一個功能的工做量大約是1或2周。有兩種方式能夠實現這個目標。安全
"功能分支"
上工做。一旦每一個人對本身的工做感到滿意,此分支將被被合併到主分支。你認爲哪一種方法效果最好?服務器
第一種方法最終將致使**「不可預測的釋放綜合症」**。長時效的特徵分支爲每一個開發人員創造了一種虛假的安全感和溫馨感。因爲分支分離了很長一段時間,沒辦法衡量將它們合併(到主分支)的難度。其最好的狀況是出現些少的代碼衝突,在最壞的狀況下,基本的設計假設將受到挑戰,事情將不得不從新進行...這是艱難的方式。架構
返工的工做將在時間壓力下進行,致使質量降低和技術債務積累。這是個惡性循環。併發
請參考關於爲什麼不該該使用特性分支來處理髒細節的文章。工具
第二種方法是咱們實現持續集成所須要的方法。每一個開發人員都在本身的分支上工做。差別是:佈局
每次推送都會將其更改合併到主分支,每一個開發人員天天會將其分支與最新的主分支版本同步幾回。
經過這種方式,團隊能夠更快且輕鬆地修復衝突並協調設計假想。**早期發現五個小問題比發佈日前發現1個大問題更好。**查看下面的「功能切換」
部分,瞭解如何將「正在進行的工做」集成到主分支。
以前的軟件開發工程基於構建週期,而後是測試周期。這可能仍然適用「特徵分支」方法(法一)。若是咱們天天數十次集成和合並代碼,那麼,手動測試就沒有意義了。這將花費太長的時間。咱們須要自動檢查以驗證代碼是否正常工做。咱們須要一個CI工具,幫助開發人員自動推送並運行構建和測試。
測試類型和內容應該爲:
不幸的是,沒有一種方式適合全部測試類型和內容。這要根據你的項目適當平衡。在CI階段,不要運行大而耗時的測試套件。雖然這些測試提供了更好的安全性,但它們的代價就是對開發人員的延遲反饋。這將致使上下文工做切換,純粹就是浪費時間。
長時間CI檢查,個人意思是超過3分鐘的(CI),消耗團隊中的每一個開發人員的大量時間。
讓咱們來比較下「好」和」壞「的工做流程
。「好」的工做流程:
「壞」的工做流程:
這糟糕的工做流程不只僅是浪費時間。對開發人員來講也是使人沮喪的。高效的開發會使得開發人員很開心的。
你須要調整工具和工做流程以保證開發人員的滿意度。
持續集成是指未來自不一樣開發人員分支的代碼集成到配置管理系中的公共分支。有可能你正在使用git。在git中,存儲庫中的默認主分支稱爲"master"
。一些團隊建立了一個名爲"develop"
的分支做爲(開發時)持續集成的主分支。他們使用"master"
來跟蹤交付和部署(develop分支將合併到master分支)。
你(的項目中)可能已經有了一個主分支,你的團隊將代碼推送或合併到那裏。堅持(這樣作)下去。
每一個開發人員都應該在本身的分支上工做。若是同時處理許多不一樣的功能內容,可使用多個分支。雖然這多是"不專心"
工做的標誌。只要代碼連貫部分準備就緒,就能夠推送到你的存儲庫。若是成功,CI將檢查、啓動並將代碼合併到主分支。若是檢查失敗,您仍然在本身的分支上,能夠修復須要的任何內容並再次推送。
上述過程當中的關鍵語是你代碼連貫的部分。那麼,你怎麼知道它是連貫的?簡單。
若是你可以輕鬆地想出一個好的提交信息,那就是連貫的。
另外一方面,若是你提交的信息須要分三次且帶有許多形容詞或副詞,那可能並很差。屢次拆分你的工做內容,連貫的提交,而後推送代碼。連貫的提交有助於代碼的審查,且能讓倉庫的歷史記錄更容易被遵循。
不要亂推送任何東西,由於這(有可能)意味着一天的結束!
pull request (拉取請求)
是什麼呢?拉取請求是種概念,其要求團隊將你的分支合併到主分支。接受你的請求應該經過你的CI工具提供的狀態和潛在代碼審查。最終由負責合併拉取請求
的人手動合併。
拉取請求誕生於開源項目中。維護者須要一種結構化的方式來評估合併以前的貢獻。拉取請求並非Git
的一部分。他們受到任何Git提供程序的支持(GitHub, BitBucket, GitLab, ...)。
請注意,在持續集成中,拉取請求並非必須的。而拉取請求的主要好處是支持代碼審查過程,這過程沒法經過設計自動化。
若是你正在使用拉取請求,適用(下面)相同的原則或(上面提到的)「分塊工做」和「優化開發者時間」:
持續過程的核心是自動檢查。它們確保在合併代碼後,主分支代碼能正常工做。若是它們失敗,則代碼不會合並。至少代碼應該編譯或轉換,或者你的技術堆棧應該作點什麼以使其爲運行時作好準備。
在編譯之上,你應該運行自動化測試以確保軟件正常工做。測試覆蓋率越高,在將新代碼合併到主分支時你就越有信心。注意了!更好的覆蓋率意味着更多測試和更長的執行時間。你須要找到正確的權衡。
當你徹底沒有測試或者須要減小一些長時間運行的測試時,你要從哪裏開始呢?專一於你項目或產品的相當重要的事項。
若是你要構建一個SaaS應用,則應該檢查用戶是否能夠註冊或登陸,以及執行SaaS提供的最基本操縱。除非你正在開發Salesforce競爭產品,不然你應該可以在幾分鐘內運行測試,若是不是立刻運行。若是要構建繁重的數據處理後端:使用有限的數據集來運行不一樣的構建塊。在持續集成中保持大型數據集的長時間運行。合併代碼以後,能夠觸發長時間運行的測試。
持續集成的關鍵概念是儘快將代碼放在主分支中,甚至工做正在進行中。若是功能不徹底正常,或者你不但願暴露給測試的人員或終端用戶。實現這一目標的方法就是功能切換。在啓用/禁止
切換下啓用新功能。這切換能夠是編譯時布爾標誌,環境變量或運行時事物。正確的方法取決於你想要 實現的目標。
功能切換的第一個主要好處是,你能夠根據需求將它們投入生產並啓用/禁止
新功能。你可使用更改的環境變量來從新啓動服務器,或者切換打開/關閉
一個新的UI儀表盤的佈局。經過這種方式,你能夠靈活地推出功能。若是在線上中致使意外問題,請將其禁用。或容許終端用戶選擇加入或退出該功能(使用UI切換)。
功能切換的第二個主要好處是它們會強制你考慮你正在執行的操縱與現有代碼之間的界限。這是一個好的練習,如論什麼時候,每次添加到現有系統時,都應該從這裏開始。功能切換步驟使得該過程的這一步更加明顯。
功能切換的惟一缺點是你須要按期從環境和代碼中清除它們。一旦功能通過實測並被用戶採用,它應該是默認(成功的)。應該清理切換的代碼和舊版本的東西(若是有的話)。不要陷入「配置爲切換」
系統的陷阱。你沒法維護和測試切換的全部組合,(帶來的缺點是)你最終擁有一個脆弱的架構。
謹記本文中的「好」和「壞」工做流程
。咱們但願避免開發人員的上下文切換工做(的狀況)。拿起你的手機,並開啓3分鐘的計時器。看看你等待構建完的時間有多長!3分鐘應該是個絕對最大值,你能夠集中精力並安全有效地從一個任務移動到另外一個任務。
對一些團隊來講,3分鐘內的構建可能看起來很瘋狂,但這絕對能夠實現的。它和你組織工做的方式有關,而不是你使用的工具。優化構建的方法有:
強制縮短期來限制你的CI檢查的好處在於它使你從根本上改善整個開發過程。
正如Jim Rohn所說:
「成爲一個百萬富翁,不是爲了百萬美圓,而是爲了實現這一目標會讓你很成功」
大多數持續集成工具在你的分支上運行CI構建,以確保它是否能夠合併。可是這不是咱們感興趣的內容。若是你知道本身在作什麼,那麼你推送的代碼已經頗有可能生效了。你的CI工具應該驗證的是你的分支和主分支合併正常。
你的CI工具應該執行分支到主分支的本地合併,並針對該分支來運行構建和測試。若是主分支在此期間沒有變化,則能夠自動合併你的分支。若是確實發生了更改,則應該再次運行CI檢查,直到你的代碼能夠安全合併爲止。若是你的CI工具不支持此類工做流程,請換一個工具。
有種誤解是,可以跟蹤Agile板或像JIRA之類的bug跟蹤器中相關的代碼是件很酷的(事情)。這是一個很好的教科書概念,可是對開發的過程的影響確定不值得付出努力。任務管理器提供了「功能和錯誤」
的視圖。代碼以很是不一樣的方式構建和分層。嘗試協調任務管理器中的項目和一組提交是沒有意義的。若是你想知道爲何編寫一段代碼,你應該可以從上下文和註釋中獲取信息。
工具僅僅是工具而已。設置工具多是(花費)一個小時的事情。若是你錯誤的使用工具,你將沒法獲得預期的效果。
謹記咱們爲持續集成設定的目標:
真正的意義是將你的思惟方式轉變爲「不斷爲你的項目或產品提供價值」
。
將你的軟件開發過程視爲硬件生產設施。開發人員的代碼表明可移動的部件。主要分支就是組裝產品。
更快地將不一樣部分集成在一塊兒並檢查其能正常工做,你最終將得到更好的工做產品。
一些實操例子:
「完成比完美更好」
。若是它正常工做,它在主分支中提供的價值比停滯在一旁幾天要好。