ci 即持續整合(continuous integration),沒有 ci 之前,將新增的**改動合併到主幹是一件危險的事情,通常是定期合併,合併之前進行人工 review & 測試,確認無誤後才執行合併。
簡單來說 ci 是乙個自動化流程,方便我們頻繁地合併**。ci 通常在**合併之前自動執行,主要步驟包括:構建、**靜態檢查、單元測試等。有了 ci,我們合併**的信心大大增強。
主要關注以下幾點:
單元測試:官方的測試框架go test
已經夠用了,要有什麼補充的話,考慮 bdd 測試框架 ginkgo。
通常用 shell 指令碼來實現 ci 流程,但 shell 指令碼的環境依賴是乙個深坑,不同作業系統的 shell 環境差異很大,隨手列舉幾個:
嘗試用一套 shell 指令碼去相容所有的作業系統環境是不可行的,會陷入深不見底的泥潭。
sh (posix) 在大多數作業系統下都能找到,docker 也被大多數作業系統支援,使用 sh 作為 docker 容器的啟動器,將專案**掛入到容器內,在容器內執行 bash + gnu toolchain 執行我們的 ci 指令碼,這個方案能解決 99.99% 的環境問題,我們只需要選定容器內 bash + gnu toolchain 的版本,不再需要考慮 shell 指令碼相容的問題。
將專案**以 volume 的方式掛入到容器後,在容器內檢視檔案的 owner (uid:gid) 和容器外是一樣的,如果uid對應的 user 或 gid 對應的 group 在容器內不存在,則在容器內直接顯示為 uid 或 gid 的數值。也就是說,檔案的 owner 與 user 名或 group 名無關,與具體的 uid 和 gid 有關。
docker 容器內預設的使用者為 root,如果在 docker 容器內往 volume 寫入新檔案,那麼新檔案的 owner 為 (root:root) 對應 uid=0 gid=0,這個 owner(uid=0 gid=0)通常在容器外也是 root,這會造成:如果我們在本地用 sh + docker 執行 ci 指令碼,可能會在專案**目錄內產生需要 root 許可權才能讀寫的檔案——這是不合理的。可以在 docker run 時通過--user
選項指定執行 ci 指令碼的 uid 和 gid,設定為和容器外一致,就可以避免這個問題。
docker run 時通過--user
選項指定非 root 使用者後,ci 指令碼便無法使用需要 root 許可權的命令:例如安裝軟體包。雖然這樣的需求在 ci 中並不常見,通常在 ci 的 docker 映象構建時已經預裝了需要的軟體包,但考慮到一套 ci 指令碼可能被多個專案復用,可能出現各種各樣的需求,如果能在容器內支援 sudo 命令那就更好了。
sudo 的使用者白名單本質上是 uid 和 gid 的白名單,在 ci 映象打包時,我們不能確定未來執行容器時要指定的 uid 和 gid。
這裡提供乙個變通的方法:
通用的 ci 指令碼應該和專案**保持松耦合,分開維護,這樣通用 ci 指令碼也可以被多個專案復用。可以只在專案內放置乙個簡單的 sh(posix)指令碼,呼叫 curl 獲取真正執行的 ci 指令碼**,通過eval
命令解釋執行指令碼**。最終在指令碼**裡再執行 docker 容器執行更複雜更高階的 ci 指令碼……
gocache 環境變數對應 go build 的快取目錄,可以作類似的快取處理,加速 go build 命令。
Go語言 基於TCP的Sockets程式設計
簡介 做乙個簡單的通訊,從服務端建立連線,建立套接字也就是127.0.0.1 1021 我用的是這個,埠號可以自己設定 然後客戶端發起連線到127.0.0.1 1021.從而實現客戶端與服務端之間的通訊 服務端 package main import fmt net 處理連線 func proces...
Go語言 基於UDP的Socket程式設計
部落格說明 udp簡介 服務端實現 package main import fmt net func main if err nil 關閉連線 defer listen.close for fmt.printf string data n addr,n 傳送資料 err listen.writeto...
docker建立mysql容器,go語言使用
docker pull mysql 二 建立容器 docker run name mysql it p 3306 3306 e mysql root password emc123123 d mysql 在後台啟動mysql容器 name指定了容器的名稱,方便之後進入容器的命令列,mysql roo...