最新資訊
科技新聞

雲端整合專家,提供全方位雲端顧問服務

科技趨勢

你發的是Merge Request還是Monster Request?

你發的是Merge Request還是Monster Request?

 

 

前言

在程式碼開發過程中或多或少會Merge,但是大家有沒有想過怎樣的程式碼合併才是好的呢,會不會我一合併環境就炸掉了呢,而我們又該如何避免Merge Request 變成 Monster Request,就讓我們接著繼續看下去吧!

筆者的環境

  • 部署環境:GKE
  • GitLab Version:15.6.0

以下的設定與內容,可能會因各位使用的GitLab版本而有所差異。

協同開發 Collaborative Development

通常專案一開始可能只需要1~2人進行開發,而那個人可能剛好就坐在你旁邊,彼此說好要調整、合併的部分大致上就沒什麼問題(讚)。
但是!隨著公司壯大或是專案需求越來越多的時候,開發人數就會從1~2人變成很多人,這時候就不太可能按照以往的方式進行開發,因為很有可能這群人在遠端工作或是在不同國家。

這時,我們就需要一個工具,也就是Git,來協助我們進行所謂的協同開發

GitFlow

那麼,我相信大家對Git這個工具一定是非常熟悉,這邊讓我再貼心地跟大家簡單分享一下,我是如何使用Git來開發專案的。

首先直接看到圖中紅框的三個分支:
Master(正式環境)、Develop(測試環境)、Feature(開發分支)。

  1. 一開始專案會有個初始分支Master來當我們正式環境,接著從Master拉一個branch出來當測試環境也就是Develop。
  2. 當需求來的時候,會從Develop拉一個Feature branch出來進行功能開發。
  3. 功能開發完之後,透過合併的方式將程式碼Merge到Develop上進行功能測試。測試沒問題之後,一樣透過Merge把功能上線到正式環境讓使用者去使用

以上,是一個簡單的專案開發的Gitflow。

由此可知,在開發過程中Merge這件事情是無所不在,光上面圖中就可以發現4個Merge!
所以說只要有新功能開發就會有Merge產生,但是要如何確保你的這個Merge是安全的呢?

因為很有可能在我Merge之後服務就突然壞了,而我的表情就會跟上面圖片的人一樣囧!

這時候就會希望如果有一個人可以在我Merge之前跳出來跟我說:你不應該Merge! 那該有多好~~~(攤手)

各位客官真的非常幸運!
還真的有這個人,它就是我們今天的主角Merge Request (請掌聲歡迎:tada:)

Merge Request (MR)

簡單來說,Merge是一個程式碼合併的動作
拿踢足球為例:

Merge就像是再踢一個沒有守門員的足球運動,很容易就可以射門得分。
因此我們需要一個守門員一Merge Request,來幫忙擋Merge這顆球,讓我們在Source branch修改好功能要Merge到Targe branch之前,先發一個合併請求(MR),避免工程師直接對主分支或是環境進行修改。
所以說Merge Request在團隊開發中扮演著相當重要的角色。

Merge Request Flow

其實Merge Request不單單只是發一個合併請求,還可以結合CI/CD來實現DevSecOps

上面這張圖原是GitLab標準的CI/CD流程圖,這邊我加了一些元素之後拿來當作Merge Request Flow

首先由左至右:
1. 先從主分支拉branch出來開發。
2. 提交commit。
3. 開發完後接著建立Merge Request。
4. 建立MR後會觸發CI進行自動化建置、測試,包含Code Quality、Unit test、SAST、Container Scanning等等。
5. 在CI的工作都成功執行後,接著把MR交給主管或組長來進行Review或Approve,做為合併前最後一道把關。
6. Approve後,就可以進行程式碼合併了。
7. Merge後會觸發CD進行環境部署,將服務部署到實體機器或是GKE上運行。

以下會一一會帶大家看如何實踐Merge Request Flow。


Create Branch

首先!拉分支出來進行開發,大家可以根據自己的GitFlow建立分支。

Commit Code

開發就是Commit Code到GitLab Repository上,在UI上可以看到更動哪些檔案以及修改的程式碼。

Create Merge Request

這是開發完所建立的Merge Request。

  1. 在這行可以看到MR Overview、提交多少Commit、觸發哪些Pipeline以及修改了哪些檔案。
  2. 從哪個Source branch合併到哪個Target branch。
  3. 觸發哪個Pipeline。
  4. 在這個Approval表格裡,代表這個MR在合併之前需要滿足的條件,可以看到:
    • 第一列有綠色的V,代表這條件目前已被滿足。
    • 第二列是自行設定的Appovers(後面會教各位如何設定),兩個圓圈代表這MR有兩位同仁當審核人,右邊的Approvals代表這MR只需要這兩位其中一位審核通過,那麼條件就滿足了。
  5. Security scans have run:假如在執行CI的過程有使用GitLab提供的掃描工具,當掃描執行結束之後,在這MR介面就會出現這段貼心的文字提示掃描已經執行完囉,且在右邊的地方還可以下載掃描的結果。
  6. Merge Button:顧名思義就是進行合併的按鈕,按下即為合併,前提是Approval的條件必須全被滿足,按鈕才可以被點擊。
  7. 最下方這裡是Comment,可以在這裡做一些紀錄,像是測試結果、與同事討論的過程等,減少資訊不同步的情況,可使用Markdown語法撰寫。

