5

背景

最近新开了一个新项目,本次项目老师要求我们部署在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目录中。

image.png

点击设置你的workflow就会在生成一个在.github/workflows目录下的文件main.yml

image.png

workflow文件提供了很多字段,下面列举一些workflow基本字段,

  1. name 工作流的名称
    如果省略name, GitHub会显示相对于存储库根目录的工作流文件路径。
  2. on 指定此工作流的触发器
单个事件
on: push

多个事件。
on: [push, pull_request]

可以限定标签。
push:
   tags:
     '*'
  1. 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。
  1. 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

image.png

  1. 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完成,
  1. 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任务都会重新定位到根目录

image.png

解决方法就是必须在同一个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

image.png

此时基于github action ci的demo就配置好了

三、实现pull request进行钉钉推送

虽然配置了CI(持续集成),这时候就有新的问题了,我们怎么样把运行成功之后通知我们呢,预想是跟之前gitlab一样实现钉钉推送,这时候我们肯定又要发挥程序员的强项,上Google

image.png

结果惊奇的发现老师在写了一篇文章就是关于pull request进行钉钉推送的,往下滑还有还一些关于dingtalk推送的仓库

仓库链接:https://github.com/zcong1993/actions-ding

打开之后查看readme会发现使用例子

image.png

根据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发现没有啥问题。

image.png

解决问题

后面查看.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 }}'
           }
         }

完美实现钉钉推送

image.png

以后,每次修改后推送源码,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

kexiaobin
76 声望7 粉丝