本备忘单总结了 Github Actions 常用的配置说明,以供快速参考。
入门
介绍
GitHub Actions 的仓库中自动化、自定义和执行软件开发工作流程,有四个基本的概念,如下:
:- |
:- |
workflow (工作流程) |
持续集成一次运行的过程,就是一个 workflow |
job (任务) |
一个 workflow 由一个或多个 jobs 构成,含义是一次持续集成的运行,可以完成多个任务 |
step (步骤) |
每个 job 由多个 step 构成,一步步完成 |
action (动作) |
每个 step 可以依次执行一个或多个命令(action ) |
- 采用 YAML 格式定义配置文件
- 存放在代码仓库的
.github/workflows
目录中
- 后缀名统一为
.yml
,比如 ci.yml
- 一个库可以有多个
workflow
文件
- 根据配置事件自动运行配置文件
配置文件
{3,5,10}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| name: GitHub Actions Demo on: push: branches: - main
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16
- run: npm install - run: npm run build
|
存放到 .github/workflows
目录中,命名为 ci.yml
,当 push
代码到仓库 main
分支中,该配置自动运行配置。
指定触发
push
事件触发 workflow
push
事件或 pull_request
事件都可以触发 workflow
1
| on: [push, pull_request]
|
只有在 main
分支 push
事件触发 workflow
{2}1 2 3 4
| on: push: branches: - main
|
push
事件触发 workflow
,docs
目录下的更改 push
事件不触发 workflow
{2,4}1 2 3 4
| on: push: paths-ignore: - 'docs/**'
|
push 事件触发 workflow,包括 sub-project 目录或其子目录中的文件触发 workflow,除非该文件在 sub-project/docs 目录中,不触发 workflow
1 2 3 4 5
| on: push: paths: - 'sub-project/**' - '!sub-project/docs/**'
|
版本发布为 published
时运行工作流程。
1 2 3
| on: release: types: [published]
|
多项任务
1 2 3 4 5 6
| jobs: my_first_job: name: My first job
my_second_job: name: My second job
|
通过 jobs (jobs.<job_id>.name)
字段,配置一项或多项需要执行的任务
多项任务依赖关系
通过 needs (jobs.<job_id>.needs)
字段,指定当前任务的依赖关系
1 2 3 4 5 6
| jobs: job1: job2: needs: job1 job3: needs: [job1, job2]
|
上面配置中,job1
必须先于 job2
完成,而 job3
等待 job1
和 job2
的完成才能运行。因此,这个 workflow
的运行顺序依次为:job1
、job2
、job3
多项任务传递参数
{2,5,9,11,15}1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| jobs: job1: runs-on: ubuntu-latest outputs: output1: ${{ steps.step1.outputs.test }} output2: ${{ steps.step2.outputs.test }} steps: - id: step1 run: echo "::set-output name=test::hello" - id: step2 run: echo "::set-output name=test::world" job2: runs-on: ubuntu-latest needs: job1 steps: - run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
|
定时触发
可以使用 cron 表达式配置周期性任务,定时执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| name: schedule task
env: TZ: Asia/Shanghai
on: push: branches: - main schedule: - cron: '0 0/2 * * *'
|
指定每项任务的虚拟机环境
指定运行所需要的虚拟机环境,⚠️ 它是必填字段
{3}1 2 3
| jobs: build: runs-on: ubuntu-latest
|
Windows Server 2022
(windows-latest) 或 (windows-2022)
Ubuntu 20.04
(ubuntu-latest) 或 (ubuntu-20.04)
macOS Monterey 12
(macos-12)
macOS Big Sur 11
(macos-latest),(macos-11)
另见: 选择 GitHub 托管的运行器
指定每项任务的步骤
每个步骤都可以指定以下三个字段
1 2 3 4 5
| jobs.<job_id>.steps.name # 步骤名称 # 该步骤运行的命令或者 action jobs.<job_id>.steps.run # 该步骤所需的环境变量 jobs.<job_id>.steps.env
|
steps
字段指定每个 Job
的运行步骤,可以包含一个或多个步骤(steps
)
{4}1 2 3 4 5 6 7 8 9 10 11
| jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16
- run: npm install - run: npm run build
|
环境变量
1
| jobs.<job_id>.environment
|
使用单一环境名称的示例
1
| environment: staging_environment
|
使用环境名称和 URL 的示例
1 2 3
| environment: name: production_environment url: https://github.com
|
自定义环境变量
GitHub
会保留 GITHUB_
环境变量前缀供 GitHub
内部使用。设置有 GITHUB_
前缀的环境变量或密码将导致错误。
1 2 3
| - name: 测试 nodejs 获取环境变量 env: API_TOKEN: ${{ secrets.API_TOKEN }}
|
在 https://github.com/<用户名>/<项目名称>/settings/secrets
中添加 secrets
API_TOKEN
,在工作流中设置环境变量 API_TOKEN
表达式
在 if
条件下使用表达式时,可以省略表达式语法 (${{ }}
),因为 GitHub 会自动将 if
条件作为表达式求值
{3}1 2 3 4
| steps: - uses: actions/hello-world-action@v1.1 if: github.repository == 'uiw/uiw-repo'
|
设置环境变量的示例
1 2
| env: MY_ENV_VAR: ${{ <expression> }}
|
操作符
( )
(逻辑分组)
[ ]
(索引)
.
(属性解引用)
!
(非)
<
(小于)
<=
(小于或等于)
>
(大于)
>=
(大于或等于)
==
(相等)
!=
(不等)
&&
(和)
||
(或)
Github 上下文
属性名称 |
类型 |
描述 |
github (object) |
工作流程中任何作业或步骤期间可用的顶层上下文。 |
|
github.event (object) |
完整事件 web 挂钩有效负载。 更多信息请参阅“触发工作流程的事件”。 |
|
github.event_path (string) |
运行器上完整事件 web 挂钩有效负载的路径。 |
|
github.workflow (string) |
工作流程的名称。 如果工作流程文件未指定 name,此属性的值将是仓库中工作流程文件的完整路径。 |
|
github.job (string) |
当前作业的 job_id。 |
|
github.run_id (string) |
仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。 |
|
github.run_number (string) |
仓库中特定工作流程每个运行的唯一编号。 此编号从 1(对应于工作流程的第一个运行)开始,然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。 |
|
github.actor (string) |
发起工作流程运行的用户的登录名。 |
|
github.repository (string) |
所有者和仓库名称。 例如 Codertocat/Hello-World。 |
|
github.repository_owner (string) |
仓库所有者的名称。 例如 Codertocat。 |
|
github.event_name (string) |
触发工作流程运行的事件的名称。 |
|
github.sha (string) |
触发工作流程的提交 SHA。 |
|
github.ref (string) |
触发工作流程的分支或标记参考。 |
|
github.head_ref (string) |
工作流程运行中拉取请求的 head_ref 或来源分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。 |
|
github.base_ref (string) |
工作流程运行中拉取请求的 base_ref 或目标分支。 此属性仅在触发工作流程运行的事件为 pull_request 时才可用。 |
|
github.token (string) |
代表仓库上安装的 GitHub 应用程序进行身份验证的令牌。 这在功能上等同于 GITHUB_TOKEN 密码。 更多信息请参阅“使用 GITHUB_TOKEN 验证身份”。 |
|
github.workspace (string) |
使用 checkout 操作时步骤的默认工作目录和仓库的默认位置。 |
|
github.action (string) |
正在运行的操作的名称。 在当前步骤运行脚本时,GitHub 删除特殊字符或使用名称 run。 如果在同一作业中多次使用相同的操作,则名称将包括带有序列号的后缀。 例如,运行的第一个脚本名称为 run1,则第二个脚本将命名为 run2。 同样,actions/checkout 第二次调用时将变成 actionscheckout2。 |
|
Github 上下文是访问有关工作流运行、运行器环境、作业和步骤的信息的一种方式
直接常量
作为表达式的一部分,可以使用 boolean
, null
, number
或 string
数据类型
1 2 3 4 5 6 7 8 9
| env: myNull: ${{ null }} myBoolean: ${{ false }} myIntegerNumber: ${{ 711 }} myFloatNumber: ${{ -9.2 }} myHexNumber: ${{ 0xff }} myExponentialNumber: ${{ -2.99e-2 }} myString: Mona the Octocat myStringInBraces: ${{ 'It''s source!' }}
|
函数 contains
使用字符串的示例
1
| contains('Hello world', 'llo')
|
使用对象过滤器的示例返回 true
1
| contains(github.event.issue.labels.*.name, 'bug')
|
另见: 函数 contains
函数 startsWith
1
| startsWith('Hello world', 'He')
|
另见: 函数 startsWith,此函数不区分大小写
默认环境变量
环境变量 |
描述 |
CI |
始终设置为 true |
HOME |
用于存储用户数据的 GitHub 主目录路径。 例如 /github/home |
GITHUB_WORKFLOW |
工作流程的名称。 |
GITHUB_RUN_ID |
仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。 |
GITHUB_RUN_NUMBER |
仓库中特定工作流程每个运行的唯一编号。 此编号从 1(对应于工作流程的第一个运行)开始,然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。 |
GITHUB_ACTION |
操作唯一的标识符 (id)。 |
GITHUB_ACTIONS |
当 GitHub 操作 运行工作流程时,始终设置为 true。 您可以使用此变量来区分测试是在本地运行还是通过 GitHub 操作 运行。 |
GITHUB_ACTION_PATH |
GitHub 操作所在的路径 |
GITHUB_ACTOR |
发起工作流程的个人或应用程序的名称。 例如 octocat |
GITHUB_API_URL |
返回 API URL 。例如:https://api.github.com |
GITHUB_REPOSITORY |
所有者和仓库名称。 例如 octocat/Hello-World |
GITHUB_EVENT_NAME |
触发工作流程的 web 挂钩事件的名称 |
GITHUB_EVENT_PATH |
具有完整 web 挂钩事件有效负载的文件路径。 例如 /github/workflow/event.json |
GITHUB_WORKSPACE |
GitHub 工作空间目录路径。 如果您的工作流程使用 actions/checkout 操作,工作空间目录将包含存储仓库副本的子目录。 如果不使用 actions/checkout 操作,该目录将为空。 例如 /home |
GITHUB_SHA |
触发工作流程的提交 SHA。 例如 ffac537e6cbbf9 |
GITHUB_REF |
触发工作流程的分支或标记参考。 例如 refs/heads/feature-branch-1。 如果分支或标记都不适用于事件类型,则变量不会存在 |
GITHUB_HEAD_REF |
仅为复刻的仓库设置。头部仓库的分支 |
GITHUB_BASE_REF |
仅为复刻的仓库设置。基础仓库的分支 |
另见: 默认环境变量
1 2
| format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')
|
另见: 函数 format
函数 join
1 2
| join(github.event.issue.labels.*.name,', ')
|
另见: 函数 join
函数 toJSON
另见: 函数 toJSON
函数
:- |
:- |
fromJSON |
返回 JSON 对象或 JSON 数据类型的值 # |
hashFiles |
返回与路径模式匹配的文件集的单个哈希 # |
success |
当前面的步骤都没失败或被取消时返回 true # |
always |
使步骤始终执行,返回 true 即使取消也是如此 # |
cancelled |
如果工作流被取消,则返回 true # |
failure |
当作业的任何先前步骤失败时返回 true # |
函数 success()
1 2 3 4
| steps: ... - name: 作业已成功 if: ${{ success() }}
|
函数 failure()
1 2 3 4
| steps: ... - name: 作业失败 if: ${{ failure() }}
|
常用实例
获取版本信息
1 2 3 4 5 6 7 8 9
| - name: Test run: | # Strip git ref prefix from version echo "${{ github.ref }}" # VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
echo "$VERSION"
|
提交到 gh-pages 分支
1 2 3 4 5
| - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{secrets.GITHUB_TOKEN}} publish_dir: ./build
|
修改 package.json
1 2 3 4
| - name: Modify Version shell: bash run: | node -e 'var pkg = require("./package.json"); pkg.version= (new Date().getFullYear().toString().substr(2)) + "." + (new Date().getMonth() + 1) + "." + (new Date().getDate()); require("fs").writeFileSync("./package.json", JSON.stringify(pkg, null, 2))'
|
使用 github-action-package 修改 name
字段
1 2 3 4
| - name: package.json info uses: jaywcjlove/github-action-package@main with: rename: '@wcj/github-package-test'
|
克隆带有 Submodule 的仓库
1 2 3 4 5
| - name: Checkout uses: actions/checkout@v3 with: path: main submodules: true
|
submodules
:true
检出子模块或 recursive
递归检出子模块
1 2 3 4 5 6
| - name: Clone sub repository shell: bash run: | auth_header="$(git config --local --get http.https://github.com/.extraheader)" # git submodule sync --recursive # git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --remote --force --recursive --checkout ant.design
|
步骤依赖作业
使用 jobs.<job_id>.needs
识别在此作业运行之前必须成功完成的任何作业。它可以是一个字符串,也可以是字符串数组。 如果某个作业失败,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
1 2 3 4 5 6
| jobs: job1: job2: needs: job1 job3: needs: [job1, job2]
|
在此示例中,job1
必须在 job2
开始之前成功完成,而 job3
要等待 job1
和 job2
完成。此示例中的作业按顺序运行:
配置如下
1 2 3 4 5 6 7
| jobs: job1: job2: needs: job1 job3: if: ${{ always() }} needs: [job1, job2]
|
在此示例中,job3
使用 always()
条件表达式,因此它始终在 job1
和 job2
完成后运行,不管它们是否成功。
同步 Gitee
1 2 3 4 5 6 7 8 9 10 11
| - name: Sync to Gitee run: | mirror() { git clone "https://github.com/$1/$2" cd "$2" git remote add gitee "https://jaywcjlove:${{ secrets.GITEE_TOKEN }}@gitee.com/uiw/$2" git remote set-head origin -d git push gitee --prune +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/* cd .. } mirror uiwjs uiw
|
提交 NPM 包
1 2 3 4
| - run: npm publish --access public continue-on-error: true env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
获取 NPM_TOKEN
,可以通过 npm 账号创建 token
1 2 3
| npm token list [--json|--parseable] # 查看 npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] # 创建 npm token revoke <id|token> # 撤销
|
可以使用 JS-DevTools/npm-publish 提交
1 2 3 4 5
| - name: 📦 @province-city-china/data uses: JS-DevTools/npm-publish@v1 with: token: ${{ secrets.NPM_TOKEN }} package: packages/data/package.json
|
它有个好处,检测 package.json
中版本号是否发生变更,来决定是否提交版本,不会引发流程错误。
步骤作业文件共享
Artifacts 是 GitHub Actions 为您提供持久文件并在运行完成后使用它们或在作业(文档)之间共享的一种方式。
- 要创建工件并使用它,您将需要不同的操作:上传和下载
要上传文件或目录,您只需像这样使用它:
1 2 3 4 5 6 7 8
| steps: - uses: actions/checkout@v2 - run: mkdir -p path/to/artifact - run: echo hello > path/to/file/a.txt - uses: actions/upload-artifact@v2 with: name: my-artifact path: path/to/artifact/a.txt
|
然后下载 artifact
以使用它:
1 2 3 4 5
| steps: - uses: actions/checkout@v2 - uses: actions/download-artifact@v2 with: name: my-artifact
|
Node.js
1 2 3 4
| - name: Setup Node uses: actions/setup-node@v2 with: node-version: 14
|
使用矩阵策略 在 nodejs 不同版本中运行
1 2 3 4 5 6 7 8 9 10 11 12 13
| strategy: matrix: node-version: [10.x, 12.x, 14.x]
steps: - uses: actions/checkout@v2 - name: 使用 Node ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - run: npm ci - run: npm run build --if-present - run: npm test
|
提交 docker 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| - name: Docker login run: docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
- name: Build ant.design image run: | cd ./ant\.design docker build -t ant.design . - name: Tags & Push docs run: | # Strip git ref prefix from version VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:$VERSION docker tag ant.design ${{ secrets.DOCKER_USER }}/ant.design:latest docker push ${{ secrets.DOCKER_USER }}/ant.design:$VERSION docker push ${{ secrets.DOCKER_USER }}/ant.design:latest
|
创建一个 tag
1 2 3 4 5
| - name: Create Tag id: create_tag uses: jaywcjlove/create-tag-action@main with: package-path: ./package.json
|
根据 package-path
指定的 package.json
检测 version
是否发生变化来创建 tag
生成 git 提交日志
1 2 3 4 5 6 7 8
| - name: Generate Changelog id: changelog uses: jaywcjlove/changelog-generator@main with: filter-author: (小弟调调™)
- name: Get the changelog run: echo "${{ steps.changelog.outputs.changelog }}"
|
提交到 GitHub docker 镜像仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| - name: '登录到 GitHub 注册表' run: echo ${{ github.token }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: '编译 docker image' run: docker build -t ghcr.io/jaywcjlove/reference:latest .
- name: '推送到 GitHub 注册表中' run: docker push ghcr.io/jaywcjlove/reference:latest
- name: '标记 docker 镜像并发布到 GitHub 注册表' if: steps.create_tag.outputs.successful run: | echo "version: v${{ steps.changelog.outputs.version }}" docker tag ghcr.io/jaywcjlove/reference:latest ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}} docker push ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
提交 commit 到 master 分支
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| - name: 生成一个文件,并将它提交到 master 分支 run: | # Strip git ref prefix from version VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') COMMIT=released-${VERSION} # Strip "v" prefix from tag name [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') echo "输出版本号:$VERSION" # 将版本输出到当前 VERSION 文件中 echo "$VERSION" > VERSION echo "1. 输出Commit:$commit" echo "2. Released $VERSION" git fetch git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add . git commit -am $COMMIT git branch -av git pull origin master
- name: 将上面的提交 push 到 master 分支 uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }}
|
作业之间共享数据
创建一个文件,然后将其作为构件上传
{11}1 2 3 4 5 6 7 8 9 10 11 12
| jobs: example-job: name: Save output steps: - shell: bash run: | expr 1 + 1 > output.log - name: Upload output file uses: actions/upload-artifact@v3 with: name: output-log-file path: output.log
|
可以下载名为 output-log-file
的工件
{7}1 2 3 4 5 6 7
| jobs: example-job: steps: - name: Download a single artifact uses: actions/download-artifact@v3 with: name: output-log-file
|
指定运行命令的工作目录
{3}1 2 3
| - name: Clean temp directory run: rm -rf * working-directory: ./temp
|
使用 working-directory
关键字,您可以指定运行命令的工作目录(./temp
)
defaults.run
{4,5,7}1 2 3 4 5 6 7
| jobs: job1: runs-on: ubuntu-latest defaults: run: shell: bash working-directory: scripts
|
作业中的所有 run
步骤提供默认的 shell
和 working-directory
jobs..steps[*].shell
使用 bash
运行脚本
{4}1 2 3 4
| steps: - name: Display the path run: echo $PATH shell: bash
|
运行 python
脚本
{6}1 2 3 4 5 6
| steps: - name: Display the path run: | import os print(os.environ['PATH']) shell: python
|
您可以使用 shell
关键字覆盖运行器操作系统中的默认 shell
设置
一些 actions 推荐
在 Github 中创建 Docker 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: 登录 GitHub 容器注册表 uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: 构建并推送 image:latest uses: docker/build-push-action@v3 with: push: true context: . platforms: linux/amd64,linux/arm64 tags: ghcr.io/jaywcjlove/reference:latest
- name: 构建并推送 image:tags uses: docker/build-push-action@v3 if: steps.create_tag.outputs.successful with: push: true context: . platforms: linux/amd64,linux/arm64 tags: ghcr.io/jaywcjlove/reference:${{steps.changelog.outputs.version}}
|
生成贡献者头像列表
1 2 3 4 5 6
| - name: Generate Contributors Images uses: jaywcjlove/github-action-contributors@main id: contributors with: output: dist/CONTRIBUTORS.svg avatarSize: 42
|
在 Docker Hub 中创建 Docker 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: 登录到 Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: 构建并推送 image:latest uses: docker/build-push-action@v3 with: push: true context: . platforms: linux/amd64,linux/arm64 tags: ${{ secrets.DOCKER_USER }}/reference:latest
- name: 构建并推送 image:tags uses: docker/build-push-action@v3 if: steps.create_tag.outputs.successful with: push: true context: . platforms: linux/amd64,linux/arm64 tags: ${{ secrets.DOCKER_USER }}/reference:${{steps.changelog.outputs.version}}
|
检查签出仓库并安装 nodejs
1 2 3 4
| - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16
|
忽略失败
1 2 3 4
| - run: npm publish continue-on-error: true env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
当 npm
推送包失败不影响整个流程,可用于自动发包
安装 yarn
1 2 3 4 5
| - name: Setup Yarn uses: threeal/setup-yarn-action@v2.0.0 with: cache: false version: 1.22.21
|
传递环境变量
在 ci.yml
上保存环境变量
1 2
| - name: Save commit message to environment variable run: echo "COMMIT_MESSAGE=${{ github.event.head_commit.message }}" >> $GITHUB_ENV
|
在 tag.yml
上获取环境变量
1 2 3
| - name: Read commit message run: | echo "Commit: ${{ github.event.workflow_run.head_commit.message }}"
|
触发下一个工作流
在 tag.yml
上添加判断 tag
创建成功触发 tag-creation-success
的工作流
1 2 3 4 5 6 7 8
| - name: Trigger next workflow if successful if: steps.check_success.outputs.success == 'true' run: | curl -X POST \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -d '{"event_type": "tag-creation-success"}' \ https://api.github.com/repos/${{ github.repository }}/dispatches
|
在 success.yml
上监听
1 2 3
| on: repository_dispatch: types: [tag-creation-success]
|
GitLab CI/CD 迁移到 GitHub Actions
语法示例
GitLab CI/CD
1 2 3 4 5
| job1: variables: GIT_CHECKOUT: "true" script: - echo "Run your script here"
|
GitHub Actions
1 2 3 4 5
| jobs: job1: steps: - uses: actions/checkout@v3 - run: echo "Run your script here"
|
运行程序
GitLab CI/CD
1 2 3 4 5 6 7 8 9
| windows_job: tags: - windows script: - echo Hello, %USERNAME%!
linux_job: tags: - linux script: - echo "Hello, $USER!"
|
GitHub Actions
1 2 3 4 5 6 7 8 9
| windows_job: runs-on: windows-latest steps: - run: echo Hello, %USERNAME%!
linux_job: runs-on: ubuntu-latest steps: - run: echo "Hello, $USER!"
|
在不同的平台上运行作业
Docker 映像
GitLab CI/CD
1 2
| my_job: image: node:10.16-jessie
|
GitHub Actions
1 2 3
| jobs: my_job: container: node:10.16-jessie
|
条件和表达式语法
GitLab CI/CD
1 2 3 4 5 6
| deploy_prod: stage: deploy script: - echo "部署到生产服务器" rules: - if: '$CI_COMMIT_BRANCH == "master"'
|
GitHub Actions
1 2 3 4 5 6
| jobs: deploy_prod: if: contains( github.ref, 'master') runs-on: ubuntu-latest steps: - run: echo "部署到生产服务器"
|
Artifacts
GitLab CI/CD
1 2 3 4
| script: artifacts: paths: - math-homework.txt
|
GitHub Actions
1 2 3 4 5
| - name: Upload math result for job 1 uses: actions/upload-artifact@v3 with: name: homework path: math-homework.txt
|
作业之间的依赖关系
GitLab CI/CD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| stages: - build - test - deploy
build_a: stage: build script: - echo "该作业将首先运行"
build_b: stage: build script: - echo "该作业将首先运行,与 build_a 并行"
test_ab: stage: test script: - echo "此作业将在 build_a 和 build_b 完成后运行"
deploy_ab: stage: deploy script: - echo "此作业将在 test_ab 完成后运行"
|
GitHub Actions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| jobs: build_a: runs-on: ubuntu-latest steps: - run: echo "该作业将首先运行"
build_b: runs-on: ubuntu-latest steps: - run: echo "该作业将首先运行,与 build_a 并行"
test_ab: runs-on: ubuntu-latest needs: [build_a,build_b] steps: - run: echo "此作业将在 build_a 和 build_b 完成后运行"
deploy_ab: runs-on: ubuntu-latest needs: [test_ab] steps: - run: echo "此作业将在 test_ab 完成后运行"
|
缓存
GitLab CI/CD
1 2 3 4 5 6 7 8 9 10
| image: node:latest
cache: key: $CI_COMMIT_REF_SLUG paths: - .npm/
before_script: - npm ci --cache .npm --prefer-offline
test_async: script: - node ./specs/start.js ./specs/async.spec.js
|
GitHub Actions
1 2 3 4 5 6 7 8 9 10
| jobs: test_async: runs-on: ubuntu-latest steps: - name: Cache node modules uses: actions/cache@v3 with: path: ~/.npm key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }} restore-keys: v1-npm-deps-
|
数据库和服务容器
GitLab CI/CD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| container-job: variables: POSTGRES_PASSWORD: postgres POSTGRES_HOST: postgres POSTGRES_PORT: 5432 image: node:10.18-jessie services: - postgres script: - npm ci - node client.js tags: - docker
|
GitHub Actions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| jobs: container-job: runs-on: ubuntu-latest container: node:10.18-jessie
services: postgres: image: postgres env: POSTGRES_PASSWORD: postgres
steps: - name: Check out repository code uses: actions/checkout@v3
- name: Install dependencies run: npm ci
- name: Connect to PostgreSQL run: node client.js env: POSTGRES_HOST: postgres POSTGRES_PORT: 5432
|
另见