diff --git a/README.md b/README.md index 6535a4d..82cabc5 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Quick Reference ## 其它 [Quick Reference](./docs/quickreference.md) +[Github Actions](./docs/github-actions.md) [Colors Named](./docs/colors-named.md) [HTTP 状态码](./docs/http-status-code.md) [HTML 字符实体](./docs/html-char.md) diff --git a/docs/github-actions.md b/docs/github-actions.md new file mode 100644 index 0000000..64bddb9 --- /dev/null +++ b/docs/github-actions.md @@ -0,0 +1,774 @@ +Github Actions 备忘清单 +==== + +本备忘单总结了 [Github Actions](https://github.com/actions) 常用的配置说明,以供快速参考。 + +入门 +--- + +### 介绍 + +GitHub [Actions](https://github.com/actions) 的仓库中自动化、自定义和执行软件开发工作流程,有四个基本的概念,如下: + +:- | :- +:- | :- +`workflow` _(工作流程)_ | 持续集成一次运行的过程,就是一个 `workflow` +`job` _(任务)_ | 一个 `workflow` 由一个或多个 `jobs` 构成,含义是一次持续集成的运行,可以完成多个任务 +`step` _(步骤)_ | 每个 `job` 由多个 `step` 构成,一步步完成 +`action` _(动作)_ | 每个 `step` 可以依次执行一个或多个命令(`action`) + + +--- + +- 采用 [YAML](./yaml.md) 格式定义配置文件 +- 存放在代码仓库的 `.github/workflows` 目录中 +- 后缀名统一为 `.yml`,比如 `ci.yml` +- 一个库可以有多个 `workflow` 文件 +- 根据配置事件自动运行配置文件 + + +### 配置文件 + +```yaml {3,5,10} +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` + +```yaml +on: push +``` + +`push` 事件或 `pull_request` 事件都可以触发 `workflow` + +```yaml +on: [push, pull_request] +``` + +只有在 `main` 分支 `push` 事件触发 `workflow` + +```yaml {2} +on: + push: + branches: + - main +``` + +`push` 事件触发 `workflow`,`docs` 目录下的更改 `push` 事件不触发 `workflow` + +```yaml {2,4} +on: + push: + paths-ignore: + - 'docs/**' +``` + +push 事件触发 workflow,包括 sub-project 目录或其子目录中的文件触发 workflow,除非该文件在 sub-project/docs 目录中,不触发 workflow + +```yaml +on: + push: + paths: + - 'sub-project/**' + - '!sub-project/docs/**' +``` + +版本发布为 `published` 时运行工作流程。 + +```yml +on: + release: + types: [published] +``` + +### 多项任务 + +```yml +jobs: + my_first_job: # 第一个任务 + name: My first job + + my_second_job: # 第二个任务 + name: My second job +``` + +通过 jobs `(jobs..name)`字段,配置一项或多项需要执行的任务 + +### 多项任务依赖关系 + +通过 needs `(jobs..needs)`字段,指定当前任务的依赖关系 + +```yml +jobs: + job1: + job2: + needs: job1 + job3: + needs: [job1, job2] +``` + +上面配置中,`job1` 必须先于 `job2` 完成,而 `job3` 等待 `job1` 和 `job2` 的完成才能运行。因此,这个 `workflow` 的运行顺序依次为:`job1`、`job2`、`job3` + +### 多项任务传递参数 + + +```yml {2,5,9,11,15} +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}} +``` + +### 指定每项任务的虚拟机环境 + +```yml +runs-on: ubuntu-latest +``` + +指定运行所需要的虚拟机环境,⚠️ 它是必填字段 + +```yml {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 托管的运行器](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#选择-github-托管的运行器) + +### 指定每项任务的步骤 + +每个步骤都可以指定以下三个字段 + +```shell +jobs..steps.name # 步骤名称 +# 该步骤运行的命令或者 action +jobs..steps.run +# 该步骤所需的环境变量 +jobs..steps.env +``` + +`steps` 字段指定每个 `Job` 的运行步骤,可以包含一个或多个步骤(`steps`) + +```yml {4} +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 +``` + +### 环境变量 + +```shell +jobs..environment +``` +使用单一环境名称的示例 + +```yml +environment: staging_environment +``` + +使用环境名称和 URL 的示例 + +```yml +environment: + name: production_environment + url: https://github.com +``` + +#### 自定义环境变量 + +`GitHub` 会保留 `GITHUB_` 环境变量前缀供 `GitHub` 内部使用。设置有 `GITHUB_` 前缀的环境变量或密码将导致错误。 + +```yml +- name: 测试 nodejs 获取环境变量 + env: + API_TOKEN: ${{ secrets.API_TOKEN }} +``` + +在 `https://github.com/<用户名>/<项目名称>/settings/secrets` 中添加 `secrets` `API_TOKEN`,在工作流中设置环境变量 [`API_TOKEN`](https://github.com/jaywcjlove/github-actions/blob/799b232fca3d9df0272eaa12610f9ebfca51b288/.github/workflows/ci.yml#L46) + +### 表达式 + +在 `if` 条件下使用表达式时,可以省略表达式语法 (`${{ }}`),因为 GitHub 会自动将 `if` 条件作为表达式求值 + +```yml {3} +steps: + - uses: actions/hello-world-action@v1.1 + if: github.repository == 'uiw/uiw-repo' + # if: ${{ }} +``` + +设置环境变量的示例 + + +```yml +env: + MY_ENV_VAR: ${{ }} +``` + +#### 操作符 + +- `( )` _(逻辑分组)_ +- `[ ]` _(指数)_ +- `.` _(属性取消引用)_ +- `!` _(不是)_ +- `<` _(少于)_ +- `<=` _(小于或等于)_ +- `>` _(比...更棒)_ +- `>=` _(大于或等于)_ +- `==` _(平等的)_ +- `!=` _(不相等)_ +- `&&` _(和)_ +- `||` _(或者)_ + + +### 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 上下文](https://help.github.com/cn/actions/reference/context-and-expression-syntax-for-github-actions)是访问有关工作流运行、运行器环境、作业和步骤的信息的一种方式 + +### 默认环境变量 + +环境变量 | 描述 +---- | ---- +`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](https://github.com/actions/checkout) 操作,工作空间目录将包含存储仓库副本的子目录。 如果不使用 [actions/checkout](https://github.com/actions/checkout) 操作,该目录将为空。 例如 /home |/runner/work/my-repo-name/my-repo-name +`GITHUB_SHA` | 触发工作流程的提交 SHA。 例如 ffac537e6cbbf9 +`GITHUB_REF` | 触发工作流程的分支或标记参考。 例如 refs/heads/feature-branch-1。 如果分支或标记都不适用于事件类型,则变量不会存在 +`GITHUB_HEAD_REF` | 仅为复刻的仓库设置。头部仓库的分支 +`GITHUB_BASE_REF` | 仅为复刻的仓库设置。基础仓库的分支 + + +另见: [默认环境变量](https://docs.github.com/cn/actions/learn-github-actions/environment-variables#default-environment-variables) + +### 直接常量 + + +作为表达式的一部分,可以使用 `boolean`, `null`, `number` 或 `string`数据类型 + +```yml +env: + myNull: ${{ null }} + myBoolean: ${{ false }} + myIntegerNumber: ${{ 711 }} + myFloatNumber: ${{ -9.2 }} + myHexNumber: ${{ 0xff }} + myExponentialNumber: ${{ -2.99e-2 }} + myString: Mona the Octocat + myStringInBraces: ${{ 'It''s open source!' }} +``` + +### 函数 contains + + +使用字符串的示例 + +```js +contains('Hello world', 'llo') // 返回 true +``` + +使用对象过滤器的示例返回 true + +```js +contains(github.event.issue.labels.*.name, 'bug') +``` + + +另见: [函数 contains](https://docs.github.com/cn/actions/learn-github-actions/expressions#contains) + +### 函数 startsWith + +```js +startsWith('Hello world', 'He') // 返回 true +``` + +另见: [函数 startsWith](https://docs.github.com/cn/actions/learn-github-actions/expressions#startswith),此函数不区分大小写 + +### 函数 format + +```js +format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat') +// 返回 '{Hello Mona the Octocat!}'. +``` + +另见: [函数 format](https://docs.github.com/cn/actions/learn-github-actions/expressions#format) + +### 函数 join + +```js +join(github.event.issue.labels.*.name, ', ') +// 也许返回 'bug, help wanted'. +``` + +另见: [函数 join](https://docs.github.com/cn/actions/learn-github-actions/expressions#join) + +### 函数 toJSON + +```js +toJSON(job) +// 也许返回 { "status": "Success" }. +``` + +另见: [函数 toJSON](https://docs.github.com/cn/actions/learn-github-actions/expressions#tojson) + +### 函数 + + +:- | :- +:- | :- +`fromJSON` | 返回 JSON 对象或 JSON 数据类型的值 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#fromjson) +`hashFiles` | 返回与路径模式匹配的文件集的单个哈希 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#hashfiles) +`success` | 当前面的步骤都没失败或被取消时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#success) +`always` | 使步骤始终执行,返回 `true` 即使取消也是如此 [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#always) +`cancelled` | 如果工作流被取消,则返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#cancelled) +`failure` | 当作业的任何先前步骤失败时返回 true [#](https://docs.github.com/cn/actions/learn-github-actions/expressions#failure) + +### 函数 success() + +```yml +steps: + ... + - name: The job has succeeded + if: ${{ success() }} +``` + +### 函数 failure() + +```yml +steps: + ... + - name: The job has failed + if: ${{ failure() }} +``` + +常用实例 +---- + +### 获取版本信息 + + +```yml +- name: Test + run: | + # 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" +``` + + +### 提交到 gh-pages 分支 + +```yml +- name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{secrets.GITHUB_TOKEN}} + publish_dir: ./build +``` + +### 修改 package.json + +```yml +- 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](https://github.com/jaywcjlove/github-action-package) 修改 `name` 字段 + +```yml +- name: package.json info + uses: jaywcjlove/github-action-package@main + with: + rename: '@wcj/github-package-test' +``` + +### 克隆带有 Submodule 的仓库 + +```yml +- name: Checkout + uses: actions/checkout@v3 + with: + path: main + submodules: true +``` + +`submodules`:`true` 检出子模块或 `recursive` 递归检出子模块 + +```yml +- 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..needs` 识别在此作业运行之前必须成功完成的任何作业。它可以是一个字符串,也可以是字符串数组。 如果某个作业失败,则所有需要它的作业都会被跳过,除非这些作业使用让该作业继续的条件表达式。 + +```yml +jobs: + job1: + job2: + needs: job1 + job3: + needs: [job1, job2] +``` + +在此示例中,`job1` 必须在 `job2` 开始之前成功完成,而 `job3` 要等待 `job1` 和 `job2` 完成。此示例中的作业按顺序运行: + +``` +❶ job1 +❷ job2 +❸ job3 +``` + +配置如下 + +```yml +jobs: + job1: + job2: + needs: job1 + job3: + if: ${{ always() }} + needs: [job1, job2] +``` + +在此示例中,`job3` 使用 `always()` 条件表达式,因此它始终在 `job1` 和 `job2` 完成后运行,不管它们是否成功。 + +### 同步 Gitee + + +```yml +- 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 包 + +```yml +- run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} +``` + +获取 `NPM_TOKEN`,可以通过 [npm](https://www.npmjs.com/settings/wcjiang/tokens) 账号创建 `token` + +```shell +npm token list [--json|--parseable] # 查看 +npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] # 创建 +npm token revoke # 撤销 +``` + + +可以使用 [JS-DevTools/npm-publish](https://github.com/JS-DevTools/npm-publish) 提交 + +```yml +- 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 为您提供持久文件并在运行完成后使用它们或在作业(文档)之间共享的一种方式。 + +要创建工件并使用它,您将需要不同的操作:上传和下载。 +要上传文件或目录,您只需像这样使用它: + +```yml +steps: + - uses: actions/checkout@v2 + - run: mkdir -p path/to/artifact + - run: echo hello > path/to/artifact/a.txt + - uses: actions/upload-artifact@v2 + with: + name: my-artifact + path: path/to/artifact/a.txt +``` + +然后下载 `artifact` 以使用它: + +```yml +steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + with: + name: my-artifact +``` + +### Node.js + +```yml +- name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: 14 +``` + +使用[矩阵策略](https://docs.github.com/cn/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategy) 在 nodejs 不同版本中运行 + +```yml +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 镜像 + + +```yml +# https://www.basefactor.com/github-actions-docker +- 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,') + + # 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 +``` + +### 创建一个 tag + +```yml +- name: Create Tag + id: create_tag + uses: jaywcjlove/create-tag-action@main + with: + package-path: ./package.json +``` + +根据 `package-path` 指定的 `package.json` 检测 `version` 是否发生变化来创建 `tag` + +### 生成 git 提交日志 + +```yml +- 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 镜像仓库 + + +```yml +- 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 分支 + + +```yml +- 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 }} +``` + +### 作业之间共享数据 + +创建一个文件,然后将其作为构件上传 + +```yml {11} +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` 的工件 + +```yml {7} +jobs: + example-job: + steps: + - name: Download a single artifact + uses: actions/download-artifact@v3 + with: + name: output-log-file +``` + +另见 +--- + +- [Github Actions 学习笔记](https://jaywcjlove.github.io/github-actions) _(jaywcjlove.github.io)_ +- [了解 GitHub Actions](https://docs.github.com/cn/actions/learn-github-actions) _(docs.github.com)_ \ No newline at end of file diff --git a/scripts/assets/github-actions.svg b/scripts/assets/github-actions.svg new file mode 100644 index 0000000..76aed5d --- /dev/null +++ b/scripts/assets/github-actions.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file