Security Scanning Tools

不得不說GitLab在掃描方面,提供了很多種工具:thumbsup:,讓我們在CI/CD的時候可以來檢查服務有沒有存在一些安全的漏洞,以下表格提供給大家參考囉!


Continuous Integration (CI)

GitLab在CI/CD Pipeline提供了一個圖形化的介面,可以清楚地看到,這個Pipeline跟哪個MR有關聯、有哪些stage、job以及執行狀態,點擊job還可以看到運行的log紀錄。


Right After Approving

接著回到MR,在Approve之後,我們可以看到,誰幫我審核了以及剛剛的Approval表格可以看到兩個條件是都被滿足打勾了,代表著我們可以進行合併。
Merge Button也從灰色變藍色了。

最底下GitLab再次貼心的,幫我們自動壓一個誰審核的Log紀錄。


Right After Merging

按下Merge按鈕之後,一樣可以在MR的畫面看到,是哪位同仁按下的,同時呢也會觸發CD做服務部署。
當CD執行完成後,就會幫我們把Artifact部署到目標環境上運行囉。

Continuous Deployment (CD)

CD畫面呈現跟CI是一樣的。


前面都是在教大家如何建立使用Merge Request,其實它還有一些額外的設定,可以讓MR使用起來更彈性更嚴謹。

MR Approval Rules

在MR合併之前必須獲得多少核准,以及哪些User應該進行批准
可以透過Users的方式一個一個加入審核清單,或是以Groups的方式加入就不需要一一新增至名單裡。

MR Approval Settings

透過Settings的設定,限制了誰可以核准合併請求,讓Approval Rules更貼近我們的設定。

  • Settings > Merge requests > Merge request approvals
    以上設定只需要設定一次即可繼續沿用,有需要時再更動就好。

GitLab Runner

前面講MR的時候有提到會觸發CI/CD,那麼在GitLab裡CI/CD就是透過GitLab Runner來執行。

  • Runner是一個Application用來執行Pipeline中的Job
  • 可自行註冊到GitLab使用
    • Docker
    • Kubernetes (GKE)

其中GitLab Runner又分為三種類型。

  • Shared runners:提供所有Projects使用。
  • Group runners:提供給一個組中的所有Projects和subgroups使用。
  • Specific runners:提供給特定的Project。

當我們寫好Code commit到GitLab Repository上後,接著GitLab會trigger GitLab Runner去根據CI YAML檔所定義好的內容幫我們執行CI/CD。

.gitlab-ci.yaml

  • CI/CD設定檔
  • 定義Project的Pipeline, Stages, Jobs and Environment
  • 放置在Repository根目錄中

當Repository中的檔案有更動時,GitLab會去檢查根目錄有無.gitlab-ci.yaml這個檔案,有的話則觸發GitLab Runner根據裡面的內容執行對應的CI/CD工作。

以下跟大家介紹一下CI YAML兩個比較基本的term!

Stages

Stages包含一至多個stage,像圖中的test, build, deploy;stage用來定義Job在哪個階段執行

舉例來說,我希望在程式碼建置之前先執行測試,因此test stage就會被放在build stage前面先被執行。

  • stage裡的job必須全部都成功執行後才會往下一個stage執行。
  • 在同一個stage的jobs會同時被執行。

    如果jobs之間執行時有順序上的關聯,可以透過need或是dependencies這兩個Keyword來定義關係,可參考此連結

Jobs

  • .gitlab-ci.yaml最基本的元素
  • 定義要做的事情
    • e.g., run test、build image、deploy

廢話不多說直接上圖!介紹幾個Keyword。

  • include:可以透過include template方式,將別人寫好的template引入到我們自己的YAML來使用,像是這邊我使用GitLab寫好的SAST掃描服務,只要在YAML加入一行程式碼,就可以使用掃描服務,是不是真的很方便。
  • rules:決定job要在什麼時候執行。
    • e.g., 希望在建立、更新MR的時候可以執行job,就可以在job底下只用rules來設定要被觸發的條件。
  • script:執行指定的commands。
  • artifacts:希望有些工作最終會產出一些成果,像是原始碼組譯後的打包成果等等,這時候就可以在工作中定義Artifact,將需要產出的檔案搜集起來。

如果想了解關於.gitlab-ci.yaml更多的keyword,請點連結

Summary

  • 避免你的Merge Request變Monster Request:
    • Pipeline
      • SAST
      • Code Quality
      • Dependency Scanning
      • Container Scanning
    • 設定Approval Rules、Settings
  • GitLab Runner:
    • Shared Runner
    • Group Runner
    • Specific Runner
  • .gitlab-ci.yaml:
    • Stage:定義哪一個階段執行Job
    • Job:CI YAML最基本的元素,定義要做的事情

最後,希望透過圖解的方式,讓大家更加認識GitLab的Merge Request,也讓我們在開發上可以更快速又安全!

Reference

tags: gitlab merge request devsecops cicd