DEV Community

Chris Cook
Chris Cook

Posted on

Trigger GitHub Workflow for Comments on Pull Request

GitHub Actions is a powerful feature that allows developers to automate tasks and build workflows that can be triggered in response to events such as push, pull request creation, issue creation, and many others. In this article, we'll explore how you can use comments on pull requests to trigger GitHub Actions workflows.

To get started, let's first create a new workflow that will be triggered when a comment is added to a pull request. Create a new file in the .github/workflows directory of your repository and name it something like deploy-on-comment.yml. Here's a basic example of what this file might look like:

name: "Deploy on Comment"

on:
  issue_comment:
    types: [created]

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.event.issue.pull_request && contains(github.event.comment.body, '/deploy')
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Deploy
        run: |
          echo "Deploying..."
Enter fullscreen mode Exit fullscreen mode

Let's break this down. The on key specifies the event that will trigger the workflow. In this case, we're using the issue_comment event, which is triggered when a comment is created or edited on an issue or pull request. The types key specifies which types of comment events to listen for, in this case, we're only interested in when a comment is created.

The event is triggered for issues and pull requests. However, we're only interested in PRs. Note the if condition on the job definition. It is using the github.event object to access information about the event that triggered the workflow. In this case, we're checking whether the issue_comment event was triggered on a pull request and whether the comment body contains the /deploy string. If those conditions are met, the workflow will continue to the deploy job.

Get the right branch

One caveat is, that the issue_comment event runs on the default branch (usually main or master) of the repository, and not on the branch of the pull request. This means that if you are using the issue_comment event to trigger a workflow that performs actions on the branch of the pull request, you will need to take additional steps to reference the correct branch.

We will use the GitHub Action xt0rted/pull-request-comment-branch@v1 to determine the correct branch. We will pass this branch then actions/checkout@v3 to check out the right branch.

#...

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.event.issue.pull_request && contains(github.event.comment.body, '/deploy')
    steps:
      - name: Get PR branch
        uses: xt0rted/pull-request-comment-branch@v1
        id: comment-branch

      - name: Checkout PR branch
        uses: actions/checkout@v3
        with:
          ref: ${{ steps.comment-branch.outputs.head_ref }}

      - name: Deploy
        run: |
          echo "Deploying..."
Enter fullscreen mode Exit fullscreen mode

Show the workflow result on the PR

It's important to note that when using an issue_comment event to trigger a workflow that performs actions on a pull request branch, the workflow run will not appear on the pull request page by default. This is because the issue_comment event runs in the context of the default branch, and not the pull request branch.

In other words, while the workflow will be triggered by the comment on the pull request, it will not be attached to the pull request itself. This can make it difficult to track the status of the workflow in the context of the pull request.

To solve this issue, we will use the GitHub Action myrotvorets/set-commit-status-action@master to manually attach a check to the latest commit on the pull request.
This will allow us to see the status of the workflow on the pull request page and is useful if you have multiple workflows running on the same pull request, or if you want to ensure that the workflow has completed successfully before merging the pull request.

#...

jobs:
  deploy:
    name: Deploy
    if: github.event.issue.pull_request && contains(github.event.comment.body, '/deploy')
    runs-on: ubuntu-latest

    steps:
      - name: Get PR branch
        uses: xt0rted/pull-request-comment-branch@v1
        id: comment-branch

      - name: Set latest commit status as pending
        uses: myrotvorets/set-commit-status-action@master
        with:
          sha: ${{ steps.comment-branch.outputs.head_sha }}
          token: ${{ secrets.GITHUB_TOKEN }}
          status: pending

      - name: Checkout PR branch
        uses: actions/checkout@v3
        with:
          ref: ${{ steps.comment-branch.outputs.head_ref }}

      - name: Setup Node.js 16
        uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Deploy
        run: |
          echo "Deploying..."

      - name: Set latest commit status as ${{ job.status }}
        uses: myrotvorets/set-commit-status-action@master
        if: always()
        with:
          sha: ${{ steps.comment-branch.outputs.head_sha }}
          token: ${{ secrets.GITHUB_TOKEN }}
          status: ${{ job.status }}
Enter fullscreen mode Exit fullscreen mode

In this updated workflow, we're using the myrotvorets/set-commit-status-action@master action to set the status of the latest comment on the pull request to pending at the beginning of the workflow. Then we move on to do the actual task of our workflow, e.g. setup node, deploy our code, and so on.

After performing the actions required by our workflow, we're using the same action again to set the status of the latest comment on the pull request to the final status of the workflow run, which is indicated by the value of job.status. If any of our actions fails, i.e. an action exits with status code 1, the entire workflow fails.
Note that the if: always() condition ensures that we always set the final status on the latest commit, no matter if the workflow fails or succeeds.

By using this action to set the status of the latest comment on the pull request, we can track the status of the workflow in the context of the pull request and ensure that the pull request is not merged until the workflow has completed successfully.

