博客 / 詳情

返回

提交代碼「前置處理」,向前一小步,效率提升「億點點」

💡 如何巧用 Git Hook,解決代碼提交中的代碼規範性、衝突和錯誤以及工作流程問題?

近日,在極狐Tech Talk 直播上,極狐(GitLab) 後端工程師田魯分享了自己的實踐經驗。以下內容整理自本次直播,你也可以點擊文末「閲讀原文」觀看視頻回放。Enjoy~

在開發過程中,開發人員提交代碼後,需要繼續做很多工作,因此我們不由萌生一個問題:是否可以把一些工作前置處理,減少等待時間?

首先,我們先回顧一下常見的代碼流程:

1. 開發人員在本地編寫代碼之後,執行 Git Commit 操作 ,保存本地倉庫;

2. 將代碼推送到遠端服務器,觸發 CI Pipeline,執行 Pipeline 中各階段任務:Build、Unit test、Integration test;

3. 執行 CD Pipeline 階段任務:Review、Staging、Production。

在該流程中,若在本地發現問題,修復起來時間相對較短;若在遠程執行 Pipeline 後才發現問題,則修復時間較長,並且增加了服務器的壓力。

那麼是否可以將一些工作提前,如在中間部分(如上圖)完成來提高本地效率,縮短開發流程呢?如題所言“向前一步”,即把原本在 CI 中執行的部分工作,放在本地執行。

代碼流程中的後置處理之痛

常見代碼開發過程中,通常依賴於後置處理,即開發人員的代碼提交到 Git 上以後,運行 CI/CD 或者 Code Review 過程中才發現常見問題,包括:

  • 代碼規範 → 花大量時間溝通達成一致;
  • 衝突與錯誤 → 提交後發現與主分支衝突,需要重複修改代碼和提交;
  • 敏感誤提交 → 可能造成安全事故;
  • 缺少自動化任務 → 手動執行,容易遺忘。

這樣既浪費了 CI/CD 資源,也花費了不必要的時間,導致開發效率低。

舉個🌰,如下圖極狐GitLab 中的 Pipelines,在構建作業 → 測試 → 發佈的環節中,我們需要等上傳測試後才能發現錯誤,接着在本地修改,再把 Pipeline 推送上來,才能確認這個錯誤是否被修復;若沒有修復,則需要重複修改,直至修復完成,這個過程耗費很多時間。

可能大家會想到,對團隊成員進行口頭約束,或從制度上要求開發人員必須自己做檢測,但這些幾乎是流於形式。

那麼,極狐GitLab 如何處理解決這些問題的?

極狐GitLab 自動化流程落實前置處理

極狐GitLab 通過自動化流程,高效落實開發工作,讓團隊協作更流暢

  • 代碼規範性問題
    在提交代碼前,運行代碼風格檢查和自動化測試等腳本,幫助開發人員發現並修復代碼中的規範性問題,從而保證代碼的質量和可維護性。
  • 衝突和錯誤問題
    在提交代碼前運行 Git Hook,幫助開發人員避免將錯誤或不規範的代碼推送到代碼倉庫中,從而減少代碼衝突和錯誤。
  • 工作流程問題
    開發人員規範化 Git 工作流程,提高工作效率和協作效果。通過配置 Git Hook,可以自動化執行代碼檢查、測試、構建和部署等任務,避免手動操作繁瑣和出錯。

極狐GitLab 在具體實踐中逐步完善了該自動化流程,從而確保研發任務能更有效執行。這部分在極狐GitLab 的文檔裏也有更具體説明,感興趣的小夥伴可以查閲我們的資源與文檔。

前置處理的關鍵方法:Git Hook

與許多其他版本控制系統一樣,Git 有一種方法可以在發生某些重要操作時,觸發自定義腳本,即 Git Hook(Git 鈎子)。

