Search K
Appearance
Appearance
在 Workflows 作业中,Github Actions 会注入一些环境变量到执行 Workflows 的运行容器中,有 CI
, GITHUB_*
和 RUNNER_*
。 CI
一直为 true,GITHUB_*
存储的是有关 github 的环境变量,RUNNER_*
存储的是作业容器环境的系统相关信息。
常见的环境变量有:
GITHUB_ACTOR
:运行 Workflows 作业的用户或应用程序的名称,通常 Push,Pull Request 等操作触发 Workflows 都是用户名称,在 Workflows 中触发通常是应用程序的名称。GITHUB_TOKEN
: 针对 Workflows 作业临时生成的针对本仓库的访问令牌。NOTE
每一次 Github Actions 工作流作业开始时,Github 都会创建唯一的 GITHUB_TOKEN
在这个工作流中进行身份验证,这个GITHUB_TOKEN
的生存时间只在这个工作流运行期间,或者最长 24 小时(考虑到即是一些复杂工作流运行时间较长,但也太可能要运行 24 小时)。且 GITHUB_TOKEN
的权限仅限于本仓库,并且可以在 仓库的 Settings > Actions > General
的 Workflow permissions
中设置为对本仓库的可读或者可读可写权限。
全部环境变量参考 Github Actions 文档 默认环境变量。
明文环境变量
除了可以在 Shell 中使用外,还可以通过 env
上下文,在 Workflows 配置文件中使用。
可以像 Dockefile
那样在文件中配置 ENV,将明文数据作为环境变量注入到容器中,在 Workflows 配置文件中明文配置的环境变量有个 3 个作用域,全局,jobs,steps。
name: Greeting on variable day
on: workflow_dispatch
env: # 全局作用域
DAY_OF_WEEK: Monday
jobs:
greeting_job:
runs-on: ubuntu-latest
env: # jobs 作用域
Greeting: Hello
steps:
- name: "Say Hello Mona it's Monday"
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
env: # steps 作用域
First_Name: Mona
- name: "Say 你好 it's Monday"
if: ${{ env.DAY_OF_WEEK == 'Monday' }}
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
env:
First_Name: Mona
也可以存储到 vars 上下文中,在 Settings > Security > Secrets and Variables > Actions
中添加 Variables
,Variables 也是明文存储,可以在流水线中直接输出该环境变量明文内容。
在 Workflows 配置文件中使用 vars 上下文
on:
workflow_dispatch:
env:
env_var: ${{ vars.ENV_CONTEXT_VAR }}
jobs:
display-variables:
name: ${{ vars.JOB_NAME }}
如果是私密数据,可以在仓库的 Settings > Security > Actions
中添加 Secrets
,即是是在流水线中输出该环境变量,也是加密数据。
私密数据存储到密钥后,可以通过 secrets上下文
来使用,更多细节和安全使用方式参考 Github Actions 文档 使用机密。
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }}
env: # Or as an environment variable
super_secret: ${{ secrets.SuperSecret }}
提醒
自定义 Secrets 环境变量不能和默认环境变量名称相同,如果名称相同会被忽略。
上下文是可以在 Workflows 配置文件中作为表达式使用的,类似于模板变量,会将 Workflows 文件进行编译,替换模板变量,根据编译后的 Workflows 配置文件配置容器环境。 而环境变量是进入到容器后,可以通过 Shell 读取的值。
用户可以给予此特性,对 Workflows 配置文件进行逻辑编程,使得流程不仅是纯文本表达,还有一定执行逻辑性,参考 Github Actions 文档 上下文。
jobs 选项是数组,可以配置多个 job,所有 job 默认并行运行,可以配置 job 运行之间的关系,使 job 可以依照依赖关系顺序串行的运行。
jobs:
setup:
runs-on: ubuntu-latest
steps:
- run: ./setup_server.sh
build:
needs: setup
runs-on: ubuntu-latest
steps:
- run: ./build_server.sh
test:
needs: build
runs-on: ubuntu-latest
steps:
- run: ./test_server.sh
当一些公共库需要测试不同版本开发/生产/测试环境下的功能,可以使用矩阵任务,更多详细内容参考 Github Actions 文档 矩阵策略。
jobs:
build:
runs-on: ubuntu-latest
# 给 build 任务设置成矩阵jobs,分别在 node.js 14 和 16版本下分别运行此 job
strategy:
matrix:
node: [14, 16]
# 如果测试版本很多,还可以控制并发数
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
当 Github Actions 工作流内 使用 GITHUB_TOKEN
push 推送内容到本仓库中,是不会触发 push 事件,导致工作流循环递归触发的,但是会触发 workflow-dispatch
和 repostory_dispatch
事件。并且用 GITHUB_TOKEN
的 GitHub Actions 工作流推送的提交不会触发 GitHub Pages 生成。
如何从一个仓库 Github Actions 工作流中 push 产物或者代码到另一个仓库呢?
比如,从一个私有仓库触发 Github Actions 工作流,然后推送到另外一个仓库如 GitHub Pages 仓库中,GITHUB_TOKEN
只有本仓库的权限,也就是只有这个私有仓库的权限,是没有办法 push 到另一个公共仓库的,所以需要创建一个 Github App token,用来将构建产物 commit 提交到公共仓库中。
通过 run
关键字来执行 shell 命令。
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm install -g bats
- name: 多行脚本
run: | npm install -g \
npm run build
- name: 删除打包文件
run: rm -rf .dist
或者将 shell 脚本写入到仓库的文件中,但是在 Github Actions 工作流中,如果没有使用 action/checkout@4 来下载仓库文件到工作流的虚拟服务器中是没有办法读取到 shell 文件的,所以需要特意指定目录,这样才能读取到脚本文件
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts
steps:
- name: 多行脚本
run: npm install -g && run build
- name: 上传到服务器
run: ./upload.sh
- name: 删除脚本
run: |
./do-something.sh
./delete-dist.sh
脚本执行权限问题
如果脚本没有执行权限,可以在本地 git update-index --chmod=+x PATH/TO/YOUR/script.sh
,然后 commit 并且提交到仓库,这样脚本才可以在 Github Actions 容器中执行。
Github Actions 运行容器通常是 Linux,也有使用 Mac 的,这两种环境下不需要上述那样麻烦,直接在 Workflows 文件中给 shell 脚本文件添加执行权限。
# ...
steps:
- name: 多行脚本
run: npm install -g && run build
- run: chmod +x ./upload.sh
- name: 上传到服务器
run: ./upload.sh
# ...
将 build Workflows 打包的文件通过 actions/upload-artifact@4
上传保存,使用 actions/download-artifact@4
下载保存的产物文件。
jobs:
build:
name: Save output
runs-on: ubuntu-latest
steps:
- shell: bash
run: |
expr 1 + 1 > output.log
- name: Upload output file
uses: actions/upload-artifact@v4
with:
name: output-log-file
path: output.log
retention-day: 5 # 自定义保留日期 5 天
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Download a single artifact
uses: actions/download-artifact@v4
with:
name: output-log-file
提示
多文件可以直接上传目录
- name: Upload archive production artifacts
uses: actions/upload-artifact@v4
with:
name: dist-without-markdown
path: |
dist
!dist/**/*.md
更多或详细内容参考 Github Actions 文档 存储项目。
参考 Github Actions 文档 表达式#fromJSON
name: build
on: push
jobs:
job1:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
run: echo "matrix={\"include\":[{\"project\":\"foo\",\"config\":\"Debug\"},{\"project\":\"bar\",\"config\":\"Release\"}]}" >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.job1.outputs.matrix) }}
steps:
- run: echo "Matrix - Project ${{ matrix.project }}, Config ${{ matrix.config }}"
使用 actions/cache@v3
缓存一个 .npm 目录。
jobs:
example-job:
steps:
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# 缓存目录
path: ~/.npm
# 缓存目录的 key
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
# 恢复key,使用此 key 来恢复缓存的文件
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
更多详细内容,参考 Github Actions 文档 缓存依赖项。