使用Spring Boot設定GitLab CI/CD管道 - Marcus

banq發表於2022-03-05

當我們將專案放在 GitLab 儲存庫中時,我們需要做的第一件事。我們需要建立一個.gitlab-ci.yml來初始化管道:

# Adding workflow rules to avoid other branches to use the pipeline 
# since we only want to use the master branch
workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_COMMIT_BRANCH == 'master'

variables:
  IMAGE_OPENJDK_GRADLE: gradle:7.3.3-jdk17-alpine

stages:
  - clean
  - build
  - test
  - build-image
  - publish-image
  - deploy

clean:
  image: $IMAGE_OPENJDK_GRADLE
  stage: clean
  script:
    - echo "Cleaning leftovers from previous builds"
    - sh $CI_PROJECT_DIR/gradlew clean

build:
  image: $IMAGE_OPENJDK_GRADLE
  stage: build
  script:
    - echo "Compiling the code..."
    - sh $CI_PROJECT_DIR/gradlew assemble
  artifacts:
    paths:
      - build/libs/blog-*.war

static-code-analysis:
  image: $IMAGE_OPENJDK_GRADLE
  stage: test
  script:
    - echo "Running Static Code Analysis..."
    - echo "Checking style..."
    - sh $CI_PROJECT_DIR/gradlew checkstyleMain
    - echo "Checking duplicated code..."
    - sh $CI_PROJECT_DIR/gradlew cpdCheck
    - echo "Checking bugs..."
    - sh $CI_PROJECT_DIR/gradlew spotbugsMain
    - echo "Checking code standard..."
    - sh $CI_PROJECT_DIR/gradlew pmdMain

unit-test:
  image: $IMAGE_OPENJDK_GRADLE
  stage: test
  script:
    - echo "Running unit tests..."
    - sh $CI_PROJECT_DIR/gradlew test -Dspring.profiles.active=test

coverage-test:
  image: $IMAGE_OPENJDK_GRADLE
  stage: test
  needs:
    - job: unit-test
  script:
    - echo "Running coverage tests..."

build-image:
  stage: build-image
  script:
    - echo "Building Docker Image..."
    - docker build -t $CI_REGISTRY/mjovanc/blog-api:$CI_COMMIT_SHORT_SHA .
    - docker build -t $CI_REGISTRY/mjovanc/blog-api:latest .

publish-image:
  stage: publish-image
  script:
    - echo "Publishing Docker Image..."
    - docker login -u mjovanc -p $MJOVANC_CONTAINER_REGISTRY_TOKEN $CI_REGISTRY
    - docker push $CI_REGISTRY/mjovanc/blog-api:$CI_COMMIT_SHORT_SHA
    - docker push $CI_REGISTRY/mjovanc/blog-api:latest

# Alternative down stream pipeline to be triggered
deploy:
#  stage: deploy
#  trigger: mjovanc/blog-iac


 
以下是上述配置解釋:
1. 首先,我們定義工作流workflow規則,只有當新的程式碼進入主分支時,我們才進行構建。這樣我們就可以推送功能分支,即使它們處於失敗的狀態,也可以在上面工作。這樣我們就不需要每次都去構建,也不需要在構建後推送到容器登錄檔。

workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - if: $CI_COMMIT_BRANCH == 'master'


也許你可以刪除它並設定檢查器,如果不在主分支上,我們將在構建和測試後跳過其他階段。但現在我們將使用它所定義的階段。

2. 然後,我們定義一個變數,其中包含將用於構建我們的應用程式的Docker映象,這將是帶有OpenJDK17的Gradle。
variables:IMAGE_OPENJDK_GRADLE: gradle:7.3.3-jdk17-alpine
 
3. 然後我們定義這個管道中的所有階段。這個階段是clean、構建、測試、構建映象(docker)、釋出映象(docker)和部署。我們在底部註釋掉deploy,因為它不會工作,因為我們現在沒有其他管道。我們將只透過它,以便我們知道如何觸發另一個管道,來完成部署我們的容器的工作。

stages:
  - clean
  - build
  - test
  - build-image
  - publish-image
  - deploy



你可以新增另一條管道,使用Kubernetes進行部署,或者使用Ansible在伺服器上手動部署。

4. 在每個作業上,我們都會定義它應該與哪個階段連線。

clean:
  image: $IMAGE_OPENJDK_GRADLE
  stage: clean
  script:
    - echo "Cleaning leftovers from previous builds"
    - sh $CI_PROJECT_DIR/gradlew clean

我們也有一個指令碼定義,應該在GitLab執行器上執行。
GitLab有共享的、群組的或特定的執行器,我們可以使用。如果我們需要比GitLab提供的更多的CPU、記憶體等或軟體,我們可以建立自己的執行器。但現在我們將使用自動新增的共享GitLab執行器。非常方便!
 
5. 你可以看到在GitLab的流水線配置中,我們有一個叫做 "needs "的配置項,它告訴流水線,在另一項工作完成之前,這個階段不能執行。在這個例子中,我們不會在單元測試透過之前執行覆蓋率測試。如果我們把許多工作放在同一個階段,就像我們在階段測試中做的那樣,它將並行執行。所以它將嘗試在同一時間做所有的工作。

coverage-test:
  image: $IMAGE_OPENJDK_GRADLE
  stage: test
  needs:
    - job: unit-test
  script:
    - echo "Running coverage tests..."


 
6. 為了構建docker映象,我們需要進行如下配置。

build-image:
  stage: build-image
  script:
    - echo "Building Docker Image..."
    - docker build -t $CI_REGISTRY/mjovanc/blog-api:$CI_COMMIT_SHORT_SHA .
    - docker build -t $CI_REGISTRY/mjovanc/blog-api:latest .


我們使用docker命令在當前目錄下構建,並尋找我們的Docker檔案,我們透過內建的環境變數$CI_REGISTRY來標記它,並新增company/organization/user和應用程式的名稱。

我們還新增了提交的SHA256雜湊值(短版本,不是完整的值),這樣我們就可以有一個唯一的構建ID。

然後,我們還建立了第二個映象,但使用latest作為ID,所以如果我們只是想抓取最新的版本,我們總是可以拉到那個映象。如果需要回滾,我們仍然有舊的構建,所以我們可以回到早期的提交。
  
7. 然後我們只需將新構建的映象推送到GitLab容器註冊中心即可。

publish-image:
  stage: publish-image
  script:
    - echo "Publishing Docker Image..."
    - docker login -u mjovanc -p $MJOVANC_CONTAINER_REGISTRY_TOKEN $CI_REGISTRY
    - docker push $CI_REGISTRY/mjovanc/blog-api:$CI_COMMIT_SHORT_SHA
    - docker push $CI_REGISTRY/mjovanc/blog-api:latest


 
8. 最後,我們新增一個部署階段,將觸發另一個管道的執行(可選)。

deploy:
  stage: deploy
  trigger: mjovanc/blog-iac



 
為了使這個管道工作,我們需要在GitLab中新增一些配置。我們首先需要生成一個個人訪問令牌。你可以在右上角你的個人資料圖片的地方選擇偏好preferences。然後導航到訪問令牌,把名字寫成MJOVANC_CONTAINER_REGISTRY_TOKEN,然後選擇api,read_registry,write_registry。
 
現在我們的管道可以透過.gitlab-ci.yml檔案中的變數獲得該令牌,並能夠推送新構建的映象。
我們可以在側邊欄 Packages & Registries > Container Registry下找到我們所有的映象(最新的在最後一頁,每當我們做新的推送時它就會更新)。
 
原始碼: https://github.com/mjovanc/medium-gitlab-cicd-springboot
 

相關文章