GitHub工程團隊已經轉移到Codespaces:實現開發環境的秒級啓用

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"8月11日,GitHub向自己的團隊和企業雲用戶開放了"},{"type":"link","attrs":{"href":"https:\/\/github.com\/features\/codespaces","title":null,"type":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"Codespaces"}],"marks":[{"type":"color","attrs":{"color":"#0366d6","name":"user"}}]},{"type":"text","marks":[{"type":"italic"}],"text":"特性。該特性在雲上爲軟件團隊提供了一個速度更快、協作性更好的開發環境。要了解更多信息,請移步"},{"type":"link","attrs":{"href":"http:\/\/github.com\/features\/codespaces","title":"xxx","type":null},"content":[{"type":"text","text":"Codespaces頁面"}]},{"type":"text","marks":[{"type":"italic"}],"text":"。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#333333","name":"user"}},{"type":"strong"}],"text":"本文最初發佈於GitHub官方博客,由InfoQ中文站翻譯並分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GitHub.com的代碼庫有14年的歷史了。在GitHub.com的第一次提交被推送時,Rails還只有兩歲,AWS只有1歲,而Azure和GCP還不存在。如果用COBOL時間來看這可能不算長,但用互聯網時間來看,時間真是不短了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在這14年中,支撐GitHub.com(github\/github)的核心存儲庫已經有超過100萬次提交。絕大多數提交都是來自開發人員在macOS上的構建和測試工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/c7\/dd\/c72393fc5451f04ed3bfd6234cef7edd.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"一次典型的消息提交"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,我們的開發平臺在發展。在過去的幾個月裏,我們已經將macOS模型拋在一邊,GitHub.com的大部分開發都轉到了Codespaces。這是日常開發流程的一個根本性轉變。Codespaces產品的功能更強大,我們已經爲GitHub.com未來的發展做好了準備。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"現狀"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"近年來,爲使本地開發工作可以快速開始,我們已經投入了大量的時間和精力。一段時間以來,我們所採用的"},{"type":"link","attrs":{"href":"https:\/\/github.blog\/2015-06-30-scripts-to-rule-them-all\/","title":null,"type":null},"content":[{"type":"text","text":"“腳本管理一切“的方法"}]},{"type":"text","text":"爲工程師提供了熟悉的界面——新員工可以克隆"},{"type":"codeinline","content":[{"type":"text","text":"github\/github"}]},{"type":"text","text":" ,運行setup和bootstrap腳本,用半天的時間讓一個GitHub.com本地實例運行起來。在大多數情況下,這都沒什麼問題,如果有問題,我們的bootstrap腳本會打開一個GitHub問題,在新員工和內部支持人員之間建立聯繫。我們的Slack頻道"},{"type":"codeinline","content":[{"type":"text","text":"#friction"}]},{"type":"text","text":"——上面有許多樂於助人的友善的工程師——幾乎可以調試天底下所有的系統配置。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/67\/c4\/67bd7f76cd4b30405cd849ecb9945ac4.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"用一條命令在本地運行GitHub.com!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"儘管我們做了許多工作,但本地開發環境依然很脆弱。任何看似無害的修改都可能會導致本地環境不可用,更糟糕的是,需要花費數小時寶貴的開發時間來恢復。開發環境經常被莫名其妙的破壞,而是還是災難性的,我們不得不在bootstrap腳本中增加了一個選項:"},{"type":"codeinline","content":[{"type":"text","text":"--nuke-from-orbit"}]},{"type":"text","text":" 。觸發該選項時,腳本會盡可能地刪除它負責的東西,將本地開發環境恢復到一個已知的良好狀態。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,任何從事軟件工程專業的人一看就知道,這是一種很典型的情況。本地開發環境很脆弱。即使現在很完美,但一個針對特定上下文定製的本地開發環境與我們所處的即時在線、隨處訪問的世界越來越不相稱。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在多個項目的多個分支上協同開發是很痛苦的。我們經常會發現,當一個分支引入了新的依賴,做了模式修改,或者從不同的SHA創建了分支,在啓動時就得眼睜睜地等45分鐘。鑑於我們的代碼變化很快(我們每天部署數以百計的變更),這經常會導致工程摩擦。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"並非只有我們注意到了這一點,在構建Codespaces的過程中,我們接觸了多家一流的工程組織,他們已經構建了類似Codespaces這樣的平臺來解決同類問題。當規模比較大時,消除這類生產力損失可以快速提高生產力。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/7f\/5e\/7f0edd754b71cb8853363067bcde3e5e.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"上面這條消息會使GitHub的任何工程師都出一身冷汗"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"軟件開發基礎設施"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在基礎設施領域,行業最佳實踐一直將服務器作爲一種商品。其思想是,沒有哪一臺服務器是獨一無二、不可或缺或不可替換的。任何一個部件都可以被悄無聲息的取下並替換。如果一臺服務器宕了,那沒什麼問題,另換一臺就是了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然而,每個人的本地開發環境都是獨特的,都有自己的習慣性設置。因此,需要時刻保持警惕才能維持。下一次"},{"type":"codeinline","content":[{"type":"text","text":"git pull"}]},{"type":"text","text":"或"},{"type":"codeinline","content":[{"type":"text","text":"bootstrap"}]},{"type":"text","text":"就可能會導致你的環境快速退化,需要進行昂貴的上下文切換才能恢復工作,而你寧可把這些時間用來構建軟件。通常,我們並沒有一臺即取即用的備用筆記本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,有必要強調一下,把開發環境看作是自己的——我們每天大部分時間都花在那裏。我們會調整、優化我們的工作臺,一方面是爲了提高效率,另一方面也是一種個性的展示。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了Codespaces,我們就可以像對待基礎設施那樣對待我們的開發環境——一種我們可以不斷更換的商品——但仍然保有個性化定製工作臺的能力。我們藉助Visual Studio Code擴展、設置同步以及dotfiles存儲庫將開發環境帶到了我們個人的計算機上。這樣,即使工作臺出現了問題,也是小事一樁,我們可以用一個已知的良好狀態配置一個新的編碼空間,然後繼續工作。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"採用Codespaces"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"遷移到Codespaces可以克服現有開發環境的缺點,激勵我們進一步推動產品的發展,提升整體的開發體驗。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然我們的遷移故事有一個圓滿的結局,但最初遷移的時候還是充滿了挑戰。GitHub.com存儲庫佔了將近13GB的磁盤空間;光是克隆存儲庫就需要20分鐘。在加上依賴項設置,啓動一個GitHub.com編碼空間需要45分鐘以上。而當我們成功將代碼庫加載到代碼空間後,卻發現應用程序不能運行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們不得不推翻14年來啓動過程以macOS爲中心的假設。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解決這些挑戰成就了最好的GitHub。全公司的貢獻者都幫助我們重新審視以往的決策,質疑長期存在的假設,在代碼層面將GitHub開發從macOS解耦。最終,我們可以(儘管很慢)在Linux主機上配置基本的GitHub.com代碼空間了,從Visual Studio Code連接上去,然後交付一些工作。現在,我們得想辦法讓它活躍起來。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"從45分鐘到5分鐘"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於Codespaces,我們的目標是可以根據手頭的任務按需配置開發環境(分支和代碼空間差不多1:1)。爲了支持基於任務的工作流,我們近乎實時地獲得開發環境。45分鐘不能滿足我們基於任務的需求,但是我們有很多地方可以優化,讓我們先從簡單的入手。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先:改變Codespaces克隆github\/github的方式。在準備開發環境的時候,Codespaces現在不再全部克隆,而是執行一個淺層克隆,然後在包含最新提交的代碼空間創建完成後,在後臺對存儲庫歷史做深層克隆。這樣一來,克隆時間從20分鐘縮短爲90秒。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來:緩存支撐GitHub.com的軟件和服務網絡,包括傳統的基於Gemfile的依賴、使用C、Go編寫的服務以及一個自定義的Ruby構建。在該解決方案中,有一個GitHub Action會每晚運行,克隆存儲庫、引導依賴項,構建並推送克隆結果的Docker鏡像。然後,發佈的鏡像會作爲github\/github devcontainer(Codespaces的config-as-code)的基礎鏡像。現在,我們的代碼空間創建95%以上都是自舉式的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這兩個變化,以及若干應用和服務層面的優化,將GitHub.com代碼空間的創建時間從45分鐘縮短到5分鐘。但是,5分鐘距離“即時”還有相當一段距離。衆所周知,有研究表明,人們等待大約"},{"type":"link","attrs":{"href":"https:\/\/www.nngroup.com\/articles\/powers-of-10-time-scales-in-ux\/","title":null,"type":null},"content":[{"type":"text","text":"10秒"}]},{"type":"text","text":"之後思維就會中斷。因此,雖然我們已經取得了很大的進步,但仍然還有一段路要走。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"從5分鐘到10秒"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然5分鐘意味着巨大的改進,但我們在修改時也做了一些折衷,這意味着還有更一般化的產品需求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們的淺層克隆方法——對於快速啓動Codespaces很有用——有時候仍然需要我們做完整的克隆。生成代碼空間後的深層克隆又存在干擾。任何大型的複雜項目都面臨類似的問題,在克隆和啓動時會產生資源競爭。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我們提前克隆並引導存儲庫會怎麼樣?那樣,當工程師申請代碼空間的時候,我們已經完成了大部分工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"預構建:代碼空間池,已完全克隆並引導,只等想要開始工作的開發人員連接。我們在預構建方面的投資已經獲得了無數次的回報:我們現在只需10秒鐘就可以創建一個可靠的、預先配置好的代碼空間,準備好GitHub.com的開發環境。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,新員工從零開始獲得一個功能完備的開發環境比安裝Slack的時間還短。工程師剝離出新的代碼空間以實現並行工作,也沒什麼開銷。當環境崩潰時——也許它太落後了,也許是測試數據造成了破壞——工程師可以快速創建一個新環境並繼續一天的工作。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"槓桿作用日益增加"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"遷移到Codespaces解決了我們的一些實際問題:它消除了本地開發環境的脆弱性和單軌模式,同時也爲我們提供了一個新的強大的槓桿作用點,讓我們可以改進GitHub的開發體驗。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,我們有了一個契子來執行額外的設置和優化工作,一些我們在本地環境中從未想過的工作,因爲這些優化的成本(時間和耐心)太高。例如,藉助預構建,我們現在可以事先準備好語言服務器緩存和gem文檔,運行待處理的數據庫遷移,並啓用GitHub.com和GitHub Enterprise開發模式——這項任務通常需要在另一次引導、設置循環中完成。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"藉助Codespaces,我們可以通過一條配置更改升級所有工程師的機器規格。在Codespaces遷移的早期階段,我們使用8核16GB內存的VM。那些機器足夠了,但GitHub.com運行着一個包含不同服務的網絡,它會很樂意消耗我們提供的每一顆內核和每一點內存。因此,我們轉到了32核64GB內存的VM。只需修改一行配置,我們就可以升級所有工程師的機器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/e1\/41\/e143c7237988a516yy0952c5291fe541.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"即時升級"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此外,Codespaces還開始偷走我們的內部平臺“評審實驗室”的業務,這是一個類生產環境,我們和內部協作者在這裏預覽更改。在Codespaces推出之前,GitHub工程師需要提交併部署一個評審實驗室實例(經常需要同行評審),以便和同事共享他們的工作。現在,我們按住ctrl並單擊就可以獲取一個預覽URL併發送給同事。不需要提交,不需要推送,不需要審覈,也不需要部署。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"命令行"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Visual Studio Code很棒。這是GitHub.com工程師連接代碼空間的主要工具。但是,要求Vim 和Emacs用戶向圖形編輯器提交就不那麼好了。如果Codespaces是我們的未來,那麼我們不能拋下任何人。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"令人高興的是,我們通過一個簡單的預構建鏡像升級爲使用shell的同事提供了支持。該升級使用GitHub"},{"type":"link","attrs":{"href":"https:\/\/docs.github.com\/en\/github\/authenticating-to-github\/connecting-to-github-with-ssh\/adding-a-new-ssh-key-to-your-github-account","title":null,"type":null},"content":[{"type":"text","text":"公鑰"}]},{"type":"text","text":"初始化"},{"type":"codeinline","content":[{"type":"text","text":"sshd"}]},{"type":"text","text":",打開22端口,並將該端口轉發到代碼空間之外。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/a7\/c9\/a70a0443e2dcf3f1d07dd7108afd83c9.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自此,GitHub工程就可以運行Vim、Emacs了,如果他們願意,甚至可以運行ed。這一措施很有效。而且,就像Docker鏡像緩存帶來了預構建一樣,很明顯,下一步是讓我們爲GitHub.com代碼空間所做的工作成爲每個代碼空間的頭等體驗。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"改變是很困難的,涉及到開發環境更是如此。值得慶幸的是,GitHub的工程師有很強的求知慾,同時也很友善——他們很快就變成了Codespaces的超級粉。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在,Codespaces成了GitHub.com的默認開發環境。至於前面提到的用於幫助調試本地開發環境問題的Slack頻道"},{"type":"codeinline","content":[{"type":"text","text":"#friction"}]},{"type":"text","text":",我們計劃將其歸檔了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GitHub每天都會上線更多的服務,每天都會有工程師加入,關於Codespaces的價值創造,我們會發現新的故事。但是,每個故事的核心都是一個每名工程師都會產生共鳴的主題:我找到了一個更好的工具,我現在效率更高了,我不要再回到從前那樣了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看英文原文:"},{"type":"link","attrs":{"href":"https:\/\/github.blog\/2021-08-11-githubs-engineering-team-moved-codespaces\/","title":null,"type":null},"content":[{"type":"text","text":"GitHub’s Engineering Team has moved to Codespaces"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章