1.概念解析
Github Actions: 是一种持续集成和持续交付(CI/CD)平台,可以用于自动执行生成
、测试
、部署管道
。可以创建工作流程
来构建
和测试
存储库的每个拉取请求,或将合并的拉取请求部
署到生产环境。
主要的几个概念
name | 说明 |
---|---|
workflow(工作流程) | 可配置的自动化过程,可运行一个或多个作业,通过 ymal 文件定义,工作流程在存储库的.github/workflows 目录中定义 |
event(事件) | 存储库中触发工作流程运行的特定活动,例如拉取分支 、open issure ,push commit |
job(任务) | 在同一个运行器中执行的一组步骤,一个 workfow 由 1 个多多个 job 构成 , |
step(步骤) | 每个 job 由多个 step 构成 |
action(动作) | 每个 step 可以一次执行一个或者多个 action 命令 |
2. 实例
先来实操一个例子,后续讲解字段。
2.1 runs-on
------Github 托管的虚拟机配置
如果是github则可以直接使用runs-on: ubuntu-latest
, 如果在公司内部的github上,则需要配置自己托管的虚拟机。
托管虚拟机创建成果:
- 根据图片的步骤,选择需要安装的机子类型(我最开始选择了 linux-64),但是在机子上需要执行两次
./run.sh
才启动,并且 action 不能正确执行成功,因此切换到了 window - 在托管的机子上,运行
config runner
中的所有命令 - 在 github 中,将会看到生成的托管机子,
idle
表示没有作业
2.2 自动发布 npm
根据图片,选择发布的类型,将会有一个发布模板:
2.3 修改 yaml 文件(yaml 文件基础剖析)
yaml
name: your-repository-release # 工作流名称,将出现在Github`Actions`选项卡中,默认为`文件名称`
run-name: ${{ github.actor }} is release GitHub Actions # 当action运行的时候,显示在运行tab上的内容,`github.actor`是当前运行action 的github作者
# on: #: 指定工作流的触发器,当向master分支 push代码的时候触发
# push:
# branches:
# - master
on:
workflow_dispatch: # 指定工作流的触发器,手动触发
inputs: # inputs:手动触发的时候,可以添加需要输入的参数,在后面可以通过变量访问
releaseStep:
description: "start to release"
required: true
default: "start....."
jobs: # 将 `your-repository-release`的所有工作流运行的作业放在一起
publish-npm: # 定义第一个job的名字
runs-on: [self-hosted] # 作业将在`self-hosted`上运行,后面将会讲解如果配置self-hosted
steps: # 该作业所有的步骤集合,每个项都是一个单独的操作或shell脚本
- uses: actions/checkout@v3 # 使用该仓库,检索代码
- uses: actions/setup-node@v3 # 使用该仓库,安装指定版本的Node.js
with:
node-version: 16 # 指定node版本
- run: echo "${{github.event.inputs.releaseStep}}" # 打印参数
- run: npm install # 运行命令
- run: npm run build
- run: npm publish
2.4 什么是actions/checkout@v3
当第一眼看到actions/checkout@v3
和actions/setup-node@v3
,会很好奇这是什么。其实他们是已经存在 github 上的一些仓库,是GitHub Actions
中常用的 action
- actions/checkout@v3: 检查 GitHub 仓库中的代码,并将代码检出到当前工作流程运行的虚拟机中。它还支持检出指定的分支、标记或提交 ID,并可以将检出目录指定为自定义目录。
yaml
# 检出存储库的其他分支或标记,请在 with 字段中指定它们。例如,下面的示例将检出存储库的 v1.0 标记:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: v1.0
到此,你就完成了一个完整的发布流程内容。
- push 到 master,将自动触发
- workflow_dispatch: 需要到
actions
tab, 进行手动选择触发。
3 表达式 与变量
表达式可以是boolean
, null
, number
, string
数据类型,通过字段env:${{xxx}}
进行使用。
- 表达式中可以使用运算符
||
,&&
,>=
,<=
,[]
索引等等。 - 可以使用函数:
contains('Hello world', 'llo')
,startsWith('Hello world', 'He')
,join
,toJSON
等 if条件表达式
,为 true, 执行下一步,false 不执行- 可通过
env
进行访问变量
tips: linux 使用 $varible_name
获取变量, window 使用$env:varible_name
获取变量。
yaml
name: Node.js Package
on:
workflow_dispatch:
env:
DAY_OF_WEEK: DAY_OF_WEEK_Monday # 顶层变量
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: test_echo
run: echo 'befrore'
- name: test_if
if: ${{ env.DAY_OF_WEEK == 'DAY_OF_WEEK_Monday' }}
run: |
echo " Today is $DAY_OF_WEEK!"
echo "here is: $test_if_var"
echo "$First_Name $MY_ENV_VAR"
env:
test_if_var: I'M TEST ENV VAR # test_if 的变量
env: # teps test_echo 的变量
First_Name: Mona
MY_ENV_VAR: ${{ github.ref == 'refs/heads/main' && 'value_for_main_branch' || 'value_for_other_branches' }}
4 上下文
上下文是一种访问工作流运行、变量、运行器环境、作业、步骤相关信息的方式。每一个上下文都是一个包含属性的对象。我们可以通过${{context}}
表达式语法访问上下文。
上下文名称 | 描述 |
---|---|
github | 工作流程运行的相关信息 |
env | 包含工作流、作业或步骤中设置的变量 |
vars | 存储库、组织或环境级别设置的变量 |
job | 当前运行的作业的信息 |
steps | 当前作业中已运行的步骤的信息 |
runner | 运行当前作业的运行器的信息 |
runner | 运行当前作业的运行器的信息 |
secrets | 包含可用于工作流运行的机密的名称和值 |
needs | 定义为当前作业直接依赖项的所有作业的输出 |
inputs | 传递给操作可重用工作流或手动触发的工作流的输入属性 |
jobs | 仅在可重用工作流中可用,并且只能用于设置可重用工作流的输出 |
strategy | 对于具有矩阵的工作流,包含有关当前作业的矩阵执行策略的信息 |
matrix | 对于具有矩阵的工作流, 包含工作流程文件中定义的适用于当前作业的矩阵属性 |
5. 触发工作流的方式
这里列举常用的触发工作流的方式:
- 需要知道更详细的触发类型,请click here
- 需要知道更详细的工作流程语法,请click here
5.1 事件触发
yaml
### 事件触发,当 push 或者 fork 时,进行触发
on: [push, fork, page_build]
5.2 活动类型与筛选器
branches
和branches-ignore
筛选器: 接受*、**、+、?
和!
等字符匹配多个分支名称的glob 模式
yaml
on:
# 事件活动类型:使用 on.<event_name>.types 定义将触发工作流运行的事件活动类型
label: # 创建标签 触发(有created、edited 、deleted)
types:
- created
# 创建issure时触发(有created、edited 、deleted), (labeled)被标记触发
issues:
types:
- opened
- labeled
# 筛选器类型:push 事件具有 branches 筛选器
push: # 筛选器向main分支推送触发
branches:
- main
paths: # 只要推送 JavaScript 文件 (.js),就会运行以下工作流
- '**.js'
- '!sub/docs/**' # 该路径不触发
paths-ignore: # 推送到`docs/**`的内容,将不触发
- 'docs/**'
# 筛选器类型:向分支进行PR的时候触发,向tag为`v2`(refs/tags/v2)或`v1.`(refs/tags/v1.9.1)开头的标记触发
# !开头的,例如`releases/a-alpha`,将不触发
pull_request:
branches:
- main
- 'releases/*'
- '!releases/**-alpha'
tags:
- v2
- v1.*
# 筛选器类型:向分支进行PR的时候触发,但被`branches-ignore`的分支不触发
pull_request:
branches-ignore:
- 'mona/octocat'
- 'releases/**-alpha'
tags-ignore:
- v2
- v1.*
# 指定触发工作流必须在哪些分支上运行才能触发工作流
# 仅当名为 Build 的工作流在名称以 releases/ 开头的分支上运行时,具有以下触发器的工作流才会运行
workflow_run:
workflows: ["Build"]
types: [requested]
branches:
- 'releases/**'
# 仅当名为 Build 的工作流不在名为 "feature/**" 的分支上运行时,具有以下触发器的工作流才会运行
workflow_run:
workflows: ["Build"]
types: [requested]
branches-ignore:
- "feature/**"
#仅当名为`Greeting on variable day`的工作流执行完成后,再出发该工作流
workflow_run:
workflows: [Greeting on variable day]
types:
- completed
#
page_build: # 推送到启用了 GitHub Pages 的分支
5.3 手动触发
在前面的实例中,已经实践过手动触发的例子了
yaml
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
print_tags:
description: 'True to print to STDOUT'
required: true
type: boolean
jobs:
print-tag:
runs-on: ubuntu-latest
if: ${{ inputs.print_tags }}
steps:
- name: Print the input tag to STDOUT
run: echo The tags are ${{ inputs.logLevel }}
- env:
EVENT_CONTEXT: ${{ toJSON(github.event) }} # github.event 上下文打印出来, 查看哪些属性可用于触发工作流的事件
PR: ${{ github.event.pull_request.html_url }} # 访问event事件属性
# 向问题添加特定标签时,且标签name为`bug`, 运行工作流
run_if_label_matches:
if: github.event.label.name == 'bug'
runs-on: ubuntu-latest
steps:
- run: echo 'The label was bug'
5.4 读取 package.json version
yaml
name: Greeting on variable day
on: workflow_dispatch
jobs:
greeting_job:
runs-on: [self-hosted]
steps:
- name: Set color
id: color-selector
run: |
echo "SELECTED_COLOR=green" >> $Env:GITHUB_OUTPUT
$version = node -p "require('./package.json').version"
echo "version_name=$version" >> $Env:GITHUB_OUTPUT
- name: Get color
env:
TEST: ${{ steps.color-selector.outputs.version_name }}
run: |
echo "$env:TEST"
6. 利用Github Action进行Build和推送npm包,自动打Rlease Tag 完整实例
yaml
name: biz-web-library-release
run-name: ${{ github.actor }} is learning GitHub Actions
# on:
# push:
# branches:
# - master
on:
workflow_dispatch:
inputs:
versionType:
description: 'type of release version:'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
bodyContent:
description: 'new feature:'
required: true
default: 'add new feature'
type: string
jobs:
npm-publish:
runs-on: [ self-hosted ]
steps:
- name: step1:checkout code
uses: actions/checkout@v3
- name: step2:download node
uses: actions/setup-node@v3
with:
node-version: 16
- name: step3:package version chagne and publish
run: |
npm version ${{github.event.inputs.versionType}}
- run: npm install
- run: npm run build
- run: npm publish
- name: step4:set version name
id: version_name
run: |
echo "SELECTED_COLOR=green" >> $Env:GITHUB_OUTPUT
$version = node -p "require('./package.json').version"
echo "version_name=$version" >> $Env:GITHUB_OUTPUT
- name: step5:create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# VERTION_NAME: ${{ steps.version_name.outputs.version_name }}
with:
tag_name: ${{ steps.version_name.outputs.version_name }}
release_name: Release v${{ steps.version_name.outputs.version_name }}
body: ${{github.event.inputs.bodyContent}}
draft: false
prerelease: false
- name: step6:commit code(package.json's version)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global user.email "xxx"
git config --global user.name "xxx"
git add .
git commit -m "Commit Message"
git push
7.利用Github Action在发布后进行文档构建
yaml
name: deploy-page
run-name: ${{ github.actor }} is deploy oss page
# on:
# push:
# branches:
# - master
on:
workflow_dispatch:
workflow_run:
workflows: [biz-web-library-release]
types:
- completed
jobs:
npm-publish-doc:
runs-on: [ self-hosted ]
steps:
- name: step1:checkout code
uses: actions/checkout@v3
- name: step2:download node
uses: actions/setup-node@v3
with:
node-version: 16
- name: step3:publish doc
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global user.email "xxx"
git config --global user.name "xxx"
npm install
npm run docs:build
npm run docs:deploy
8. 调试阶段遇到的问题
npm ERR! fatal: tag 'v1.0.5' already exists
html
step1: 进入 \actions-runner\_work\工作目录 step2: 找到重复的tag: git tag step3:
删除tag: git tag -d v3.1.0
error: dst refspec refs/heads/master matches more than one
javascript
git push origin :refs/tags/refs/heads/master
- window 输入变量失败(github.com/actions/run...)
javascript
as is:
>> $GITHUB_OUTPUT
to be:
>> $Env:GITHUB_OUTPUT
- window服务器装git,可用windows PowerShell 的命令(记得输出参数:-OutFile)
javascript
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v2.312.0/actions-runner-win-x64-2.312.0.zip -OutFile actions-runner.zip
- window 服务器上dumi打包失败问题解决
ruby
https://github.com/umijs/dumi/issues/1701
- linux 安装runner运行两次
./run.sh
,但是启动后不能正确运行程序,因此换成了window。