likes
comments
collection
share

使用Github Actions来实现项目的CI/CD

作者站长头像
站长
· 阅读数 3

前言

在开发自己博客站的时候,因为没有专业的产品和设计指导,都是随缘开发,所以就导致了一个频繁升级发布的问题。但是这个发布又是一个非常繁琐重复的过程,所以在想为什么不用持续发布系统机器来帮我做这个重复繁琐的过程呢。

想起原来公司用过Jenkins来做自动发布,去网上查看了一波资料,发现jenkins是依赖java的,而且功能非常强大,生态非常完善,而且构建成本特别高,显然不适合这样的小项目。又分别了解了下Travis CICircleCI,各有各的好,而且也是基于第三方的一个平台,上手起来简单方便,但是也是需要接入第三方平台。

对于一个独立开发者来说,简单方便和快捷永远是第一选择,所以最终还是选择了用GitHub Actions来实现自动发布,因为要使用 Actions 是件容易的事情,前提只要你的 Repo 源同 GitHub 关联,关联之后根据以下操作就能实现部署自动化。

GitHub Actions

GitHub Actions GitHub 推出的持续集成服务,GitHub把抓取代码/测试/登录远程服务器/发布/部署项目等操作称之为actions。

基本的概念

工欲善其事,必先利其器;欲利驭于器,需先识其基。

workflow

工作流程,持续集成一次运行的过程,就可以称之为一个workflow

  1. name

    工作流程的名称(可空),如果设置,则会在GitHub的操作页面上显示工作流的名称

  2. on

    触发工作流的事件名称。譬如发起的push/pull_request等操作触发。可以只监听某一个事件string,或者多个事件。可以触发工作流程的事件

    # 示例1 监听push操作,任意push都会被触发
    on: push
    
    # 示例2 监听任意的push和pull_request
    on: [push, pull_request]
    
    

    上面的两个示例,就可以在制定的git操作是出发工作流了,但是实际开发中会新建很多分支,而且为了更好的管理流程,会有对应的dev/uat/prod...等等一系列的对应指定环境的分支名称和发布动作,这时候就会发现上面的两个示例已经不够满足需求了,这时候就不仅需要监听操作,同时也要监听对应的分支名称。

    # 示例3 监听master(和其他)分支上的push事件
    on:
      push:
        branches: [ master ]
    
job

任务,任务是工作流的主体,一个工作流由一个任务(job)或者多个任务(jobs)构成,表示一次持续集成的运行

  1. job_id

    每个任务都必须要有个id,其实就是一个字符串

  2. runs-on

    任务运行的虚拟环境,必须要指定,不然无法工作

    # 目前可用的环境
    Windows Server 2019     windows-latest  windows-2019
    Ubuntu 20.04            ubuntu-20.04
    Ubuntu 18.04            ubuntu-latest  ubuntu-18.04
    Ubuntu 16.04            ubuntu-16.04
    macOS Catalina 10.15    macos-latest  macos-10.15
    
    # 使用
    runs-on: ubuntu-latest
    
step

步骤,每个任务由多个step构成,通过一个多或者多个步骤完成一个任务。可以在运行命令、运行任务、运行仓库中的操作、docker注册表中发布操作。

注意点: 不是所有的step都会运行操作,但是所有的操作都会作为step运行,每个step在虚拟环境中都会有个独立的进程,可以访问工作区和文件系统。

  1. name

    步骤名称

  2. run

    该步骤运行的命令或者 action

  3. env

    该步骤所需的环境变量

  4. uses

    选择任务步骤中一部分运行的操作。其实就是步骤使用的actions,可以是一个或多个

action

动作,每个步骤都可以依次执行一个或者多个动作。因为很多操作在不同项目中都是类似的,所以GitHub把action设计为一个独立的脚本文件,可以存放到代码仓库里,让其他开发者使用。所以在实际的使用中,可以直接使用别人写好的action而不必所有的都自己写。GitHub也为此做了一个marketplace,这里就是action的官方市场,可以搜索到别人提交的actions。

项目实战

GitHub Actions的配置文件放在代码仓库的.github/workflows目录中,workflow文件采用YMAML格式,文件名可以任意取,但是后缀名统一为.yml,比如ci.yml/build.yml,一个库可以有多个workflow文件,而且GitHub只要发现.github/workflows目录中有.yml文件,就会自动运行该文件,而不需要我们做额外的配置。

开始构建一个workflow也很方便快捷,只要按照上述12步骤操作,就可以生成一个简单的action了。 使用Github Actions来实现项目的CI/CD 了解完GitHub Actions的基本概念和术语之后,来进行项目的部署

一、web项目部署到nginx

在项目的.github/workflows中新建一个ci.yml文件

# 建立一个名为CI的工作流
name: CI

# 监听 master上的push事件
on:
  push:
    branches: [ master ]

