从 GitHub 操作推送到源

Kir*_*ill 33 git github docker github-actions building-github-actions

我正在尝试origin从 GitHub 操作推送到远程。我的行动逻辑是:

  • 处理pull_request_review事件并按评论消息过滤
  • checkout to master, merge PR branch, run some checks and push it to origin

The script is:

if [[ "${GITHUB_EVENT_NAME}" != "pull_request_review" ]]; then
  echo "unsupported event: ${GITHUB_EVENT_NAME}"
  exit 1
fi

user=$(jq -r .review.user.login ${GITHUB_EVENT_PATH})
cmd=$(jq -r .review.body ${GITHUB_EVENT_PATH})
echo "reviewer is ${user}, command is ${cmd}"

if [[ "${cmd}" == "merge" ]]; then
  head=$(jq -r .pull_request.head.ref ${GITHUB_EVENT_PATH})
  git config user.email test@test.com
  git config user.name test
  git checkout -B _tmp origin/${head}
  git checkout -B master origin/master
  git merge --no-ff _tmp
  git push origin master
fi
Run Code Online (Sandbox Code Playgroud)

I'm running this script from alpine:3.10 Docker container:

FROM alpine:3.10

LABEL "com.github.actions.name"="Hello world action"
LABEL "com.github.actions.icon"="shield"
LABEL "com.github.actions.color"="green"

WORKDIR /app
COPY action.sh action.sh
RUN apk --update add bash git jq
CMD ["bash", "/app/action.sh"]
Run Code Online (Sandbox Code Playgroud)

First steps are working fine (checkout and merge), but action failed to push the merge to origin because of the error:

+ git push origin master
fatal: could not read Username for 'https://github.com': No such device or address

