# Github 工作流
微软大大在这两年内动作很大,前后收购了 Github (opens new window) 和 NPM (opens new window) 两大与技术人员生活息息相关的应用。并且在收购后做了很多调整,就如同大家
可以很明显看到的 Github 在视觉设计上的改版,以及 新开辟了 Actions Packages 等新功能。来将之前散落在各个三方服务提供的功能统一收敛到官方实现当中。使得 Github Workflow + NPM Publish 的使用更加的丝滑。
# CI
在 Github Actions 出来之前,比较流行的开源 CI 服务分别是 CircleCI (opens new window) 以及 TravisCI (opens new window)。之前也有一些项目使用过这些第三方服务,但给人的体验都不是很好例如构建缓慢。特别是对于国内用户来说访问它们的资源实在是太慢了, 并且它们自身的功能也存在一点缺失。
# Github Actions
接下来让我们看看应用要如何接入 Github Actions (opens new window) 以 create-ssr-app (opens new window) 为例
# 创建配置文件
$ mkdir -p .github/workflows
$ touch .github/workflows/CI.yaml
# 监听 Git 命令
在 push 代码 以及 合并 PR 的时候触发 CI 工作
name: CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the dev branch
on:
push:
branches: [dev, master]
pull_request:
branches: [dev, master]
# 添加构建环境
这里推荐使用 build matix 来确保我们的应用可以在多个操作系统,多个语言版本中成功构建
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ["12", "13", "14"]
name: install - ${{ matrix.os }} - ${{ matrix.node }}
runs-on: ${{ matrix.os }}
# 定义job
我们的构建一般都包含多个任务,github 可以并行的执行这些任务来提升构建速度,并且可以指定任务之间的依赖关系
jobs:
install: # 定义安装依赖的任务
if: "!contains(github.event.head_commit.message, 'skip ci') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
strategy: # 分别在三个操作系统的三种 Node.js 环境中运行任务
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ["12", "13", "14"]
name: install - ${{ matrix.os }} - ${{ matrix.node }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: restore # 恢复之前缓存的依赖
uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package.json') }} # 依赖缓存的 key 当 package.json 内容变动时丢弃缓存 也可以使用 package-lock.json or yarn.lock
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}-nodemodules-
- name: Install dependencies # 安装依赖
run: |
yarn
测试 和 lint 任务需要依赖 install 任务执行完毕后才可以执行。但这两个任务之间没有依赖关系,可以并行的运行
test:
needs: install
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ["12", "13", "14"]
name: test - ${{ matrix.os }} - ${{ matrix.node }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: Load node_modules
uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package.json') }}
- run: yarn test # 执行测试并生成覆盖率,这里一般都是接入 codecov 服务,需要配置 CODECOV_TOKEN 环境变量才能够上传
lint:
needs: install
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ["12", "13", "14"]
name: lint - ${{ matrix.os }} - ${{ matrix.node }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: Load node_modules
uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package.json') }}
- run: yarn lint
# 构建产物并上传
我们的应用的运行代码通常是用构建工具 如 tsc|babel|webpack 来生成的。但是我们提交到 github 的只有源代码。在这里我们在 CI 中进行构建任务后,需要将构建的产物上传。否则下一个发布任务将无法获得构建任务生成后的目录文件
build:
needs: [lint, test]
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ["12", "13", "14"]
name: build - ${{ matrix.os }} - ${{ matrix.node }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: Load node_modules
uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package.json') }}
- run: yarn build # 执行构建
- name: Upload artifact # 上传构建产物,这里我们的源码目录是 src,而实际运行的代码是构建后的 bin 目录
uses: actions/upload-artifact@v2
with:
name: build_output
path: bin # 上传 bin 目录
# 发布到 NPM
这里不需要使用到 matrix, 我们只需要在一个环境发布即可。发布功能依赖一些环境变量,我们需要创建 NPM_TOKEN 环境变量
$ npm token create
在 github 项目主页添加环境变量
publish:
name: Publish
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: 12
- name: Download artifacts # 下载之前上传的构建产物
uses: actions/download-artifact@v2
with:
name: build_output
path: bin
- name: Publish
run: | # 只有 commit 信息包含版本号的提交才进行发布,否则不需要发布。这里我们可以使用 lerna publish/version 或者 npm version 来进行发布
if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$";
then
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
npm publish
else
echo "Not a release, skipping publish"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
以上的步骤都做完后,当执行 npm version patch
命令来生成版本后推送到仓库便会自动帮你执行构建发布流程
← 算法