本文目标
阅读本文你将有如下收获
- Github Actions是什么?
- Github Actions如何使用?
- 案例讲述使用Github Actions打包构件,rsync免密登陆,同步代码到cvm,ssh远程命令行修改发布回滚
Github Actions 是什么?
官方解释:Automate your workflow from idea to production
简言之:它是github推出的持续集成部署的工具,目前优秀的cicd工具包括:travis ci,jenkins
你可以这么理解:经过一个动作(自动触发、手动触发、定时触发)唤醒它,剩下操作(actions)它来做
(例如:打包、构建、集成、测试、预发布、打镜像、上生产...,只有你想不到的,没有它做不到的)
Github Actions 如何工作的?
为了把概念讲的通俗易懂,我们来看个
点餐流程
如下图:
github actions的概念名词
如下图:
名次解释
- workflow (工作流水线):多个任务组成的工作流,
一个项目下可以有多条工作流
水线。 - on (触发时机):可以
定时触发
,可以监听push
,pr
触发,可以监听分支,文件夹,tags等,非常之多
。 - jobs (阶段任务):一个流水线由多个任务组成,每个任务有
单独的运行环境
,任务可以并行
,可以串行
。 - steps(操作步骤):阶段任务由多个操作步骤组成,操作步骤
串行
。 - actions (操作动作):每个步骤所需要的工具,可以理解为每一步骤内的
小操作点
。官方提供了插件市场
,还可以自己编写,目前支持js和docker两种创建方式。
两外还需要了解两个重要的参数
- runs-on(任务的环境):目前官网提供三种环境,支持self-host
- env (环境变量):支持github私有变量,workflow全局变量,job、step局部变量
项目及文档结构
使用前提:需要创建github仓库(公有、私有仓库都可以使用)
根据上图我们模拟一份yml来介绍名词
项目文件夹结构
代码语言:javascript复制order_proj/ // ---> 仓库名
--.github/ // ---> .github文件夹 必须
----workflows/ // ---> workflows文件夹 必须
------order.yml // ---> 工作流程文件 必须
--src/ // ---> 源代码
order.yml文件内容结构
代码语言:javascript复制name: GitHub Actions order.yml
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
// 煮饭任务
job1_zhufan:
// 在哪里执行任务
runs-on: ubuntu-latest
steps:
// 把米装进盒子,拉取代码
- name: box
uses: actions/box@master
// 清洗
- name: wash
uses: actions/wash@master
// 开始煮饭
- name: steam
uses: actions/steam@master
env:
// 设定的煮饭的时间
set_time: 10000
// 并行煮菜
job2_zhucai:
...
// 前两步完成打包
job3_dabao:
needs: [job1, job2]
...
// 打包完成配送
job4_paisong:
needs: job3
...
举例说明
经过上面的说明,相信你应该对github actions 是什么应该有个大致的了解了,接下来我们用一个例子实践一下
- 案例说明:主要内容是动态构建前端代码,将构件压缩包发布到远程机器,创建软连,修改生产文件夹软连指向的模拟
- 环境依赖:github仓库,任意配置的一台cvm机器
- 案例所需要了解的知识:ssh免密登陆
- 所用到的action插件
- actions/checkout@v2 :拉代码
- actions/cache@v1:缓存
- actions/upload-artifact@v1:打包上传构件
- actions/download-artifact@v1:下载构件
- easingthemes/ssh-deploy@v2.0.7:ssh-deploy部署插件
- contention/rsync-deployments@v1.0.0:rsync同步插件
- appleboy/ssh-action@master:ssh命令行插件
先把rsync搞明白
搞明白谁免密登陆谁,私钥存在哪里,公私钥怎么生成
前文已经讲过,每个job会有独立的运行环境(runs-on),使用rsync或者ssh-action两个工具的时候才会用到免密登陆
先看张图,理解一下机器环境配置
ssh公私钥生成
代码语言:javascript复制记住在生成机器上为github actions构建机创建单独的用户
# 在rs2创建专属账户,生成公私钥
# 注意:gid和uid均为1212,此为示例,也可以选用其它值,只要保证不和现有的用户和组冲突
cat /etc/group
# "-m"表示要为github用户创建home目录,即/home/github/
# 创建用户组github
$ groupadd -g 1212 github
# 创建github用户,并加入github用户组
$ useradd -m -s /bin/bash -g 1212 -u 1212 github
# 为github创建.ssh目录
$ mkdir /home/github/.ssh
$ chown github:github /home/github/.ssh
# 要上传的文件夹$ chown github:github /home/rsynctest
# 注意上面文件夹的权限,要限制用户权限在此文件加下操作
# 在哪一台机器上创建公私钥都可以,但是要登陆或者目标主机要存放公钥,存放在当前用户的.ssh/
# [rs2] 用ssh-keygen生成密钥
[root@xxxx ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): //rsync_id_dsa
Enter passphrase (empty for no passphrase): //输入空
Enter same passphrase again: //输入空
Your identification has been saved in /home/github/rsync_id_dsa.
Your public key has been saved in /home/github/rsync_id_dsa.pub.
# 将公钥存放在.ssh目录下
cp /home/github/rsync_id_dsa.pub /home/github/.ssh
# 公钥导入/home/github/.ssh/的authorized_keys文件
$ cd /home/github/.ssh
$ cat rsync_id_dsa.pub > authorized_keys
$ chown github:github authorized_keys
# 将私钥内容存储到github-->仓库-->setting--->secret
编写workflow文件
代码语言:javascript复制name: deploy
on:
push: # 当发生推送事件时
tags: # 当推送 tag 时
- v*
branches: # 当推送分支时
- master
#paths: [ src/* ]
pull_request: # 当发生合并事件时
branches:
- master
# 流水线变量查看:https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables
env:
WORKFLOW_ID: ${{github.run_id}}
WORKFLOW_NUMBER: ${{github.run_number}}
WORKFLOW_WORKSPACE: ${{github.workspace}}
WORKFLOW_COMMITID: ${{github.sha}}
BUILD_SCRIPT: "npm run newprod"
ARGS: "-rltgoDzvO --delete"
TARGET: "/home/rsynctest/vwork${{github.run_number}}" # 这个一定是rsync 用户的有权权限的目录
WWWROOT_DIR: "/home/rsynctest"
REMOTE_HOST: ${{ secrets._HOST }}
REMOTE_PORT: ${{ secrets._PORT }}
REMOTE_USER: ${{ secrets._USERNAME }}
SSH_PRIVATE_KEY: ${{ secrets._SECRET }}
jobs:
build: # 构建安装依赖,构建文件
name: "Build"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2 # 拉去分支
- name: Cache node modules #缓存依赖
uses: actions/cache@v1
env:
cache-name: cache-node-modules
with:
path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
# - name: Install Dependencies
# run: npm i
#
# - name: Npm run build
# run: $BUILD_SCRIPT
- run: mkdir dist && echo 3333> dist/index.html
- run: mkdir zip
- run: cd dist && zip -rq dist.zip ./* && mv dist.zip ../zip
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
name: dist
path: zip
deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest
steps:
- name: Download result
uses: actions/download-artifact@v1
with:
name: dist
- run: ls -la
# use ssh-deploy
# - uses: easingthemes/ssh-deploy@v2.0.7
# env:
# SSH_PRIVATE_KEY: ${{ secrets._SECRET }}
# ARGS: "-rltgoDzvO --delete"
# #SOURCE: dist/
# SOURCE: ./dist.zip
# REMOTE_HOST: ${{ secrets._HOST }}
# REMOTE_USER: ${{ secrets._USERNAME }}
# TARGET: ${{env.TARGET}}
# use rsync-deployments
- name: rsync deployments
uses: contention/rsync-deployments@v1.0.0
env:
DEPLOY_KEY: ${{env.SSH_PRIVATE_KEY}}
UPLOAD_DIR: ${{env.TARGET}}
with:
args: "-avzr --delete ${{env.REMOTE_USER}}@${{env.REMOTE_HOST}}:${{env.UPLOAD_DIR}}"
# use ssh-commands
- name: Switch SoftLink
uses: appleboy/ssh-action@master
env:
softlinkname: "test.vwork"
with:
host: ${{ env.REMOTE_HOST }}
username: ${{ env.REMOTE_USER }}
key: ${{ env.SSH_PRIVATE_KEY }}
port: ${{ env.REMOTE_PORT }}
script_stop: true
script: |
cd ${{env.TARGET}}
unzip -o dist/dist.zip -d .
rm -rf dist
ls -la
cd ${{env.WWWROOT_DIR}}
if [ ! -L "${{env.softlinkname}}" ]; then
if [ -d "${{env.softlinkname}}" ]; then
rm -rf ${{env.softlinkname}}
fi
ln -snf "vwork${{github.run_number}}" "${{env.softlinkname}}"
fi
pre_link=`readlink -f ${{env.softlinkname}}`
echo "$pre_link" > "${{env.WWWROOT_DIR}}/pre_link_${{env.softlinkname}}"
# 清理文件
# 切换软连
ln -snf "vwork${{github.run_number}}" "${{env.softlinkname}}"
ls -la
exit 0
最后,你可以提交代码触发测试一下
感谢阅读,不足和错误欢迎指正,没有更多了end
资料链接:
- 官方文档:https://help.github.com/en/actions
- 插件市场:https://github.com/marketplace?type=actions
- travis-ci:https://travis-ci.org/
- jenkins:https://jenkins.io/zh/
- 腾讯云:https://cloud.tencent.com