當我們初始化一個項目之後,.git 目錄下有一個 hooks 目錄,可以看到上圖左側有很多執行任務,比如 pre-commit,代表在運行這些命令之後或之前,會進行一些校驗和檢測來執行相應任務。

Git Hook 分為兩部分:本地和遠程,如下圖所示:

本地 Git Hook,由提交和合並等操作觸發

  • 比如代碼發生變更,進行 git add,把 message 進行 commit changes;
  • 當 git commit 時,就會執行一個鈎子叫 pre-commit(準備提交鈎子)。

遠程 Git Hook,運行在網絡操作上,例如接收推送的提交

  • 在 commit 之後,要推送到遠端,此時有一個叫 pre-push 鈎子,把信息推送 git 倉庫;
  • 在遠程階段,極狐GitLab 相當於一個遠程倉庫。如圖有很多倉庫,分別承擔不同功能,比如 pre-receive ,主要在服務器端接收通過本地推上來代碼,然後 update 相關代碼,post-receive 説明代碼接受成功,同時有一個服務器鈎子執行。

在這裏,我們主要關注本地 hook,比如説 pre-message 和 pre-push,因此我們會藉助這些工具來實現規範化代碼內容。

提前進行代碼規範檢測

極狐GitLab 是一個非常大的代碼倉庫,包含前端代碼、後端代碼,還有運維相關代碼:

  • 前端代碼如 ESlint、Jsonlint、HAML-lint、Markdown-lint;
  • Ruby 相關的如 RuboCop、Stylelint;
  • Yaml 相關的如 Yaml-lint。

當然也支持不同語言項目,像 Python、Java 或者其它編程語言,也會有相應代碼規範要求,可以自己添加。

每個 Lint 都會去檢測代碼中的變動,從而檢測代碼是否符合預期。只有符合預期的代碼,才能夠推送進來,避免代碼提交之後,再發現代碼規範問題,在反覆修改上浪費時間

這就好比整個代碼倉庫是房子,代碼是水,Lint 相當於過濾器,必須讓這些代碼經過過濾後,才能從水龍頭流出,成為生活用水。

提前進行代碼安全檢測

下圖展示的是 GitHub 安全事故:很多人在測試或調試代碼過程中,把一些 Token 放在裏面,無意識地推送到倉庫中,導致 API 和加密密鑰泄露,這很容易被人發現和利用,進而造成巨大損失。

極狐GitLab 十分注重代碼安全,我們必須想辦法阻止開發人員將密鑰提交到倉庫,也就是必須在 Commit 之前,阻止開發人員把密鑰信息給放到 Git 歷史記錄中。

那麼,常見的安全代碼檢測工具有哪些?這裏給大家提供一個參考,就是 Gitleaks。

Gitleaks 是一個 SAST 靜態代碼檢測工具,檢測代碼中常見的 Secret、Token、Password 等內容,生成 Secret 檢測報告產物,避免誤提交,提高研發安全性。

提前進行自動化內容檢測

上述代碼規範檢測、代碼安全檢測,都是在代碼提交前,及時發現問題和解決問題,提升代碼質量和安全性。自動化內容檢測偏向於常規性內容檢測,例如:

  • gettext:查找未翻譯的內容,提示開發人員及時翻譯;
  • docs-metadata:提醒開發人員為文本添加描述等;
  • graphql-doc:檢測 graphql 的 doc 是否完整;

自動化內容檢測避免代碼提交到在服務器後再去修改內容,也是提高開發效率的手段之一。

上述 3 個步驟放在本地開發階段執行,基於以下原因,開發效率就會有很大提升,甚至整個運行時間降低 50%,同時更高效地提升了代碼質量

  • 本地運行速度快;
  • 及時發現問題,減少溝通協作成本;
  • 節省 Code Review 時間;
  • 節省 CI/CD 運行資源。

友好的 Git Hook 管理工具:Lefthook

