翻譯者:樂視 SCM 高翻院 石雪峰 校對:葉赫華、黃華、劉慧美
Etsy 是如何利用 web 持續部署實踐來改善 App 釋出流程的
代碼部署應該簡單且頻繁,研發工程師需要參與整個部署流程,對于Etsy web而言意味着秉持持續部署的核心實踐。對于日常釋出而言,會有一組工程師和一名專職的釋出經理共同監督所有變更被成功部署到準生産環境和生産活動,在釋出流程的每一個檢查點,團隊成員會對他們的變更負責,保證不會破壞代碼品質,確定其可以随時釋出。
所有人必須緊密配合保證每次部署都安全完成,而在 Etsyweb 這是一個頻繁發生的事情,有時甚至每天會有超過50次的部署。
這種政策奏效主要歸因于每次部署都是由最熟悉變更的成員直接完成,那些直接負責這些子產品代碼的開發工程師可以很容易發現并解決軟體中的問題。是以,開發人員應該被授權根據需要部署代碼,且代碼的順利部署保持關注。
而對于一個 App 的釋出而言,會有一些不同的地方,代碼部署的方法就不太适用了。其中一個主要的原因就在于 App 有版本疊代和編譯的完整過程,同時 App 需要通過 app store 或者 google play 進行分發,是以需要花費些額外的時間才能真正到達使用者。
一般來說,由于 App 釋出的這種特性,團隊會傾向于引入釋出分支和釋出經理來管理這個流程。而我們的 App 最早也是沿用類似政策,可是很快我們發現這樣的做法不太像 Etsy,是以我們決定是時候進行改變了。

