Trigger GitHub Workflow for Comments on Pull Request
Tags: github, githubactions, devops, productivity
Published: 2023-02-20 13:00:00

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:

```yml
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..."
```

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.

```yml
#...

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..."
```

## 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.

```yml
#...

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 }}
```

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:

```yml
# ...
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
            })
```

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](https://github.com/zirkelc/github-actions-workflows) 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](https://github.com/zirkelc/github-actions-workflows/pull/2) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9ty9wpwrl3vcixmbpg5.jpg)