Add workflow result as a comment

In addition to setting the status of the latest comment on the pull request, you may also want to add a comment to the pull request with the result of the workflow run. This can help you provide additional context to reviewers and collaborators, and ensure that everyone is aware of the status of the pull request.

To add a comment to the pull request, you can use the actions/github-script@v6 action. This action allows you to write JavaScript code that interacts with the GitHub API and perform various operations, including adding a comment to a pull request.

Here's an example of how to use the actions/github-script@v6 action to add a comment to the pull request with the result of the workflow run:

# ...
jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.event.issue.pull_request && contains(github.event.comment.body, '/deploy')
    steps:
      # ... other steps to deploy the code
      - name: Add comment to PR
        uses: actions/github-script@v6
        if: always()
        with:
          script: |
            const name = '${{ github.workflow   }}';
            const url = '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}';
            const success = '${{ job.status }}' === 'success';
            const body = `${name}: ${success ? 'succeeded ✅' : 'failed ❌'}\n${url}`;

            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: body
            })
Enter fullscreen mode Exit fullscreen mode

In this example, we're using the actions/github-script@v6 action to run arbitrary JavaScript code with support for the GitHub API. We're using the github.rest.issues.createComment() function to add a comment to the pull request with the result of the workflow run.

The comment that we're adding includes the name workflow and the status of the workflow run, and a link to the workflow run details. The comment is being added by the github-actions bot, which is the default bot used by GitHub Actions.

Live example

If you'd like to try out the workflow for yourself, I've created a sample repository that you can use to get started. You can find the repository here:

To test the workflow, you can add a comment to this pull request in the repository with the text /deploy. This will trigger the workflow. I set up the workflow to randomly fail or succeed. Once the workflow completes, a comment will be added to the pull request with the result of the workflow run.

Check on PR

Oldest comments (10)

Collapse
 
niklampe profile image
Nik

Nice Writeup! Well done!

Collapse
 
mrkhan profile image
Mark Han

It's incredible how many third party actions it takes to get this functionality. Thanks for the write-up. Hopefully in the near future this will be able to be done with 1st party Github actions. I've been trying to nail this down for weeks

Collapse
 
zirkelc profile image
Chris Cook

Yes, I think so too! The problem is that the issue_comment event references the default instead of the pull request branch. Maybe they will introduce a dedicated pull_request_comment event.

Collapse
 
mrkhan profile image
Mark Han

Exactly! I tried a few ways of working around that, but was just too much. a pull_request_comment event would be awesome.

Collapse
 
rdhar profile image
Rishav Dhar

Totally agreed.

I wanted to design a generic, modular CI/CD pipeline that could be used by anyone configuring Terraform, not just my repository. GitHub's reusable workflow seemed to fit the bill perfectly.

However, getting it to trigger on issue_comment events on top of pull request branches took a lot more tinkering than expected, and still has quirks to workaround such as rendering workflow run status.

Collapse
 
rdhar profile image
Rishav Dhar • Edited

Many thank to you for laying down the groundwork, I've been able to input Terraform commands into PR comments and have them run on triggered workflows for a CLI-like experience via GitHub's UI (DevSecTop/TF-via-PR).

It's still a pain trying to reconcile support of issue_command event trigger compared to pull_request, but at least it's somewhat manageable. Now, I wish it possible to trigger workflows on adding emoji/reactions to PR comments — for example, adding a 🚀 emoji on Terraform's plan output comment could trigger a workflow to Terraform apply.

Collapse
 
ringo_95dd2b5668 profile image
ringo

Do I read correctly that since the if comment condition is in the job, not the workflow, I get a new workflow on each comment but only a few of them (with valid comment body) will trigger? Wouldn't that result in magnitude of "empty" workflows?

Collapse
 
zirkelc profile image
Chris Cook

Yes, that's correct. You can see an example here: github.com/zirkelc/github-actions-...

Collapse
 
emmadonovan profile image
Emma Donovan • Edited

Thanks for sharing, I appreciate you :) Are you a student? then this is for you. Yesterday,  my sister asked me to help her with essay writing because she was not well, but at that time I was also busy with my work. So to make things easy, I searched about it on Google and and found this boomessays.com/ writing service provider website, which writes essays, assignments, and many other things at an affordable price. If you are also in need, you can visit the.

Collapse
 
nikclayton profile image
Nik Clayton

Hi Chris, one update to this.

You have

      - name: Checkout PR branch
        uses: actions/checkout@v3
        with:
          ref: ${{ steps.comment-branch.outputs.head_ref }}
Enter fullscreen mode Exit fullscreen mode

I don't think that works if the PR is coming from a fork of the repository. See e.g,. this workflow run: github.com/pachli/pachli-android/a...

Changing ...head_ref to ...head_sha (github.com/pachli/pachli-android/p...) gets this working on PRs from repository forks.