It looks like GitHub-action Docker container is not configured to push to GitHub. How can I configure it? Is it possible to use some of the env variables provided by GitHub or maybe some mounted files (like in /github/* path)?

pet*_*ans 95

动作/结帐@v2

结帐的第 2 版解决了分离的 HEAD 状态问题并简化了推送到源的过程。

name: Push commit
on: push
jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Create report file
        run: date +%s > report.txt
      - name: Commit report
        run: |
          git config --global user.name 'Your Name'
          git config --global user.email 'your-username@users.noreply.github.com'
          git commit -am "Automated report"
          git push
Run Code Online (Sandbox Code Playgroud)

如果您需要推送事件来触发其他工作流,请使用repo范围内的Personal Access Token

      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.PAT }}
Run Code Online (Sandbox Code Playgroud)

动作/结帐@v1(原始答案)

为@rmunn 的优秀答案添加更多细节。问题是该actions/checkout@v1操作使 git 存储库处于分离的 HEAD 状态。有关更多详细信息,请参阅此问题:https : //github.com/actions/checkout/issues/6

这是一个完整的示例,用于演示如何将签出的存储库置于可用状态并推送到远程。

name: Push commit
on: push
jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Create report file
        run: date +%s > report.txt
      - name: Commit report
        run: |
          git config --global user.name 'Your Name'
          git config --global user.email 'your-username@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
          git checkout "${GITHUB_REF:11}"
          git commit -am "Automated report"
          git push
Run Code Online (Sandbox Code Playgroud)

要包含未跟踪的(新)文件,请更改工作流程以使用以下内容。

          git add -A
          git commit -m "Automated report"
Run Code Online (Sandbox Code Playgroud)

上述工作流程应该适用于大多数事件。对于on: pull_request工作流,GITHUB_HEAD_REF应检出合并分支 ( ) 以替换默认合并提交。

重要提示:如果除了以下工作流程之外,您还有其他拉取请求检查,那么您必须使用个人访问令牌而不是默认的GITHUB_TOKEN. 这是由于 GitHub Actions 故意限制工作流(例如push)引发的事件无法触发进一步的工作流运行。这是为了防止意外的“无限循环”情况,并作为一种反滥用措施。使用repo范围内的个人访问令牌是一种已批准的解决方法。有关解决方法的更多详细信息,请参阅此 GitHub 问题

name: Push commit on pull request
on: pull_request
jobs:
  report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
        with:
          ref: ${{ github.head_ref }}
      - name: Create report file
        run: date +%s > report.txt
      - name: Commit report
        run: |
          git config --global user.name 'Your Name'
          git config --global user.email 'your-username@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
          git commit -am "Automated report"
          git push
Run Code Online (Sandbox Code Playgroud)

有关在on: pull_request工作流期间推送到源的更多示例,请参阅此博客文章GitHub 操作:如何在拉取请求中自动设置代码格式

  • 有没有办法在创作提交之前检查是否有任何文件已更改?为了避免在测试或使用多个节点版本时出现错误,并且已经使用工作流程的第一次运行推送了提交。 (3认同)
  • 对于任何好奇的人,checkout@v2 凭证存储在“git config http.https://github.com/.extraheader”中 (2认同)

Vad*_*dik 13

以下是如何使用官方 github 操作actions/checkout@v3的示例:

name: Example Push Action
on: push
permissions:
  contents: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: |
          date > generated.txt
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add .
          git commit -m "generated"
          git push
Run Code Online (Sandbox Code Playgroud)

  • 是的,缺少“内容:写入”权限。谢谢你! (3认同)

rmu*_*unn 12

您可以将其secrets.GITHUB_TOKEN用作存储库 URL 上的密码。所以你可以在你的git push行之前添加这个:

git remote set-url --push origin https://your_username:$GITHUB_TOKEN@github.com/your/repo
Run Code Online (Sandbox Code Playgroud)

这假设您已经将 GITHUB_TOKEN 秘密作为环境变量传递给您的脚本。如果不是,请添加:

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Run Code Online (Sandbox Code Playgroud)

到您的工作流程步骤。


nik*_*ohn 8

所有的回复都很好,但我应该注意到,有一个 GitHub Action Add & Commit大大简化了流程。

name: Commit Date
on: push

jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Create report file
        run: date +%s > report.txt

      - name: Commit changes
        uses: EndBug/add-and-commit@v9
        with:
          author_name: Your Name
          author_email: mail@example.com
          message: 'Your commit message'
          add: 'report.txt'
Run Code Online (Sandbox Code Playgroud)


小智 5

所有提供的答案都是正确的。但我想对这些答案添加更多内容。可能存在文件没有更改的情况。因此,在这种情况下,当尝试执行该git commit命令时,它会返回一个导致 GitHub 工作流程失败的错误(失败的工作流程会阻止 PR 合并)。所以我们在commit之前要检查文件是否有变化。

name: Config Generator
on:
  pull_request:
    branches: [ main ]

jobs:
  config-generator:
    runs-on: ubuntu-latest
    steps: 
      - uses: actions/checkout@v2
        with:
          ref: ${{ github.head_ref }}

      - name: Install jsonnet
        run: sudo apt install -y jsonnet

      - name: Generate probe configs
        run: python3 generate-configs.py

      - name: Check for modified files
        id: git-check
        run: echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ]; then echo "true"; else echo "false"; fi)

      - name: Update changes in GitHub repository
        if: steps.git-check.outputs.modified == 'true'
        run:  |
          git config --global user.name 'Your Name' 
          git config --global user.email 'Your Email for GitHub'
          git add -A
          git commit -m '[automated commit] add configs generated using jsonnet & GitHub workflow'
          git push
Run Code Online (Sandbox Code Playgroud)

上述工作流程是使用 jsonnet 和 GitHub 工作流程创建配置文件的示例。它首先安装 jsonnet 并运行一个 python 脚本,该脚本使用 jsonnet 模板创建配置文件。如上所述,可能存在没有文件更改的情况。所以它使用git status命令来检查是否有任何文件更改。(也可以使用 来代替 。但它不会显示未跟踪的文件)git statusgit diff其余 git 命令仅在文件发生更改时运行。

ref: ${{ github.head_ref }}另请注意,即使我使用过,我也必须使用签出到源分支checkout@v2(在我的情况下仍然存在分离头问题)