佛心的 GitLab CI/CD 加值服務 ❤️

把 Project 開源之後,感覺就像來到了新世界,多了很多功能可以用。本文就是要介紹這些原本要付費才能使用,開放原始碼專案可以免費使用的加值服務!(用起來爽度暴增啊啊啊啊 =口=

再次感謝 GitLab.com 的佛心! <(_ _)>

在這先將使用到的服務列出來:

為什麼會有想要使用這幾個服務的念頭呢?

首先,因為我是 MR 的苦主(嘆~
如果可以有派遣工幫忙我那真是太好了,那麼,我會希望派遣工幫忙些什麼事情呢?

  • 如果可以的話,幫我盯個程式碼品質好不好?
  • 如果可以的話,程式碼裡面的漏洞能不能不要讓我人腦編譯來查?
  • 如果可以的話,幫我確認小夥伴 不小心 沒跟我說,就直接用下去的第三方函式庫能不能拿來商用?
  • 如果可以的話,我們用的函式庫有沒有問題,需不需要處理也幫我追一下?

還好派遣工有失憶症,不然肯定會抱怨怎麼要求這麼多!(笑~

以上幾個期望,就對應到了前述所說的那幾個服務!
真的是很感動!有這些服務,不管是 issue 的苦主,或是 MR 的苦主,都可以省去很多時間,更專心在應用邏輯上!
當然,採用這幾個服務的心態,並不是所有的事情都仰賴服務來做,而是心情上會好很多,有個服務幫忙分攤壓力。

CI/CD 流程調整|採用加值服務

那麼,是時候來想想該怎麼把這幾個服務放到研發流程中。
原先規劃的是:

  • MR|test
    • test => test
  • master|build
    • build => build
  • tag|deploy
    • deploy => maven

每項都是一個 stage 一個 job,依照前述的期望,感覺上應該要將服務添加在 MR 的過程中:

  • MR|test
    • test => test, CQ, SAST, DS, LC
  • master|build
    • build => build
  • tag|deploy
    • deploy => maven

就這樣設定會發現,MR 派遣工運作的時間會拉長,原因是 CQ、SAST、DS、LC 需要跑一段時間,尤其是 CQ 特別久。倘若不小心 push 了測試不會通過的程式碼,那這些服務等於白跑了。基於這樣的想法,調成如下:

  • MR|test -> quality
    • test => test
    • quality => CQ, SAST, DS, LC
  • master|build
    • build => build
  • tag|deploy
    • deploy => maven

嗯~這樣感覺很棒!
但我實際跑過一輪後,發現 GitLab Project 頁面中,針對 Security & Compliance 功能的 UI 整合,是基於跑在 master 的 pipeline。也就是說 master 上也必須跑 SAST、DS 和 LC 才能發揮最大效益。

所以,最後我的設定如下:

image: maven:3.6.3-jdk-11

# 重新整理了結構,把變數往前移
variables:
  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"

# 新增 quality stage 在 test 後,確保程式可編譯再跑
stages:
  - test
  - quality
  - build
  - deploy

# 啟動 cache 讓整個分支共用一個 cache 減少下載 dependency 的時間
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - .m2/repository

# 引用 GitLab CI/CD 加值服務,很簡單,只要 include 就可以了!
include:
  - template: Code-Quality.gitlab-ci.yml
  - template: SAST.gitlab-ci.yml
  - template: Dependency-Scanning.gitlab-ci.yml
  - template: License-Scanning.gitlab-ci.yml

# 覆寫 CQ 的定義,階段設定為 quality 只在 MR 運作,不使用 cache
code_quality:
  stage: quality
  only: [merge_requests]
  # 不使用 cache 的原因是發現,CQ 的服務會連同相依函式庫都拿來檢查
  cache: {}
  # 如果不需要讓 CQ 報告可以下載,這裡可以去掉
  artifacts:
    paths: [gl-code-quality-report.json]

# 覆寫 SAST 定義,階段設定為 quality 在 MR 和 master 時運作,Java 版本採用 11 版
sast:
  stage: quality
  only: [merge_requests, master]
  variables:
    SAST_JAVA_VERSION: "11"

# 覆寫 DS 定義,階段設定為 quality 在 MR 和 master 時運作
dependency_scanning:
  stage: quality
  only: [merge_requests, master]

# 覆寫 LS 定義,階段設定為 quality 在 MR 和 master 時運作,Java 版本採用 11 版
license_scanning:
  stage: quality
  only: [merge_requests, master]
  variables:
    LM_JAVA_VERSION: "11"

test:
  stage: test
  only: [merge_requests]
  script:
    - mvn $MAVEN_CLI_OPTS test
  artifacts:
    reports:
      junit:
        - target/surefire-reports/TEST-*.xml

# 原本的 build job,改名成 package,比較貼近語意「打包」
package:
  stage: build
  only: [master]
  script: 
    - mvn $MAVEN_CLI_OPTS package
  artifacts:
    name: "$CI_PROJECT_TITLE"
    paths:
      - target/*.jar

maven:
  stage: deploy
  only: [tags]
  script:
    - mvn $MAVEN_CLI_OPTS deploy -s ci_settings.xml

調整如上後,就會看到派遣工真的多幫忙檢查了那些原本研發流程中,要花費不少心思時時關注的問題,真的是很感謝有 CI/CD。

至此,
其實可以發現 GitLab CI/CD 並沒有想像中恐怖,有了加值服務後,也不需要寫太多 script 就可以達成很棒的綜合效果!
這陣子學習下來,用一句話總結,我認為使用 GitLab CI/CD 最重要的事情是:

仔細地想像、規劃流程,專注在團隊期望達成的效果!再來考慮如何實現。

by Arren Ping