loading...

GitHub API Authentication - GitHub Actions

gr2m profile image Gregor Martynus Updated on ・3 min read

In this post, I will explain how to create a GitHub Action workflow that adds a comment to every new pull request using

  1. A GitHub Action workflow file (.github/workflows/pr-comment.yml)
  2. A single JavaScript file (.github/actions/pr-comment.js)

Both files live in the same repository where the comments will be added. If you get stuck at any point, here is my repository with all the code described in this post.

Prerequisites

  1. Install git and Node.js
  2. Create a repository on GitHub
  3. Clone the repository to your local machine.

Passing the GITHUB_TOKEN secret to a JavaScript file

GitHub Actions come with their own special token that must be passed to each workflow step explicitly: secrets.GITHUB_TOKEN. Unlike Personal Access Tokens that I explained in the previous post of this series, you don't have to manually create them. A unique GITHUB_TOKEN is created each time your GitHub Action is run.

Let's start out by creating a new workflow file at .github/workflows/pr-comment.yml

name: PR Comment
on:
  # Run this workflow only when a new pull request is opened
  # compare: https://git.io/JvTyV
  pull_request:
    types: [opened]

jobs:
  pr_comment:
    runs-on: ubuntu-latest

    steps:
      # Make files accessible to actions
      # https://github.com/actions/checkout#readme
      - uses: actions/checkout@v2
      # Install Node
      # https://github.com/actions/setup-node#readme
      - uses: actions/setup-node@v1
        with:
          node-version: 12
      # Install dependencies
      - run: npm ci
      # Run pr-comment.js with Node and pass the authentication token 
      - run: node .github/actions/pr-comment.js
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Next, we need to create a package.json file and install a few dependencies, and create the .github/actions/pr-comment.js.

Creating a comment using JavaScript

We will use GitHub's Create a comment REST API endpoint to create the comment on every new pull request. A GraphQL query would work just the same, using octokit.graphql instead of octokit.request.

Create a package.json file in the folder you cloned your repository into:

npm init

After that, install @octokit/action

npm install @octokit/action

Next, create the .github/actions/pr-comment.js file

// GITHUB_EVENT_PATH always exists when run by an Action,
// see https://git.io/JvUf7 for a full list
const eventPayload = require(process.env.GITHUB_EVENT_PATH);
const { Octokit } = require("@octokit/action");

createPrComment();

async function createPrComment() {
  // No need to pass process.env.GITHUB_TOKEN, `@octokit/action`
  // is using it directly and throws an error if it is not present.
  const octokit = new Octokit();

  // See https://developer.github.com/v3/issues/comments/#create-a-comment
  const { data } = await octokit.request(
    "POST /repos/:repository/issues/:pr_number/comments",
    {
      repository: process.env.GITHUB_REPOSITORY,
      pr_number: eventPayload.pull_request.number,
      body: "Thank you for your pull request!"
    }
  );

  console.log("Comment created: %d", data.html_url);
}

Commit and push your changes

git add .
git commit -m 'add GitHub Action workflow to comment on new PRs'
git push origin master

Now create a new pull request on your repository. After a short delay, the Action will show up in the list of checks as pending

Screenshot of new pull request

If all goes as expected, the action will add the new comment

Screenshot of new comment

Congratulations 👏 Now that you know how to send authenticated requests against GitHub's APIs with Actions and JavaScript, sky is the limit 🚀

With great power comes great responsibility

Secrets and pull requests from forks

Creating the comment will not work when someone creates a pull request from a fork. The GITHUB_TOKEN secret is still passed, but has only read permissions, it cannot create or update anything. If that was not the case, anyone could create a pull request changing the code of the pr-comment.js script to do something malicious with your repository.

For now, I you can prevent the action from running altogether if the pull request comes from a fork by adding an if statement

# ...

jobs:
  pr_comment:
    runs-on: ubuntu-latest
    if: eventPayload.pull_request.head.repo.fork == false
    steps:
      # ...

Another alternative is to use GitHub Apps instead, which I will cover in my next blog post 😇

Posted on by:

gr2m profile

Gregor Martynus

@gr2m

Father of triplets Nico, Ada & Kian. Web developer with 20+ yrs experience. JavaScript Octokit Maintainer for GitHub. He/him

Discussion

markdown guide