GitHub 操作 ***NO_CI*** 备选方案

GitHub Actions ***NO_CI*** alternative

我正在尝试从 GitHub Actions Beta(YAML 的)中的工作流 运行 将代码推送到 GitHub 存储库。在将 origin 远程 URL 设置为包含凭据的 运行ning git push 之后,这很容易做到,这样 Git 就知道如何使用 Git中心

GitHub Actions 甚至开箱即用 PAT:GITHUB_TOKEN,它可以使用并且整个系统足够聪明,知道在推送提交时不要安排另一个操作使用 PAT 的存储库已知与以前的工作流程相关联运行。

这很好,但是,有使用自定义 PAT 的用例(在我的例子中触发 GitHub 页面来构建,开箱即用的 PAT 不会这样做)和使用自定义 PAT 失去了 GitHub 在从当前工作流推送提交后不知道 运行 另一个工作流的优势。

因此,在使用自定义 PAT 时,人们会发现自己处于工作流程的无限循环中。许多 CI 解决方案在提交消息中尊重 ***NO_CI***,并且如果提交消息中存在此字符串,则不会 运行 任何 checks/builds/whatever。 GitHub Actions Beta 不关心它。

我唯一能想到的就是使 GitHub Action 工作流程 job/step 有条件并构建如下条件:

- if: !contains(github.commit_message, "***NO_CI***")

但是 github 上下文对象没有包含提交消息的字段,并且上下文似乎没有足够的表现力让我 运行 一个命令来获取提交来自 SHA 的消息使用 Git 和 运行 在 contains 上。

我有什么选择可以实现这个目标吗?

检查 GitHub Actions for GitHub Pages

中是否存在替代方法

例如:peaceiris/actions-gh-pages,其中添加了 ACTIONS_DEPLOY_KEY SSH 密钥并将其用于该工作流程。

GitHub Pages Deploy只包括:

请记住添加适当的 filter action 作为此操作的依赖项,以避免从所有分支部署,并避免 "infinite loops" 部署本身会触发另一个 运行.

在我上面提到的工作流程中使用了此类过滤器(在 this commit or this one 中)。

GitHub 操作本身不支持 ***NO_CI***,相反,它们依赖于您使用预定义的 secrets.GITHUB_TOKEN 上下文值推送到存储库。 GitHub 如果使用此令牌,操作将对此令牌进行特殊处理,并且不会发出任何新的工作流 运行。但是当使用此令牌进行推送时,他们也不会部署 GitHub 页面。

我发现为了获得这两种行为(工作流推送到存储库不会导致另一个工作流 运行 + GitHub 从工作流 运行 工件构建页面推送到存储库),有必要结合两件事:

  • 使用secrets.GITHUB_TOKEN 推送到存储库
  • 使用带有 repo_public(或 repo 私有)范围的自定义 PAT,该范围位于存储库设置的“机密”选项卡中,并使用 secrets.GITHUB_PAGES_PAT
  • 访问
  • 运行 GitHub 使用带有自定义 PAT 的 API 手动部署页面(默认令牌标记为集成令牌,不允许调用此 API方法)

一个例子.github/workflows/main.yml:

name: github-pages
on:
  push:
    branches:
    # Limit to the `master` branch
    - master
  schedule:
    # Run hourly
    - cron:  '0 * * * *'
jobs:
  github-pages:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - name: Generate GitHub Pages
      run: |
        set -x
        # Configure Git for the push from the workflow to the repository
        git config --global user.email "tomas@hubelbauer.net"
        git config --global user.name "Tomas Hubelbauer"
        # Check out the `master` branch because by default GitHub Actions checks out detached HEAD
        git checkout master
        # Run script which generates your artifacts to push to the repo
        ./script.sh
        # Add generated artifacts to Git stage
        git add out
        # Reset unstaged changes to prevent `git commit` from yelling if there's changes outside of `out` (cache, …)
        git checkout -- .
        # Commit the changes to the Git repository to deploy GitHub Pages (if any)
        if git diff-index --quiet HEAD --; then
          exit
        fi
        git commit -m "Generate GitHub Pages"
        # Authenticate with GitHub using the default integration PAT (this one won't deploy GitHub Pages)
        git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
        # Pull before pushing to integrate fast forward changes if any
        git pull --rebase
        # Push the changes to GitHub without causing another workflow run thanks to the default integration PAT
        git push
        # Enqueue a GitHub Pages deployment using the API with the custom PAT with repo_public or repo (private) scope
        curl -f -X POST -H "Authorization: token ${{ secrets.GITHUB_PAGES_PAT }}" -H "Accept: application/vnd.github.mister-fantastic-preview+json" "https://api.github.com/repos/${{ github.repository }}/pages/builds"

您可以按照自己的方式配置 Github 操作。

- if: "!contains(github.event.head_commit.message, '***NO_CI***')"

# dump all github context
- name: Dump GitHub context
  env:
    GITHUB_CONTEXT: ${{ toJson(github) }}
  run: echo "$GITHUB_CONTEXT"

另外不要忘记在使用 ! 时将句子用引号引起来。

参考: https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions

这是 ***NO_CI***[skip ci] 的解决方法。

name: github pages

on:
  push:
    branches:
      - master  # Set a branch name to trigger deployment

jobs:
  skipci:
    runs-on: ubuntu-18.04
    steps:
      - run: echo "[skip ci] ${{ contains(github.event.head_commit.message, '[skip ci]') }}"

  deploy:
    runs-on: ubuntu-18.04
    if: contains(github.event.head_commit.message, '[skip ci]') == false
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.76.3'

      - name: Build
        run: hugo --minify

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

使用提交消息跳过的部署作业 update [skip ci] 日志:https://i.stack.imgur.com/3rVFG.png