文档章节

编写自己的 GitHub Action,体验自动化部署

张凯强-zkqiang
 张凯强-zkqiang
发布于 01/20 13:20
字数 1953
阅读 5.7K
收藏 9

本文将介绍如何使用 GitHub Actions 部署前端静态页面,以及如何自己创建一个 Docker 容器 Action。

简介 Actions

GitHub Actions 是 GitHub 官方推出的持续集成/部署模块服务(CI/CD),和 jenkins、Travis CI 是同一类产品定位。

但 Actions 的最大优势,就是它是与 GitHub 高度整合的,只需一个配置文件即可自动开启服务。甚至你不需要购买服务器 —— GitHub Actions 自带云环境运行,包括私有仓库也可以享用,而且云环境性能也十分强劲。

当然这也意味着项目必须存放在 GitHub 才能享受这项服务。如果你的 GitHub 上有一些项目需要部署,那不妨把构建、上传等工作放到 Actions 里。比如最近我有个前端项目需要打包成静态文件,然后上传到腾讯云 COS 里,这是典型的自动化部署应用场景,我们可以借助 Actions 实现一劳永逸。

配置 workflow

前文说到,开启 GitHub Actions 只需一个配置文件,这个文件就是 workflow(工作流),它需要存在仓库目录下 .github/workflows/*.yml,文件名任意,但需要是一个 YAML 配置文件。

这个文件用来规定自动化操作在什么时候触发启动,然后需要做哪些事情,比如这样:

name: Deploy

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout master
        uses: actions/checkout@v2
        with:
          ref: master

      - name: Setup node
        uses: actions/setup-node@v1
        with:
          node-version: "10.x"

      - name: Build project
        run: yarn && yarn build

      - name: Upload COS
        uses: zkqiang/tencent-cos-action@master
        with:
          args: delete -r -f / && upload -r ./dist/ /
          secret_id: ${{ secrets.SECRET_ID }}
          secret_key: ${{ secrets.SECRET_KEY }}
          bucket: ${{ secrets.BUCKET }}
          region: ap-shanghai

首先配置里所有 name 都是可以自定义的,只是用于可视化中进行识别。

on: 用来指定启动触发的事件,push 则表示在监听到 git push 到指定分支时触发。如此之外还可以是 pull_request

jobs: 是工作任务,可以包含多个 job,并且每个 job 是独立的虚拟环境。不同 job 之间默认是并行的,如果想顺序执行,可以这样 build-job: needs: test-job

runs-on: 用来指定执行系统环境,不仅有常用的 Linux 发行版,还可以是 macOS 或 Windows。

steps: 表示每个 job 需要执行的步骤,比如这里我分成了四步,拉取分支 → 安装 Node 环境 → 构建项目 → 上传 COS。

uses: 指的是这一步骤需要先调用哪个 Action。

Action 是组成工作流最核心最基础的元素。每个 Action 可以看作封装的独立脚本,有自己的操作逻辑,我们只需要 uses 并通过 with 传入参数即可。

比如 actions/checkout@v2 就是官方社区贡献的用来拉取仓库分支的 Action,你不需要考虑安装 git 命令工具,只需要把分支参数传入即可。

更多 Action 你可以通过 GitHub 顶部的 Marketplace 里找到,不过问题来了,我在其中搜索腾讯 COS 并没有找到相关 Action。

腾讯官方提供了 coscmd 命令行工具,是基于 Python 开发,很可惜没有二进制版本。因此如果使用在 Actions 中,就必须有 Python 环境,有两种思路:

  1. 在 Steps 里加入 actions/setup-python 这一步骤安装 Python 环境,然后再使用 pip install coscmd
  2. 将上面的步骤封装成独立的 Action,之后直接 uses 即可。

第一种很简单,可以在 steps 里加入:

steps:
- uses: actions/setup-python@v1
  with:
    python-version: '3.x'
    architecture: 'x64'

- name: Install coscmd
  run: pip install -U coscmd

- name: Upload COS
  run: |
    coscmd config ....
    coscmd upload -r ./dist/ /

但是我选择了第二种,顺便了解如何创建自己的 Action。

创建 Docker 容器 Action

官方提供了两种方式创建 Action,一种是使用 JavaScript 环境创建,另一种是通过 Docker 容器创建。coscmd 既然依赖 Python,这里使用 Docker 容器更简单一些。

创建 Dockerfile

那我们首先创建一个 Dockerfile:

FROM python:3.7-slim

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pip install --upgrade --no-cache-dir coscmd

COPY "entrypoint.sh" "/entrypoint.sh"
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

如果不了解 Docker 也没关系,只需要知道 FROM 是指定容器环境,然后 RUN 去执行 pip install coscmd 的操作。最后将仓库目录下的 entrypoint.sh 拷贝到容器中,并用 ENTRYPOINT 执行,至于这个 sh 文件后面再说 。

创建 action.yml

这里定义了 Action 相关的配置:

name: 'Tencent COS Action'
description: 'GitHub Actions for Tencent COS Command'
author: 'zkqiang <zkqiang@126.com>'
branding:
  icon: 'cloud'
  color: 'blue'
inputs:
  args:
    description: 'COSCMD args'
    required: true
  secret_id:
    description: 'Tencent cloud SecretId'
    required: true
  secret_key:
    description: 'Tencent cloud SecretKey'
    required: true
  bucket:
    description: 'COS bucket name'
    required: true
  region:
    description: 'COS bucket region'
    required: true
runs:
  using: 'docker'
  image: 'Dockerfile'

除了一些描述性信息,最重要的是定义 input: args 输入参数,也就是 step 里 with 传递的参数,可以通过 required 设置该参数是否必传。这里传递的参数都是识别和验证对象桶的必需参数。

最后通过 runs 指定 docker 环境和 Dockerfile 文件。

创建 entrypoint.sh

这里需要使用 shell 来写传递参数后的执行逻辑,由于 coscmd 本身就是命令行工具,所以我们只需将参数再传给它即可。

#!/bin/bash

set -e

if [ -z "$INPUT_ARGS" ]; then
  echo 'Required Args parameter'
  exit 1
fi

# ...省略部分代码

coscmd config -a $INPUT_SECRET_ID -s $INPUT_SECRET_KEY -b $INPUT_BUCKET -r $INPUT_REGION -m $THREAD

IFS="&&"
arrARGS=($INPUT_ARGS)

for each in ${arrARGS[@]}
do
  unset IFS
  each=$(echo ${each} | xargs)
  if [ -n "$each" ]; then
  echo "Running command: coscmd ${each}"
  coscmd $each
  fi
done

action.yml 中的参数会自动转成 INPUT_ 前缀并且大写的变量传入,因此我们可以直接引用。

验证完参数之后(也可省略,action.yml 已判断),先配置 coscmd config,然后将 args 参数传入 coscmd 即可。另外为了方便使用多条命令,加入了支持 && 连接命令,脚本里需要对其分割。

调用自建的 Action

将刚才创建的 Action 推送到 GitHub 上,就调用这个 Action 了,前文的 workflow 配置里也已经包含了:

name: Upload COS
uses: zkqiang/tencent-cos-action@master
with:
  args: delete -r / && upload -r ./dist/ /
  secretId: ${{ secrets.SECRET_ID }}
  secretKey: ${{ secrets.SECRET_KEY }}
  bucket: ${{ secrets.BUCKET }}
  region: ap-shanghai

args: delete -r -f / && upload -r ./dist/ /,相当于先清空对象桶,然后再执行上传。deleteupload 都是 coscmd 自己的命令参数,其他命令可以查阅官方文档。

另外有没有注意到 ${{ secrets.XXX }} 这种参数,并不是具体的值,而是调用了 GitHub Settings 里保存的 secrets,添加方式如下:

设置 secrets 的步骤

为什么这样做?是因为 workflow 代码在公开仓库中也是任意可见的,如果将 SecretKey 这些信息暴露,等于将 COS 操作权限交出,而存在 settings 里则不会有这个问题。

然后就可以使用 Actions 功能了,向包含 workflow 的仓库 master 分支推送一次代码,如果没有配错的话,过段时间可以在 Actions 栏里看到一列绿色的对号。

Actions 执行结果

结语

至此我们了解了如何使用 GitHub Actions 部署,以及如何自己创建一个 Action,可见这一项免费的服务真的非常好用,借助 Action 开源市场也可以大幅简化使用。

当然 CI 的应用不仅仅在部署这方面,绝大部分从开发完成到交付/部署之间的动作也都可以用自动化完成,只要是重复的操作就应该考虑能不能加入自动化来解放双手。

本文 COS Action 的代码仓库

workflow 官方文档

更多的 Actions 可以从 Marketplaceawesome-actions 里获取。


本文属于原创,首发于微信公众号「面向人生编程」,如需转载请后台留言。

© 著作权归作者所有

张凯强-zkqiang

张凯强-zkqiang

粉丝 9
博文 6
码字总数 7033
作品 2
杭州
程序员
私信 提问
加载中

评论(2)

robortly
robortly
有没有 Asp.Net Core 的实践
sndnvaps
sndnvaps
写得不错,我也要实践一下。。
前端自动化部署方案探索(二):Jenkins篇

碎碎念 工作日每天回到家只想睡觉,拖到现在才开始写这篇文章,不得不说只有周末在闲暇之余才有心情写自己的代码或者文章。 前言 上一篇讲了如何使用Docker去部署应用,但其实在自动化部署的...

Lymon
2019/06/03
0
0
Hexo遇上Travis-CI:可能是最通俗易懂的自动发布博客图文教程

相信很多同学都有自己的博客,如果没有,可以参看《Hexo建站:部署到github》,利用Hexo和github pages服务搭建一个美观便捷的博客,Hexo可以将你编写的md文档解析渲染成html网页,最后通过g...

MichaelX
2018/10/30
0
0
Github Actions:再次改变软件开发

本文转自 FEPulse 公众号(微信搜索 FEPulse,精选国内外最新前端资讯,为你把握前端脉搏)。 Github Actions 是 GitHub Universe 大会上发布的,被 Github 主管 Sam Lambert 称为“再次改变...

CompileYouth
2018/10/22
0
0
Github Actions 初探

简单介绍 是推出的一个新的功能,可以为我们的项目自动化地构建工作流,例如代码检查,自动化打包,测试,发布版本等等。入口在项目的旁边。 私有仓库现在应该很多同学都可以看到了,公有的因...

linliqzh
2019/02/17
0
0
简述 Microservices(微服务)

原文同步至 自 2014 年始,Microservices(微服务)一词越来越火爆,不谈 Microservices 彷佛就 out 了。那么什么是 Microservices?Microservices 架构与传统的架构有什么区别?何时应该采用...

waylau
2016/02/19
3.5K
4

没有更多内容

加载失败,请刷新页面

加载更多

在两个日期之间查找对象MongoDB

我一直在围绕在mongodb中存储推文,每个对象看起来像这样: {"_id" : ObjectId("4c02c58de500fe1be1000005"),"contributors" : null,"text" : "Hello world","user" : { "following......

javail
25分钟前
35
0
《aelf经济和治理白皮书》重磅发布:为DAPP提供治理高效、价值驱动的生态环境

2020年2月17日,aelf正式发布《aelf经济和治理白皮书》,这是aelf继项目白皮书后,在aelf网络经济模型和治理模式方面的权威论述。 《aelf经济和治理白皮书》描述了aelf生态中各个角色及利益的...

AELF开发者社区
36分钟前
44
0
EditText的首字母大写

我正在开发一个小小的个人待办事项列表应用程序,到目前为止,一切都运行良好。 我想知道一个小怪癖。 每当我去添加一个新项目时,我都会看到一个带有EditText视图的Dialog。 当我选择EditT...

技术盛宴
40分钟前
30
0
战疫 | 高德工程师如何在3天上线“医护专车”

新冠状病毒肺炎疫情突袭,无数医护人员放弃与家人团聚,明知凶险,仍然奋战在一线。但因为武汉公交、地铁、网约车停运,医护人员上下班很难。白衣天使疾呼打车难。 (截图摘自《财经国家周刊...

amap_tech
47分钟前
41
0
img在IE中无法按比例显示

在IE浏览器中使用img标签当给img标签设置width:98%时,显示时还是会把img的原始高度显示出来 解决方式给父标签设置width,但width不能使用100%需要指定一个值 <div style="width:900px;"> ...

有理想的鸭子
48分钟前
45
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部