我們兩個曾經是 Etsy 的釋出經理,Jen 負責 Sell on Etsy ,而我負責Etsy。我們的職責包括:所有釋出階段流轉,維護釋出計劃,管理所有釋出環節中的協同溝通,解決沖突以及跨團隊調配資源來應對緊急釋出中的問題修複。
我們的工作重在使個人各施其職,按部就班。每個釋出時間點也是我們最需要注意的評審點,此時需要組建專門團隊負責此階段功能內建到主産品,輪流進行疊代。階段釋出需要按計劃進行,并且保證到達特定釋出階段時會完成某些變更。重要的是,那些變更是意料之中且已經測試過的。
僅僅依靠 Jen 和我來追蹤所有在這次釋出中的變更是一件非常困難的事情,是以我們的任務之一就是協調所有作出變更的工程師保證他們的改動符合預期且驗證通過。在實際操作中,這意味在特定檢查點(比如拉出釋出分支的時候)需要發送大量的郵件和資訊用于溝通。當然在緊急報警發生的時候,我們同樣需要及時知會相關人員。
後來 Jen 離開了 Etsy 尋找更好的機會,而我就成了唯一的釋出經理,所有釋出的決策都需要通過我來完成,也隻有我能作出和執行這些決定,我俨然成為了釋出系統中的那個容易導緻單點失敗的瓶頸。
這令我壓力山大,手足無措,我擔心自己會陷入無盡的上傳 iTunes, Goolge Play 和發郵件的工作中,這也并非是我期望的工作内容。我希望這些繁瑣的任務都可以自動化,隻需要一個按鈕就可以完成,想到web部署時候的輕松惬意,這讓我很是羨慕。
即使回到我們兩個釋出經理的時候也并不輕松,從工程師的角度來說,這個階段的 app 釋出一點都不透明。他們很難知道目前的釋出階段,每天都接收大量的郵件,但隻有很少部分才是他們真正關心的。我們僅僅是把郵件發給4個應用。
開發人員的群組,内容混淆了FYI類的郵件和真正需要緊急處理的case,這讓我們陷入了“狼來了”的困境。
所有這些問題都會讓工程師感覺自己像機艙裡托運的貨物,而不是駕駛員,這完全不符合我們之前web部署的原則,也不符合我們的研發處世哲學。我們并不喜歡這樣,他應該變得更好,讓工程師從被動變為主動。
是以我們打造了一個管道來協調app釋出過程中的狀态,計劃,溝通以及工具,他有幾點好處:
•保持跟蹤誰做了哪些修改
•發送必要有效的 Slack 消息和郵件給需要的角色
•管理所有釋出的狀态和計劃
為了讓這些抽象的概念更加容易了解,我們可以看個例子:
Alicia 在 IOS app v4.64.0 版本上完成了第一次送出
Ship 擷取了這個消息,自動發送給 Alicia 一封 v4.64.0 版本歡迎郵件 .
譯者注:Ship是一個自動化系統
•自動任務将釋出流轉到測試階段,并自動編譯出測試版本 v4.64.0.52.
•Ship 擷取了這個消息,并發送 一封版本編譯完成郵件給 Alicia.
•Alicia 安裝這個版本并驗證她的改動,并回複給 Ship 這個問題已經 OK
•所有人完成自己改動的驗證,并 回報成功狀态.
•自動任務完成釋出分支的建立和預釋出版本的準備工作
•Ship 擷取了這個消息,并 給驗收測試團隊發送一封郵件.
•驗收測試團隊報告沒有發現嚴重問題
•自動任務将 v4.64.0 版本送出 iTunes Connect 稽核
•自動任務檢測到 iTunes Connect 的稽核結果,同通知 Ship 本次釋出已經獲得準許
•Ship 發送郵件給 Alicia 和所有改動負責人,通知本次釋出已經獲得準許
•自動任務正式釋出 v4.64.0.
•Ship 自動郵件給 Alicia 和所有改動負責人,通知本次釋出已經正式到生産環境
•Ship 發送一封 crash 報告給所有本次釋出中的負責人
在 Ship 誕生之前,所有以上這些工作都需要手動完成,但是你也許會發現,當一切都自動化之後,是不是釋出經理這個角色就被腳本所取代了,Ship 變成了我們的釋出經理?
隻說對了一部分,實際上Ship有一個功能将每次釋出配置設定給一個釋出司機(Release Driver)。
司機的職責在于一系列無法自動化或者 不應該自動化 的工作,包括:
•安排變更計劃
•跟蹤監控所有工程師變更都達到準備釋出的狀态
•跟蹤解決所有釋出前的嚴重問題
其他的事情呢?全部是自動化完成的!分支拉取,候選釋出版本編譯,送出 iTunes Connect — 甚至啟動釋出到 Google Play!
當然,我們也受到 automation going awry 這篇文章的啟發。有一些工作預設是編排為手動執行的。同時還有一部分工作在 Ship 中是明确定義為禁止自動完成的,比如Google Play的正式釋出。
這樣的工作需要人為幹預,除此之外盡量實作自動化。當然我們還有一個安全控制機制,在任何時候釋出司機都可以停止所有自動任務,切換到手動駕駛模式。
當釋出司機希望手動處理一些工作的時候,他們并不需要手動通路 iTunes Connect or Google Play,這些工作都被很好的封裝簡化到一鍵完成。這麼做的好處是,我們完全無需擔心釋出配置被所有人擷取,包括裝置号,認證簽名等,同時在背景我們儲存了一份清晰的日志來記錄所有釋出司機的行為。
在主線分支進入下一個釋出周期的時候,我們會采取半随機的形式來選舉新的釋出司機,範圍是上一個周期中參與到代碼送出活動的工程師和釋出司機。當選舉完成後,我們會自動發送一份通知郵件到這位幸運兒,告知他所要承擔職責:
其實在釋出分支被正式拉出之前,新一任司機基本都無需跳到前台,在釋出分支建立前幾個小時,就需要他正式登場啦,首先要确認所有本次待釋出的改動已經準備就緒,同時評估那些尚未完成的工作事項的詳細計劃。當一切就緒後,司機仍然要作為主要接口人來跟蹤驗收測試,如果發現任何問題,那麼他就需要推動解決。
假設一切順利的來到釋出當天,司機可以選擇手動釋出,或者安排自動任務,如果自動任務過程中出現問題,會自動通知出來。在釋出之後,司機會關注可視化看闆,日志,圖表來确認本次釋出的健康程度。
并非所有釋出都是計劃内的,意外總會發生,這才是 意料之中的. 假設嚴重問題不會随版本釋出出去過于天真,事實上會有各種各樣的問題需要我們 事後應對。當問題出現時,任何工程師都可以快速的基于最近一次正式釋出的基線修複問題。
研發工程師會通知釋出司機請求內建這個改動。當他們拉出新的釋出分支時,所有必要改動會內建進來,隻要獲得釋出司機的同意,其他人也可以這樣做。之後的流程跟正式釋出一緻,編譯待釋出版本,安排驗收測試,推送生産環境,一切盡在釋出司機的掌握之中。
誠然,版本的釋出是一個異常複雜的過程。
他起源于一個抽象的釋出計劃,之後便開始一系列具體的工作,送出代碼改動到主分支。代碼改動完成後則進入下一個階段拉出待釋出分支。編譯待釋出版本并跑通驗收測試,并投放到生産環境,之後釋出分支的生命周期就會結束。
當拉出釋出分支後,下一次釋出任務即刻在主分支啟動,周而複始,每一次釋出都有自己的釋出狀态機,幫助開發和釋出工作有節奏的交替進行。
通知機制覆寫整個釋出周期,因為整個過程中有太多資訊。讓合适的人在合适的時間收到合适的通知是非常重要的。是以我們使用釋出狀态機來通知工程師,以及其他訂閱消息的人員,這取決于他們的需求以及他們對本次釋出的影響。
我們提供了訂閱機制,允許釋出過程中的通知訂閱,這對于産品經理,支援團隊,工程團隊都有幫助,我們的通知機制正是基于主動訂閱的方法來設計的。
根據訂閱,我們會在狀态轉換的時候發送通知郵件,以保證郵件中覆寫必要資訊。
至于如何判斷對本次釋出的影響大小,我們需要其他途徑來擷取這些有效資料。
我們提到 Ship 需要通過其他途徑來擷取資料,在 Etsy,我們使用GitHub作為代碼版本控制系統,我們的app會基于平台(Android,IOS)來建構。為了保證 Ship 的資料及時準确,我們添加了背景腳本 GitHub Webhooks ,檢測到 master 分支推送和釋出分支推送的時候,會自動通知Ship。
當 Ship 擷取到這個消息後,他會周遊送出,記錄作者,儲存本地送出路徑,送出資訊以及受影響的 App 和影響版本。Ship 會統計分析這些資料,來評估影響哪些工程師會出現版本影響人員清單,這個清單會作為郵件通知的重要依據,以保證關聯人員可以及時擷取資訊。
此外,在釋出過程中,工程師可以登入改變他們的通知狀态,他們往往是因為需要擷取更多版本資訊,或者 Ship 錯誤識别了代碼改動資訊,并把他們添加到了不需要的版本通知清單中。
以上我們已經說明了在内部Ship是如何跟蹤狀态的機制,但還沒有提及自動任務是如何同外部系統協同工作的,以及他如何影響Etsy的開發流程。
我們研發了一套管理部署平台 Deployinator 來提供 App 釋出支援。他可以實作同 Google Play and iTunes Connect的釋出互動,這是我們用來編譯待釋出版本,釋出,建立分支,送出 iTunes Connect 等一系列任務的作業平台。
我們采用 Deployinator 基于幾個以下幾個原因:
•Etsy 的工程師非常熟悉這個平台
•通過一鍵操作封裝複雜的釋出過程操作
•便捷的日志提取和錯誤追蹤功能
在我們的系統中采用了 cross 任務,他幫助我們在周二晚上拉出釋出分支,也幫助我們接口 Google Play and iTunes Connect,我們使用官方API通過 Python 子產品實作通路 Google Play,至于 iTunes Connect 我們使用 Spaceship 來實作非官方的 API 的調用。
建構Ship的目标是讓他成為我們的釋出經理,從此 Etsy 不再有專職的釋出經理角色,任何人都有可能成為這個角色,包括我也不時的參與到釋出工作之中。
人的作用不可能被自動化完全取代,這對于 web 部署和 App 釋出殊途同歸。我們的流程之是以獨特,就在于不斷窮盡我們所能想到的所有事情,并讓他變得自動。與此同時,賦予研發工程師相比從前更多的職責,讓研發工程師來完成部署上線,決策是否拉出分支,工程師來親自上陣,點選按鈕釋出版本。
而這才正式 Ship之所有存在的核心期許,他讓我們的工程師傳遞最好的 App 給我們的使用者,讓工程師走向前台,職責共擔,激發更大的熱情和責任感。
譯者注:有效價值的快速持續傳遞是 DevOps 的終極目标,組織和文化的改變往往比工具層面的演進更加重要,打破部門牆群組織邊界的關鍵在于職責共擔,Etsy 正是通過極盡的自動化,簡化原本複雜而專業的事情,讓人人成為釋出經理,當工程師真正站在産品的角度意識到他的每一次改變都能帶來價值的時候,行為的改變潛移默化的帶動文化的改變,進而使這樣一家公司迸發出更多活力,成為研發效率領域的明星。
Posted by Sasha Friedenberg on May 15, 2017
文章來源:DevOps時代社群