# 开始任务
jobs:
  # 建立一个名为 build 的job
  build:
    # 在最新的乌班图环境进行工作
    runs-on: ubuntu-latest

    # 开始设置构建步骤
    steps:
    # 这是github官方的一个action,用于clone该仓库的源码到工作流中,
    - uses: actions/checkout@v2

    # 命名这个步骤为构建Build
    - name: Build
      // 运行 安装和打包任务
      run: npm install && npm run build

    # 命名这个任务为发布Deploy
    - name: Deploy
      # 因为构建之后,需要把代码上传到服务器上,所以需要连接到ssh,并且做一个拷贝操作
      uses: cross-the-world/scp-pipeline@master
      env:
        WELCOME: "ssh scp ssh pipelines"
        LASTSSH: "Doing something after copying"
      with:
        host: ${{ secrets.TG_HOST }}
        user: ${{ secrets.TG_USER }}
        pass: ${{ secrets.TG_PASS }}
        connect_timeout: 10s
        local: './dist/*'
        remote: /usr/share/nginx/html
        

上面的示例,还有一个点要特别注意,就是因为ci.yml文件是可以被访问到的,但是发布的时候又需要连接到服务器上去替换文件,这时候就涉及到一个连接服务器的问题。那为了保护隐私,就需要借助GitHub的Secrets

使用Github Actions来实现项目的CI/CD 上述3操作后则会出现如下设置,TG_HOST和xxx.xxx.xxx.xxx都可以按照实际的需求去进行设置,点击Add secret之后,就会得到列表4

使用Github Actions来实现项目的CI/CD

这时候,我们再把设置的内容反馈到ci.yml中

host: ${{ secrets.TG_HOST }}
user: ${{ secrets.TG_USER }}
pass: ${{ secrets.TG_PASS }}

配置完成之后,只需要在master上做一个提交动作,GitHub就会去执行打包发布的指令了。

使用Github Actions来实现项目的CI/CD 这时候打开网页,就会发现,你更新的代码已经自动发布好了。

当然,有的时候可能会因为一些失误,或者不确定做调试,也会有出错的时候,这时候也不必慌,可以进入到ci查看问题出在哪儿,然后一步一步解决,最终完善配置。

使用Github Actions来实现项目的CI/CD

二、node项目部署到云服务

部署node项目和web项目其实主要的流程还是一样的,但是有个区别就是,因为node项目是用pm2来守护进程的,而pm2又没有开启watch,并且node项目是没有经过打包的,所以如果按照web项目来部署的话,一旦遇到某些依赖更新的时候,就会遇到意想不到的问题。所以比较合理的解决方法就是,在代码更新之后,到服务器上再执行一边install操作和pm2 reload操作

name: CI/CD
on:
  push:
    branches: [ master ]
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
    - name: Deploy
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.TG_HOST }}
        username: ${{ secrets.TG_USER }}
        password: ${{ secrets.TG_PASS }}
        # 上面的流程都跟web项目类似,只有下面运行脚本不一致
        script: |
          cd Documents/frivolous/drip-flow-node/
          git pull
          export NODE_HOME=/usr/local/lib/nodejs/node-v12.18.1-linux-x64
          export PATH=$PATH:$NODE_HOME/bin
          npm install
          npm run prod

  1. cd Documents/frivolous/drip-flow-node/

    因为我用的是再服务器上存储同步代码的方式,所以第一步需要进入到对应的项目地址

  2. git pull

    第二步就是做一个同步代码的操作,从远程GitHub仓库拉取代码

  3. export NODE_HOME=/usr/local/lib/nodejs/node-v12.18.1-linux-x64
    export PATH=$PATH:$NODE_HOME/bin
    

    这一步是重点,因为虽然已经通过ssh-action连接上服务器上了,但是并不是在真实的服务器上,所以可能会出现npm指令不存在的问题

使用Github Actions来实现项目的CI/CD 经过上网一顿搜索和不断的实验,最终得出应该是环境问题(个人猜想GitHub Actions就是一个应用容器引擎,然后配置交叉编译工具链的时候,并不能获取到真实的路径,所以需要指定编译工具的路径,就是需要设置环境变量)。所以重新设置了一些环境变量,在执行install的时候,npm就可以正常执行了。

-   服务端上通过`whereis node`就找到了node的目录,所以直接copy后再设置一下环境变量即可。

使用Github Actions来实现项目的CI/CD 4. npm install

重新安装依赖,避免有开发中有新的模块没有装或者包版本号有变动

5. npm run prod

这一步就是把代码编译为可执行状态,同时重新reload一下进程守护。

```
npm run tsc && pm2 reload pm2.json
```

这样流程下来的话,就可以完成代码push之后自动发布部署了。

总结

其实实战下来,还算比较好用和方便。并且给我们的开发节省了特别多的发布部署操作。懒人改变和改造时间,懒人yyds!!

转载自:https://juejin.cn/post/7003278731171069982
评论
请登录