在GitHub操作中评论一个拉取请求

37

我正在尝试使用GitHub操作在拉取请求中插入常规评论,但似乎无法正确实现。 Octokit,这个底层库,允许您为PR创建reviewComments,但这些是指提交,而不是我想要的简单评论。我想我可以使用octokit.issues.createComment来实现。然而,似乎不起作用。

这是代码:

import * as core from '@actions/core';
const {GitHub, context} = require('@actions/github')
const parse = require('parse-diff')

async function run() {
    try {
        // get information on everything
        const token = core.getInput('github-token', {required: true})
        const github = new GitHub(token, {} )
        console.log( context )
        const PR_number = context.payload.pull_request.number

        // Check if the body contains required string
        const bodyContains = core.getInput('bodyContains')

        if ( context.payload.pull_request.body.indexOf( bodyContains) < 0  ) {
            core.setFailed("The body of the PR does not contain " + bodyContains);
            console.log( "Actor " + context.actor + " pr number " PR_number)
            const result = await github.issues.createComment({
                owner: context.actor,
                repo: context.payload.repository.full_name,
                issue_number: PR_number,
                body: "We need to have the word " + bodyContains + " in the body of the pull request"
            });
            console.log(result)
       } // more irrelevant stuff below
}}

这似乎只是返回“未找到”。我似乎找不出它是否是类型问题,还是其他问题。理论上,所有者,存储库和问题编号以及正文应该是正确的,并且已经正确地打印了。任何帮助都将不胜感激。这可能是GitHub API领域中更一般的问题,而GitHub操作仅是上下文,所以我可能是错的。


1
我有类似的需求,希望通过GitHub Actions插入类似机器人的评论。我将不怕丢脸地分享我的repo,我使用axios和REST调用完成了这个技巧 - 一些示例PR和问题都在这个repo中:https://github.com/rytswd/respost/ - Ryota
7个回答

69

一种规范的方法是使用官方的Github Script actions。不要混淆,对于GitHub API来说,问题和PR是相同的。

2020年:

on:
  # Trigger the workflow on push or pull request
  pull_request:
    branches:
      - master
      - develop

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: ' Thanks for reporting!'
            })

在以下位置看到:https://github.com/actions/github-script#comment-on-an-issue

编辑于2021年:

为了适应GH的新版本,必须直接引用REST客户端。请参阅写作时的说明

on:
  # Trigger the workflow on push or pull request
  pull_request:
    branches:
      - master
      - develop

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v5
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: ' Thanks for reporting!'
            })

修改于2023年:

V6已发布,以下是如何使用它的方法。没有破坏性变化,只是脚本版本已更改。

on:
  # Trigger the workflow on push or pull request
  pull_request:
    branches:
      - master
      - develop

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: ' Thanks for reporting!'
            })


3
我不喜欢这种 2020 年的方法。使用 curl 触摸真实的 API 端点应该是正确的做法。否则,这些 Github Actions 就像脚本一样没有用处,因为它使用了另一个“脚本”,因此模糊了意图并使其处于危险之中。结果会让你变得愚蠢,因为你不知道(或者更准确地说,无法控制)正在发生什么。 - Sevastyan Savanyuk
7
@SevastyanSavanyuk 楼主的措辞可能可以更加客观一些,但一旦你进入了 GH 生态系统,我认为想要减少对它的依赖有点不必要。在使用 actions 上有很多经验后,我认为这是最好的选择。 - eljefedelrodeodeljefe
2
关于“不要混淆,GitHub API 中的问题和 PR 是相同的。”,请查看 https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts#L55-L62 - yskkin
4
这个应该由pull_request_target触发,而不是pull_request触发吧?在由pull_request触发的运行中,GITHUB_TOKEN没有对仓库的写入权限,会导致错误信息“集成无法访问资源”。 - David Lechner
1
@Kay 最近我解决了一个关于PR的“资源无法被集成访问”的问题。你需要在GitHub工作流中添加pull_requests: write权限。这里可以找到一些示例:https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs - wjkw1
显示剩余8条评论

31

我最初尝试使用Respost,但它不允许设置原始的body字符串。

所以这里介绍一种使用curl的方法。

.github/workflows/whatever.yml文件中:

name: Some workflow

on:
  issue_comment:
    types: [created]

