不可諱言,許多工程師在開發過程,都曾經歷幾種惱人處境。第一是「Bug 變 Feature」,哪天你發現自已寫的程式碼與 Business Domain 對不上,看來像是 Bug,卻又沒有使用者回報,難不成 Bug 已變 Feature?該改掉它嗎?難免陷入天人交戰。
第二是「奇怪的 Code 不敢動」,哪天看到一些奇怪程式碼,Blame 下去竟發現 Commit 上寫著 Fix Issue,完全看不出 Fix 了什麼,生怕貿然更改會出亂子,因而動彈不得。
第三是常見的「Rollback」。哪天線上出包,上司催促趕緊 Rollback,但攤開 CI/CD 記錄,發現從上次 Release 至今 Pipeline 跑了一堆,要找到前一次 Release 可謂曠日費時。此時有嫻熟 K8s 的同事自告奮勇,想利用 rollout undo 實現自動 Rollback,怎料做完後反倒導致系統全面崩壞,從 Service Mesh 淪為 Service Crash。
前述三種場景,難免讓工程師感嘆人生好難。但新加坡商鈦坦科技 (Titansoft)技術經理蕭晊莛認為,把 Commit 寫好,即可遠離這些窘境。但鈦坦是一個強調自組織的公司,若直接使用權力驟然推動 Conventional Commits(約定式提交),免不了引發 Team Member 反彈。因此他基於在鈦坦練就的實戰心法,轉化為 Hello World Dev Conference 當中一場「用 Commit 生成編年史、構築世界再到多重宇宙」演說,期望引導工程師利用 Commit Message 驅動諸多正面變革。
自動連結 Jira,從 Commit 可以找到修改依據
「當一段 Code 被 Commit,你期待看到什麼?」蕭晊莛表示,不妨以 5W1H 做為思考的原點。一是 Why,為何需要改;二是 What,想解決什麼問題;三是 Who,誰改的;四是 When,何時改的;五是 Where,哪裡被改;最後是 How,如何被實作。事實上我們只要用 git log 與 git diff,便可獲得第三到六題解答,故接下來的重點,便是找到欠缺的 Why 與 What 答案。
鈦坦善用 Jira 成功為 Why 與 What 解題。怎麼做?當主管要求 Conventional Commits,極可能引起反抗,因此舉違反人類的自由天性;此時主管可放緩步調,僅要求在 Commit 時加上 Jira 編號,因過程簡單,就不致衍生過大反彈。只要做到這一步,哪怕 Commit Message 一團亂,但總算有了 Convention,而 convention 是人類看得懂機器也讀得懂的方式,既然機器讀得懂接下來就很有機會做自動化。
譬如鈦坦便利用 GitLab 整合 Jira,後續當游標指向 Commit 上的 Jira 編號,就被帶到 Jira 卡片,讓人清楚識別過去究竟為了什麼而做,甚至自動將 Commit Message 寫入 Jira Item Comment。
這時難免有些人依然抱怨,直言每次 Commit 還需記得 Jira 編號,頗為麻煩。為避免衝擊開發者體驗,主管可縮小變動範圍,不要求每次做,只改 Branch Name;也就是開 feat branch 或 fix branch 的同時帶入 Jira 編號。
當我們只改變 Branch Name,就可以開始在 Convention 做一些事。譬如鈦坦所使用的 JetBrains IDE,利用 Plugin,當要撰寫 Commit 時,自動生成 prefix,僅需在後面寫入想要的內容即可,讓整件事更簡單。
事已至此,還有人抱怨?當然有可能。例如有人主張做開發就是不斷嘗試,卡片上寫 Try 即可,為何還要費心掛 Jira 編號?乍聽之下頗有道理,此時主管稍微改變策略,等到 Merge 再實施檢查,屆時工程師才需要把 Merge 訊息寫清楚。
大致上來說,當我們推動 Convention,應避免一下子用力過猛,一點一點慢慢來就好,比較不會遭到反抗。另值得一提,主管亦應思考成員平常的開發習慣,據此發想對應策略,儘可能減輕推動阻力。
自動生成 SemVer,建立不同版本微服務的整合測試
下一步重點為「生成編年史」,既然透過 Commit 得知 feat、fix 及 Jira 編號,接著可利用工具來自動產生更新日誌(Changelog)。因為大家平常連文件都懶得寫,更何況寫 Changelog?所以既然有 Convention、可做自動化了,就能自動生成 Changelog;而 Changelog 上有 Features 與 Bug Fixes,主要利用 Commit 的前綴來得知做了什麼事,另外帶出 Jira Link 與 Git Diff、讓你能透過 Changelog 重回當初,進一步瞭解為什麼新增此 Feature、想解決什麼問題,或實際上改了什麼、怎麼改的。
更重要的,Changelog 會自動生成 SemVer 版號,一個版號代表一次 Release,還自動幫你連結兩個版號之間的差異,有助確保 Rollback 正確性。
至此一切完美無瑕?並不是。Commit Message 的內容還是仰賴人撰寫;一般狀況只能靠 code review 時調整,Changelog 上面可能充斥不明確的資訊,每次都要去 Jira 看,看久了大家自然而然會把 commit message 寫成 item 摘要,Message 品質就會漸入佳境。
再來談到「構築世界」。蕭晊莛指出,在一個未經妥善規劃的微服務下,你可能改動一個 Service,整個系統就炸了。但如果版號容易閱讀,工程師就容易記錄哪些版本組合可以正常運作,等到日後做 Rollback,就有清晰的脈絡可供核對,避免做出錯誤的升版或降版動作。
再來我們可嘗試將版號帶入環境變數,例如將 Image 名稱與 Image Tag 壓進 K8s 環境參數裡。如此一來,我們就能輕易將 Image:Ver 帶入 Structured Logging,亦可將 Service/Ver 帶到 HTTP Request,意即在 Header 補上 User-Agent,讓 Service 知道是哪一個服務的哪一個版本送出 Request,最終形成一個有 SemVer 的微服務世界。後續當 Issue 發生、而你需要查詢 Log 時,較能貼近真實現況;此外能利用 User-Agent,讓 Server-Side 認得 Client-Side。
針對最後一步「多重宇宙」議題,精髓就在於運用 Docker Compose 建立不同版本的整合測試。箇中關鍵仍是 SemVer,唯有 SemVer 易讀,人們才能清楚知道當下整合的版本為何,輕易看出是否有 Breaking Change,如此不論在 Local 的 K3s、Stage 的 K8s 或 Production 的 K8s 任何環境,都能重現問題,實現 Docker Image 的獨立性與可遷移性設計。
總括而論,藉由蕭晊莛循序鋪陳的教戰心法,凡是覺得 Commit 紊亂、覺得每次想版號十分痛苦、或覺得 Commit Message 無用到不知為何而做,甚至難以在隔離環境重現問題的工程師們,都可望豁然開朗,迎來健康有序的微服務發展。
最後分享鈦坦 Atlassian 顧問團隊的的部落格,我們每週都會分享 Atlassian 相關的應用或技術文章,歡迎有興趣的大家一起來交流!
熱門新聞
2024-11-12
2024-11-10
2024-11-13
2024-11-14
2024-11-10