我們可以使用 Git Hook 裏的 bash 腳本來編寫,比如前面提到的 Eslint、Stylelint 等,但是這種方式有個比較大的缺點:無法放在倉庫中,則無法看到變更歷史,也不方便分發,而且可能不是每個開發人員都熟悉腳本的開發。

因此,我們可能需要更友好的 Git Hook 管理工具,這裏推薦工具:Lefthook。

什麼是 Lefthook?

Lefthook 是一個開源的 Git Hook 管理工具,幫助開發人員自動化和規範化 Git 工作流程。

Lefthook 具備以下特點:

1.  支持多種編程語言:包括 Python、JavaScript、Ruby、Go、Java 等;

2.  簡單易用:輕鬆安裝和配置,使用過程也非常簡單;

3.  高靈活性:允許用户在 Git Hook 中使用任何語言和工具,而不僅僅是 shell 腳本;

4.  高可擴展性:可與其他工具和系統集成,比如 CI/CD 工具、代碼檢查工具、自動化測試工具等;

5.  支持跨平台:支持 macOS、Linux 和 Windows 等多個平台。

如何使用 Lefthook?

前文介紹了本地開發的前置一步,接下來通過實例讓大家體會一下在前置處理中,如何使用 left hook 處理代碼的風格安全問題。

上圖是我第一次編輯的一段 Ruby 代碼:通過 ChatGPT 抓取 GitHub issue 的一個內容。可以看到,acces-token 是一個環境變量,生成一個client 接口,接着我們去抓取相關 issue 信息,最後把它們打印出來。

這段代碼無論從風格上還是從安全性上來説,都是一個很簡單的內容。

假設本地開發人員對這段代碼進行了二次編輯,他發現設置本地變量比較麻煩,直接把密鑰寫在代碼中(如上圖。密鑰為隨機值),同時還把代碼風格打亂了,空了很多多餘行,換行也是往後對齊,導致整個代碼亂糟糟,不符合規範。

把這段代碼推送到 CI 上,就會被檢測出問題,或者 Code Review 發現這些Token 不應該上傳,但這樣屬於事後處理,實際上,我們應該在提交之前處理掉這些問題。

那麼我們看下 Lefthook 的配置, Lefthook 是類似一個 yml 的文件的配置。如下圖,這裏有一個 pre-push 的 hook,還有推送前的一個命令叫 pre commit。這裏我們着重講講 pre-commit。

pre-commit 它運行兩個方面:

1. Rubocop 風格檢測:對 .rb 後綴的文件進行入庫,檢測是否符合規範;

2. 密鑰檢測:檢測文件中是否發生了密碼的泄露。

當我們在 commit 時,就會運行這兩個命令,檢測提交的代碼內容。

檢測上圖這段糟糕的的代碼時,看到執行鈎子 pre-commit 後的效果:

  • 密鑰檢測提醒第七行有一個 api key 泄露,確實左邊第七行用了一個明文密鑰;
  • 風格檢測提醒 15-17 行是多餘空行,第 25 行寫法不符合規範。

從而這段代碼報錯了,阻止 commit 的提交。

發現這些問題之後,就可以直接在本地去修復了,不用等待 CI/CD 時間;修復完再次提交,就成功了,可以看到 CI/CD 正常運行,讓 CI/CD 在 測試期間也能正常通過,效率就大大提高了。

除了這些內容,我們還會進行一些常規檢測,比如在 Lefthook 配置裏,有一個叫 Ruby 代碼風格檢測工具 Rubocop,有一些命令可以修復大部分錯誤內容,我們也可以加入一些自定義命令,如出現問題,自動修復並推送到服務後,給釘釘發送信息等。

極狐GitLab 中,大概有十幾個 Lefthook 命令,在開發過程中自動發現常見問題並解決。

總結

很多時候,造成效率低下的原因,是發現問題的時機太晚,Git Hook 在本地就能幫助我們解決代碼規範問題、代碼安全問題,並通過自定義腳本內容來自動執行,減少CI/CD、Code Review 時間,整體提升開發效率。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.