jobs:
  comment:
    if: contains(github.event.comment.body, 'special string')

    runs-on: ubuntu-latest

    steps:
      - name: Add comment to PR
        env:
          URL: ${{ github.event.issue.comments_url }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          curl \
            -X POST \
            $URL \
            -H "Content-Type: application/json" \
            -H "Authorization: token $GITHUB_TOKEN" \
            --data '{ "body": "blah blah" }'

12
对于事件 pull_request,我必须使用 ${{ github.event.pull_request.comments_url }} 作为 URL。 - binaryfunt
1
有关字符串替换的帮助,请参见此处有关单引号/双引号的内容:https://dev59.com/dWYr5IYBdhLWcg3wR4Us - bubbaspike

9

您还可以使用 @actions/github,这将允许您使用 Octokit 客户端 来简化操作:

const core = require('@actions/core');
const github = require('@actions/github');

async function run() {
  try {
    const message = core.getInput('message');
    const github_token = core.getInput('GITHUB_TOKEN');

    const context = github.context;
    if (context.payload.pull_request == null) {
        core.setFailed('No pull request found.');
        return;
    }
    const pull_request_number = context.payload.pull_request.number;

    const octokit = new github.GitHub(github_token);
    const new_comment = octokit.issues.createComment({
        ...context.repo,
        issue_number: pull_request_number,
        body: message
      });

  } catch (error) {
    core.setFailed(error.message);
  }
}

run();

此内容取自仓库


这是一个独立于工作流程的演示:workflow.ymlmain.js。但是,最好还是使用 actions/github-script:https://dev59.com/GVMH5IYBdhLWcg3w1Dr0#64126737 - Ciro Santilli OurBigBook.com

8
其他答案没有提到的是,从触发pull_request事件的分叉处运行的GitHub操作的安全限制。这些操作中的GITHUB_TOKEN没有对存储库的写访问权限,因此无法创建评论。请参阅GITHUB_TOKEN的权限workflow_run事件的GitHub文档有一个很好的解决方法示例。基本思路是由pull_request事件触发的工作流在使用actions/upload-artifact上传任何需要在评论中使用的信息作为构建成果物。然后,由workflow_run事件触发的单独的工作流使用actions/download-artifact下载信息。
注意:出于安全原因,由workflow_run触发的工作流具有写访问权限,必须在使用之前提交到默认分支。(还要记住,构建成果物可能包含来自恶意拉取请求的恶意数据)
以下是来自链接文档的示例工作流的副本(以防链接失效或文档更改):
name: Upload data

on:
  pull_request:

jobs:
  upload:
    runs-on: ubuntu-latest

    steps:        
      - name: Save PR number
        env:
          PR_NUMBER: ${{ github.event.number }}
        run: |
          mkdir -p ./pr
          echo $PR_NUMBER > ./pr/pr_number
      - uses: actions/upload-artifact@v3
        with:
          name: pr_number
          path: pr/

name: Use the data

on:
  workflow_run:
    workflows: [Upload data]
    types:
      - completed

jobs:
  download:
    runs-on: ubuntu-latest
    steps:
      - name: 'Download artifact'
        uses: actions/github-script@v5
        with:
          script: |
            let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: context.payload.workflow_run.id,
            });
            let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
              return artifact.name == "pr_number"
            })[0];
            let download = await github.rest.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: matchArtifact.id,
               archive_format: 'zip',
            });
            let fs = require('fs');
            fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data));

      - name: 'Unzip artifact'
        run: unzip pr_number.zip

      - name: 'Comment on PR'
        uses: actions/github-script@v5
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            let fs = require('fs');
            let issue_number = Number(fs.readFileSync('./pr_number'));
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue_number,
              body: 'Thank you for the PR!'
            });

3

我非常喜欢GitHub操作评论拉取请求,因为它允许更新评论。

添加评论的示例:

- name: Comment PR
  uses: thollander/actions-comment-pull-request@v2
  with:
    message: |
      Hello world ! :wave:
    reactions: eyes, rocket

通过“标签”(以“隐藏”的HTML元素形式呈现)来更新评论。
- name: Comment PR with execution number
  uses: thollander/actions-comment-pull-request@v2
  with:
    message: |
      _(execution **${{ github.run_id }}** / attempt **${{ github.run_attempt }}**)_
    comment_tag: execution

1

这是我在想要从一个push事件中评论PR时使用的方法(而不是pull_request事件,那里很容易):

      - uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: (await github.rest.repos.listPullRequestsAssociatedWithCommit({
                commit_sha: context.sha,
                owner: context.repo.owner,
                repo: context.repo.repo,
              })).data[0].number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: ' Thanks for reporting!'
            })

关键部分在于这个,它允许获取PR的正确“问题编号”:
await github.rest.repos.listPullRequestsAssociatedWithCommit({
                commit_sha: context.sha,
                owner: context.repo.owner,
                repo: context.repo.repo,
              })).data[0].number

1
你需要对你的工作拥有写入权限,这对我起作用了。从另一个评论中得到了灵感。
stage_test:
    permissions: write-all
    runs-on: [ubuntu-latest]
    steps:
    - name: Check out code
      uses: actions/checkout@v2 
    - name: Comment PR
      uses: thollander/actions-comment-pull-request@v2
      with:
        message: |
          Test successful !
        reactions: rocket

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接