测试 GitHub 工作流,一些比较特殊的玩儿法。
GitHub actions 有四个基本的概念,如下:
GitHub Actions 采用YAML 格式的配置文件叫做 workflow 文件,存放在代码仓库的.github/workflows 目录。文件名可以任意取,但是后缀名统一为.yml,比如ci.yml。一个库可以有多个workflow 文件。GitHub 只要发现.github/workflows 目录里面有.yml 文件,就会根据配置事件自动运行该文件。
name: GitHub Actions Demoon:push:branches:- mainjobs:build:runs-on: ubuntu-18.04steps:-uses: actions/checkout@v3-uses: actions/setup-node@v3with:node-version:16-run: npm install-run: npm run buildon 字段指定触发workflow 的条件,通常是某些事件。
# push 事件触发 workflowon: push# push 事件或 pull_request 事件都可以触发 workflowon:[push, pull_request]# 只有在 main 分支 push 事件触发 workflowon:push:branches:- main# push 事件触发 workflow,但是 docs 目录下的更改 push 事件不触发 workflowon:push:paths-ignore:-'docs/**'# push 事件触发 workflow,# 包括 sub-project 目录或其子目录中的文件,触发 workflow# 除非该文件在 sub-project/docs 目录中,不触发 workflowon:push:paths:-'sub-project/**'-'!sub-project/docs/**'# 版本发布为 published 时运行工作流程。on:release:types:[published]通过jobs (jobs.<job_id>.name)字段,配置一项或多项需要执行的任务。
jobs:my_first_job:name: My first jobmy_second_job:name: My second job通过needs (jobs.<job_id>.needs)字段,指定当前任务的依赖关系。
jobs:job1:job2:needs: job1job3:needs:[job1, job2]上面配置中,job1 必须先于job2 完成,而job3 等待job1 和job2 的完成才能运行。因此,这个 workflow 的运行顺序依次为:job1、job2、job3。
jobs:job1:runs-on: ubuntu-latest# Map a step output to a job outputoutputs:output1: ${{ steps.step1.outputs.test}}output2: ${{ steps.step2.outputs.test}}steps:-id: step1run: echo "::set-output name=test::hello"-id: step2run: echo "::set-output name=test::world"job2:runs-on: ubuntu-latestneeds: job1steps:-run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}runs-on 字段指定运行所需要的虚拟机环境。⚠️ 它是必填字段。
runs-on: ubuntu-18.04jobs:build:runs-on: ubuntu-18.04| 虚拟环境 | YAML 工作流程标签 | 注: |
|---|---|---|
| Windows Server 2022 | windows-latest 或windows-2022 | windows-latest 标签目前使用的是 Windows Server 2022 运行器镜像 |
| Windows Server 2019 | windows-2019 | |
| Ubuntu 22.04 | ubuntu-22.04 | Ubuntu 22.04 目前处于公开测试阶段。 |
| Ubuntu 20.04 | ubuntu-latest 或ubuntu-20.04 | |
| Ubuntu 18.04 | ubuntu-18.04 | |
| macOS Monterey 12 | macos-12 | macOS 12 目前处于公开测试阶段。 |
| macOS Big Sur 11 | macos-latest 或macos-11 | macos-latest 标签当前使用 macOS 11 运行器镜像。 |
| macOS Catalina 10.15 | macos-10.15 |
steps 字段指定每个 Job 的运行步骤,可以包含一个或多个步骤。每个步骤都可以指定以下三个字段。
jobs.<job_id>.steps.name:步骤名称。jobs.<job_id>.steps.run:该步骤运行的命令或者 action。jobs.<job_id>.steps.env:该步骤所需的环境变量。jobs:build:runs-on: ubuntu-18.04steps:-uses: actions/checkout@v3-uses: actions/setup-node@v3with:node-version:16registry-url:'https://registry.npmjs.org'-run: npm install-run: npm run build# ci.ymlname: Node.js CIon: pushjobs:test:# Containers must run in Linux based operating systemsruns-on: ubuntu-lateststeps:-uses: actions/checkout@v3-uses: actions/setup-node@v3with:node-version:16-name: Install dependenciesrun: npm installtrigger_tests:needs: testruns-on: ubuntu-lateststeps:-name: Trigger testsuses: actions/github-script@v6with:script:| const res = await github.rest.repos.createDispatchEvent({ owner: 'jaywcjlove', repo: 'typenexus', event_type: 'run-deploy' });env:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN}}上面ci.yml 工作流执行完成之后,触发main.yml,注意上面的run-deploy 取名保持一致
# main.ymlname: deployon:repository_dispatch:types:[run-deploy]jobs:build:runs-on: ubuntu-lateststeps:-uses: actions/checkout@v3-name: Testrun:| # Strip git ref prefix from version echo "${{ github.ref }}" # VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')# # Strip "v" prefix from tag name# [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') echo "$VERSION"name: CIon:push:tags:- v*jobs:create-docker-image:runs-on: ubuntu-lateststeps:-uses: actions/checkout@master# 向 EVN 写入 CURRENT_VERSION 环境变量赋值版本号-run:| echo "CURRENT_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV# 可以获取到 CURRENT_VERSION 的值-run: echo "${{env.CURRENT_VERSION}}"jobs:build:if:"!contains(github.event.head_commit.message, 'skip ci')"-run: echo "previous_tag=$(git describe--tags--abbrev=0 2>/dev/null|| echo '')">> $GITHUB_ENV-name: Generate changelogid: changeloguses: jaywcjlove/changelog-generator@mainif: env.previous_tag-name: Modify Versionshell: bashrun:| 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))'-name: Deployuses: peaceiris/actions-gh-pages@v3with:github_token: ${{ secrets.GITHUB_TOKEN}}publish_dir: ./build-name: Checkoutuses: actions/checkout@v3with:path: mainsubmodules:truesubmodules:true 检出子模块或recursive 递归检出子模块。
-name: Clone sub repositoryshell: bashrun:| 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 识别在此作业运行之前必须成功完成的任何作业。它可以是一个字符串,也可以是字符串数组。 如果某个作业失败,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。
jobs:job1:job2:needs: job1job3:needs:[job1, job2]在此示例中,job1 必须在job2 开始之前成功完成,而job3 要等待job1 和job2 完成。
此示例中的作业按顺序运行:
❶ job1❷ job2❸ job3jobs:job1:job2:needs: job1job3:if: ${{ always()}}needs:[job1, job2]在此示例中,job3 使用always() 条件表达式,因此它始终在job1 和job2 完成后运行,不管它们是否成功。
Artifacts 是 GitHub Actions 为您提供持久文件并在运行完成后使用它们或在作业(文档)之间共享的一种方式。
要创建工件并使用它,您将需要不同的操作:上传和下载。 要上传文件或目录,您只需像这样使用它:
steps:-uses: actions/checkout@v2-run: mkdir-p path/to/artifact-run: echo hello> path/to/artifact/world.txt-uses: actions/upload-artifact@v2with:name: my-artifactpath: path/to/artifact/world.txt然后下载artifact 以使用它:
steps:-uses: actions/checkout@v2-uses: actions/download-artifact@v2with:name: my-artifact-run: npm publish--access publicenv:NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}获取NPM_TOKEN,可以通过npm 账号创建token
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># 撤销# https://www.basefactor.com/github-actions-docker-name: Docker loginrun: docker login-u ${{ secrets.DOCKER_USER}}-p ${{ secrets.DOCKER_PASSWORD}}-name: Build ant.design imagerun:| cd ./ant\.design docker build -t ant.design .-name: Tags & Push docsrun:| # Strip git ref prefix from version VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')# Strip "v" prefix from tag name[[ "${{ 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-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@masterwith:github_token: ${{ secrets.GITHUB_TOKEN}}-name: Setup Nodeuses: actions/setup-node@v2with:node-version:18jobs:test:# Containers must run in Linux based operating systemsruns-on: ubuntu-lateststrategy:matrix:node-version:[16.x, 18.x, 20.x]steps:-uses: actions/checkout@v3-name: Use Node.js ${{ matrix.node-version}}uses: actions/setup-node@v3with:node-version: ${{ matrix.node-version}}-run: npm ci-run: npm run build--if-present-run: npm test-name: Sync to Giteerun:| mirror() { git clone "https://github.com/$1/$2" cd "$2" git remote add gitee "https://jaywcjlove:${{ secrets.GITEE_TOKEN }}@gitee.com/uiw/$2.git" git remote set-head origin -d git push gitee --prune +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/* cd .. } mirror uiwjs uiw强烈建议操作使用环境变量访问文件系统,而非使用硬编码的文件路径。 GitHub 设置供操作用于所有运行器环境中的环境变量。
| 环境变量 | 描述 |
|---|---|
| CI | 始终设置为 true。 |
| HOME | 用于存储用户数据的 GitHub 主目录路径。 例如 /github/home。 |
| GITHUB_WORKFLOW | 工作流程的名称。 |
| GITHUB_RUN_ID | 仓库中每个运行的唯一编号。 如果您重新执行工作流程运行,此编号不变。 |
| GITHUB_RUN_NUMBER | 仓库中特定工作流程每个运行的唯一编号。 此编号从 1(对应于工作流程的第一个运行)开始,然后随着每个新的运行而递增。 如果您重新执行工作流程运行,此编号不变。 |
| GITHUB_ACTION | 操作唯一的标识符 (id)。 |
| GITHUB_ACTIONS | 当 GitHub 操作 运行工作流程时,始终设置为 true。 您可以使用此变量来区分测试是在本地运行还是通过 GitHub 操作 运行。 |
| GITHUB_ACTOR | 发起工作流程的个人或应用程序的名称。 例如 octocat。 |
| 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。 例如 ffac537e6cbbf934b08745a378932722df287a53。 |
| GITHUB_REF | 触发工作流程的分支或标记参考。 例如 refs/heads/feature-branch-1。 如果分支或标记都不适用于事件类型,则变量不会存在。 |
| GITHUB_HEAD_REF | 仅为复刻的仓库设置。 头部仓库的分支。 |
| GITHUB_BASE_REF | 仅为复刻的仓库设置。 基础仓库的分支。 |
注:
GitHub会保留GITHUB_环境变量前缀供GitHub内部使用。 设置有GITHUB_前缀的环境变量或密码将导致错误。
在https://github.com/<用户名>/<项目名称>/settings/secrets 中添加secretsNODE_API_TOKEN,在工作流中设置环境变量NODE_API_TOKEN
-name: 测试 nodejs 获取环境变量env:NODE_API_TOKEN: ${{ secrets.NODE_API_TOKEN}}run: npm run env| 属性名称 | 类型 | 描述 |
|---|---|---|
| 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。 |
As always, thanks to our amazing contributors!
Made withaction-contributors.
Licensed under the MIT License.