背景
最近新开了一个新项目,本次项目老师要求我们部署在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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。