Version Control 與 Artifact Management


幾年前的分享 聊聊軟體交付的濫觴 - 談產出物管理,簡報最後面留幾個問題讓大家思考。

最近有朋友私下敲我,問了最後一個問題:

分支策略Artifact Management 的關係?

問題背後是他在新創團隊裡,遇到在處理分支策略的同時,也遇到如何打包 Artifact ,兩者的衝突與矛盾。

底下是我針對這個問題整理的摘要。

本文重新整理我在 FB 寫的草稿,之後嘗試錄了一段口述,提供給大家參考。


要解決怎樣的問題?

這兩個東西各有要解決的問題。

分支策略 要解決的核心問題:團隊協作的問題

  • 一堆人開發,比較流暢的方式。
  • 開發流程的分工與切割?
  • 顆粒度大小?
  • libraries or web service ? console ? …

分支策略,應該要減少影響發布流程,也就是常說的 CI / CD Pipeline 過程,太複雜的分支策略,會製造出很複雜的 Pipeline。

各種分支策略的比較,參閱 持續交付2 第八章,這不是 0 or 1 的是非題,而是看組織 / 架構 發展到哪個階段 (#康威定律),還有 Tech Lead 能掌握的狀況。

Artifact Management 要解決的則是 軟體交付標準化 的問題。

  • 給 docker image or zip?
  • 這東西我能用嗎?你可以不要一直改嗎?
  • 我是 QA,正在測一個 long running 情境,我要哪哪一個版本測?
  • 我明天就要開工,你可以先給我一個沒有實作的 lib 嗎?
  • 我要部署到美西,給北美市場,請問我要部署哪一個版本
  • 我要部署到火星,給木星市場,請問我要部署哪一個版本

Artifact 交付的原則 - Version Control

簡單定義 Artfact 交付的一些基本概念:

我把 交付 定義成 Artifact 主要目的,也就是 版本控管 (Version Control)

核心規則如下:

Artifact Image 會分兩種 Types:

  • dev: development version
    • 假設功能尚未被驗證,以驗證功能為主,只能在團隊內部使用。
    • 具備 debug 功能, 特殊後門, 特殊 config flag, 選擇性編譯 (build flag) … etc.
      • binary 沒有最佳化, 放特殊 trace flag …
      • 如果是 open source 專案,找找官網的 nightly build or daily build,就是這一類。
  • rel: release version
    • 功能已經完成驗證,經過認證程序,可以給客戶使用。
    • debug 功能關閉,或者需要其他特殊方法才能開啟
    • binary 有最佳化,像是混淆、簽章
    • 一個版本,最後只會有一個,也就是在外面流通的。

底下舉例,這段例子在 Version Control 一文也有描述 :

  • 開發中: v1.0.0
    • 今天 (04/06) 建制的版本:RickLds-v1.0.0-dev-b20220406-1200.zip
    • 明天 (04/07) 建制的版本:RickLds-v1.0.0-dev-b20220407-1200.zip
    • 大後天建制的版本:RickLds-v1.0.0-dev-b20220408-1200.zip
    • 類推,就是個 Time Series 的概念。
    • 注意:版本 (v1.0.0) 都還沒跳號,不管過程中發現多少 defects
    • 直到完成 v1.0.0 的 release procedure 後
    • 下一個開發循環開始的時候,跳 v1.1.0 ,回到 (a.)
  • Release: v1.0.0
    • 完成 v1.0.0 release procedure,
    • 最後產出 release image: RickLds-v1.0.0-rel.zip or RickLds:v1.0.0-rel
    • 只有一個,透過 sign 的方式確認檔案的唯一性 (md5/sha256/sha512)
    • artifact 與 config 是 1 對多的關係。
    • config 的數量 = env 數量。

平常看得到的案例

  • 微軟 Windows
    • 試用版或者內部人員流出來的開發版,就是上述的 dev version,可能會有多個。
    • 正式 release 的就是上述的 release version,通常一個版本只會有一個。
      • 有些會有 RC (release candidate) 或者 beta version. (名稱差異代表開發流程的定義)
  • dapr: https://github.com/dapr/dapr/releases
    • release / rc: 鄉民可以拿來玩的東西
    • dev: 看不到,自己下載 source 自己 build ㄅ
  • Go 的 Module 發布: 官方文件建議用 pseudo-versions 表示發布之前的版本,其實就是我前述的 開發版。官方設計的 pseudo-version 包含以下三個資訊:
    • A base version prefix (vX.0.0 or vX.Y.Z-0), which is either derived from a semantic version tag that precedes the revision or vX.0.0 if there is no such tag.
    • A timestamp (yyyymmddhhmmss), which is the UTC time the revision was created. In Git, this is the commit time, not the author time.
    • A revision identifier (abcdefabcdef), which is a 12-character prefix of the commit hash, or in Subversion, a zero-padded revision number.

Artifact Images 的規則是必要的?

Q: 我的團隊從來都沒有你說的東西 dev / rel,一樣能跑。所以真的需要這樣分?什麼時候需分 開發版釋出版 的 Artifact Images?

沒有 dev / rel 團隊依然可以運作,大部分是因為遇到依賴管理問題,所以就不會有這樣的需求,也沒意會到這樣的問題。依賴管理指的是團隊彼依賴的功能是透過 Artficat 發布的方式運作,像是彼此是透過 NuGET / Docker / mvn / npm … 等。當團隊規模到一定程度之後,拆分模組獨立發布與管理,這是必然的需求。

會覺得沒有這樣的問題,常常是因為參照的方式是透過 檔案相對路徑 參考,而不是透過 artifact 參考。像是 .NET 專案 (.csproj) 裡面的 dependency 是相對路徑,而不是 reference。

最常見的是開發共用的 libraries 給大家用,開發過程必然會有開發中的版本 (dev version),給自己團隊內部測試、驗證使用,以及釋出給別人 (其他團隊、客戶) 使用的 rel version。

最常見的錯誤觀念

  • 開發中的版本, ex v1.1.0, 還沒 release 就要 進版號, 不管是 x, y, or z.
  • 沒有區分 dev / rel ,不管怎樣的環境都用同一種
  • 把 config 包進去 artifact
  • 以為只能用在 semanitc versioning, chrome 單一版號也適用。
  • 以為這樣不能跑敏捷開發 (ex: scrum): 這好像沒關係。
  • 以為用了這個就不敏捷 …. 我下班了。

Semantic Versioning

Version Control 通常會搭配 版本號碼的規則,而 Semantic Versioning (x.y.z) 則是最常見、最普遍的通則。

初始專案實踐 Semantic Versioning 的方式

初始專案指的是新專案,從 0 -> 1 的階段,在這段時間 Semantic Versioning 跳號方式:

建議從 v0.1 開始跳,每個 sprint 跳一個 v0.2-dev, v0.3-dev …
直到可以 release 給第一個客戶,直接跳 v1.0-rel

進入專案的 1 -> 10 的階段,就進入正常的跳號流程,
每個 release 都跳 第二碼,也就是 v1.1.0 -> v1.2.0 -> v1.3.0 …

Deliver Hello World in First Day

專案之初,通常是從 0 -> 1 的階段
就要把上述流程建好,
不管是開發 Web Service / Frontend / Libraries / Desktop App / Console …
都是一樣的原則。

換言之
專案開跑的時候,
就可以 build 可以交付的 artifact
我把這概念稱為 Deliver Hello World in First Day
第一天就要可以交付。
這種交付不是透過 IDE 那種 export 功能完成的
而是透過 ci server 建制出來的。

第一天就要完成 軟體交付的四大支柱 定義的東西。

這個概念,跟 Unit Test 的概念是一樣的,只是對象不一樣而已。錄影中我嘗試闡述這段 Deliver Hello World in First Day 的想法:

結論

所以 Artifact Management 跟分支策略的關係是?我具體的回答如下:

沒關係,因為要解決的問題不一樣。在 軟體開發生命週期 (SDLC) 過程,都應該要有 開發版釋出版,不管哪個分支策略,技術上都做得到,也應該做得到。

至於本文前述中我定義的名詞 (dev / rel),可能和一些生態系用語會有些差異。像微軟預設就有 Release / Debug 的定義,而我把 debug 定義成 另一個 flag 的概念。因為不管 dev or rel 都具備 debug 功能,也可以關掉。不然你以為 上上下下左右左右BABA 是怎麼來的?XDD

所以兩者要解決的問題不一樣,關係不太。100 團隊有 1000 種分支策略跑法。但 Artifact Management 的原則都一樣,但實作可能也有 1000 種。像是版號: 三碼 (x.y.z)、還是一碼 (chrome 99)?支援多少種 artifact type (docker / raw / nuget / npm … etc),artifact image 命名規則大家都不一樣,Version Control 整理一些以前的例子,Artifacts Management 最後面的截圖舉了兩種例子。

版本管理與軟體開發

By the way,我口語的 版本管理 跟大部分寫 Code 的 Engineer 是不一樣的意思,大部分 Engineer 談的都是 VSC (Version Control System),像是 git / svn / p4 … 這種 工具,談的是分支策略, 或者是 git 怎麼操作 (man git)。

而我講的 版本管理軟體開發週期 (SDLC),如何定義好版本 以及開發過程中,如何交付給別人使用,從使用者角度。

而這篇文章描述是我用來判斷是否了解 軟體開發週期 (SDLC) 的依據之一,特別是擔任軟體 TPM / PM / PO 是必須清楚掌握的,因為無法掌握整個 SDLC,就是掌握不住團隊運作的 節奏,一首歌拍子不對,音符彈的再炫砲、技術再厲害,曲就是不成歌。


延伸閱讀

站內文章

參考資料



Comments

  • 全站索引
  • 學習法則
  • 思考本質
  • 一些領悟
  • 分類哲學
  • ▲ TOP ▲