背景
最近新開了一個新項目,本次項目老師要求我們部署在github上的,之前的項目都是部署在gitlab上,已經有一套寫好的ci/cd的配置方式,基本就是新項目一來就套着使用,而本次是部署在github上,也需要為項目配置ci/cd,算是重新學習一套新的東西。本篇文章主要內容是配置ci(持續集成)過程中遇到的問題和體會。
一、什麼是(CI)持續集成
持續集成 (CI) 是一種需要頻繁提交代碼到共享倉庫的軟件實踐。 頻繁提交代碼能較早檢測到錯誤,減少在查找錯誤來源時開發者需要調試的代碼量。 頻繁的代碼更新也更便於從軟件開發團隊的不同成員合併更改。 這對開發者非常有益,他們可以將更多時間用於編寫代碼,而減少在調試錯誤或解決合併衝突上所花的時間。
用通俗的解釋,當你提交代碼的時候,可以編寫shell命令執行你想要的操作,根據你要求的觸發要求進行觸發,如編譯代碼、運行測試等操作,從而能避免錯誤的發生,也不用每次提交代碼的時候在本地重複一遍操作。
二、利用Github Actions配置CI
1、 基本概念
- workflow (工作流程):持續集成一次運行的過程,就是一個 workflow。
- name:工作流程的名稱
- on:觸發工作流程的事件名稱
- job (任務):一個 workflow 由一個或多個 jobs 構成,含義是一次持續集成的運行,可以完成多個任務。
- step(步驟):每個 job 由多個 step 構成,一步步完成。
- runs-on:任務運行的系統環境
2、workflow 文件
GitHub Actions的工作流文件使用YAML語法,並且必須具有.yml或. YAML文件擴展名, 必須將工作流文件存儲在存儲庫的.github/workflows目錄中。
點擊設置你的workflow就會在生成一個在.github/workflows目錄下的文件main.yml
workflow文件提供了很多字段,下面列舉一些workflow基本字段,
- name 工作流的名稱
如果省略name, GitHub會顯示相對於存儲庫根目錄的工作流文件路徑。 - on 指定此工作流的觸發器
單個事件
on: push
多個事件。
on: [push, pull_request]
可以限定標籤。
push:
tags:
'*'
- jobs.<job_id>.name為作業設置一個名稱,workflow 文件的主體是jobs字段,表示要執行的一項或多項任務。
jobs:
unit-test:
name: angular test
spring-boot-test:
name: API test
angular-build:
name: web build
api-build:
name: API build
包含4個任務分別是unit-test、spring-boot-test、angular-build和api-build。
- jobs.<job_id>.runs-on 指定運行的虛擬機,這是github提供的免費的虛擬機,也可以通過定義託管服務器Self-hosted
job1:
runs-on: ubuntu-latest
job2:
runs-on: windows-latest
job3:
runs-on: macos-latest
job4:
runs-on: Self-hosted
- jobs.<job_id>.needs 能指定代碼的執行順序
jobs:
unit-test:
name: angular test
spring-boot-test:
name: API test
angular-build:
needs: [unit-test, spring-boot-test]
name: web build
api-build:
needs: [unit-test, spring-boot-test]
name: API build
上面任務中,unit-test、spring-boot-test必須先於angular-build、api-build完成,
- jobs.<job_id>.steps 字段指定每個 Job 的運行步驟,執行一個或者多個
* name:步驟名稱。
* run:該步驟運行的命令。
* env:環境變量。
* uses:引用其他倉庫中的操作、腳本或 Docker 容器
遇到的問題
- name: change to web directory
run: cd web
- name: print working directory
run: pwd
- name: install dependencies
run: npm install
從這裏發現每一個run任務都會重新定位到根目錄
解決方法就是必須在同一個run中完成你想要執行的命令,上面的方式就類似每次重開了一次termial
- name: test
run: |
pwd
cd web
env
npm install
下面一個基於angular和springboot完整案例
name: GitHub Actions
run-name: integrationTesting
#設置觸發時機
on:
pull_request:
branches: [ main ]
#每個 workflow 由多個 job 組成
#默認並行運行
jobs:
unit-test:
runs-on: ubuntu-latest
# 定義任務的步驟 串行
steps:
# 將倉庫的代碼檢出到當前工作目錄中
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 18.16.0
- name: angular-test
# 執行shell命令
run: |
pwd # 打印當前工作目錄
cd web # 切換到 web 目錄
env # 顯示環境變量信息
npm install # 安裝 Node.js 依賴
# 運行angular 單元測試
npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
# 構建 Angular 應用
npm run build
spring-boot-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: build mysql
run: |
docker pull mysql:8.0
docker run -p 3307:3306 -e MYSQL_ROOT_PASSWORD=yunzhi -e MYSQL_DATABASE=integrationTesting -d mysql:8.0 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- name: Set up JDK17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: springboot-test
# 執行shell命令
run: |
pwd
# 切換到 api 目錄
cd api
# 切換到 api 目錄
env #顯示環境變量信息
# 安裝 Maven 依賴
mvn install
# 顯示 Maven 版本信息
mvn -v
# 運行 Maven 測試
mvn test
# 使用批處理模式進行打包
mvn --batch-mode packageage
此時基於github action ci的demo就配置好了
三、實現pull request進行釘釘推送
雖然配置了CI(持續集成),這時候就有新的問題了,我們怎麼樣把運行成功之後通知我們呢,預想是跟之前gitlab一樣實現釘釘推送,這時候我們肯定又要發揮程序員的強項,上Google
結果驚奇的發現老師在寫了一篇文章就是關於pull request進行釘釘推送的,往下滑還有還一些關於dingtalk推送的倉庫
倉庫鏈接:https://github.com/zcong1993/actions-ding
打開之後查看readme會發現使用例子
根據README文檔開始了第一個推送demo
dingding-error:
runs-on: ubuntu-latest
needs: [unit-test, spring-boot-test]
steps:
- name: Send dingding notify error
uses: zcong1993/actions-ding@master
with:
dingToken: xxxx #釘釘token
body: |
{
"msgtype": "text",
"text": {
"content": '[打叉][打叉][打叉] 執行失敗\n提交者: ${{ github.triggering_actor }}\n任務: ${{ github.event.pull_request.title }}\n${{ github.ref_type }}: ${{ github.head_ref }}\n${{ github.event_name }}: ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.number }}'
}
}
結果出現了問題,robot type do not match with the message,仔細查看了example發現沒有啥問題。
解決問題
後面查看.github/workflows的demo
發現比example加多一句,之後就解決問題了
steps:
- uses: actions/checkout@v4
一個完整的釘釘推送
dingding-error:
runs-on: ubuntu-latest
needs: [unit-test, spring-boot-test]
if: ${{ failure() }}
steps:
- uses: actions/checkout@v4
- name: Send dingding notify error
uses: zcong1993/actions-ding@master
with:
dingToken: xxxx #釘釘token
body: |
{
"msgtype": "text",
"text": {
"content": '[打叉][打叉][打叉] 執行失敗\n提交者: ${{ github.triggering_actor }}\n任務: ${{ github.event.pull_request.title }}\n${{ github.ref_type }}: ${{ github.head_ref }}\n${{ github.event_name }}: ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.number }}'
}
}
dingding-success:
runs-on: ubuntu-latest
if: ${{ success() }}
needs: [unit-test, spring-boot-test]
steps:
- uses: actions/checkout@v4
- name: Send dingding notify success
uses: zcong1993/actions-ding@master
with:
dingToken: xxxx #釘釘token
body: |
{
"msgtype": "text",
"text": {
"content": '[微笑][微笑][微笑] 執行成功\n提交者: ${{ github.triggering_actor }}\n任務: ${{ github.event.pull_request.title }}\n${{ github.ref_type }}: ${{ github.head_ref }}\n${{ github.event_name }}: ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.number }}'
}
}
完美實現釘釘推送
以後,每次修改後推送源碼,GitHub Actions 都會自動運行,進行測試代碼後,如果成功會推送到釘釘。
五、參考資料
官網文檔: https://docs.github.com/en/actions/using-workflows/about-workflows
設置前台:https://docs.github.com/zh/actions/automating-builds-and-tests/building-and-testing-nodejs
設置後台: https://docs.github.com/zh/actions/automating-builds-and-tests/building-and-testing-java-with-maven
設置數據庫: https://github.com/mirromutth/mysql-action?tab=readme-ov-file
設置釘釘機器人推送:https://github.com/zcong1993/actions-ding