How to Build GitHub Apps For Fun and Profit
Tags: javascript, github, devops
Published: 2021-04-06 00:32:42

Hi there, GitHub developer! So you host your code on GitHub, and you've seen some comments like this:

![dependabot](https://user-images.githubusercontent.com/2993937/113446246-6d81de00-93c5-11eb-9e4e-80a5f687f869.png)

Dependabot and thousands of bots like it are what are called [GitHub Apps](https://docs.github.com/en/developers/apps/about-apps#about-github-apps). Today, I'll teach you how to make a GitHub App and how to list it for purchase in GitHub Marketplace. GitHub Apps have been around for several years but are worth another look as the GitHub Platform expands and improves.

## About GitHub Apps

GitHub Apps are a great way to programmatically interact with GitHub:
* Flexible, first class actors on GitHub
* Secure, fine-grained permissions model
* Scalable, dedicated rate limits
* Built-in webhooks

You might need a GitHub App for:
* *Integrating* with GitHub, potentially via the [GitHub Technology Partner Program](https://partner.github.com/technology-partners). Your software product can connect, augment, and inspire developers right where they work in GitHub, the [largest and most advanced development platform in the world](https://github.com/home).
* *Interacting* with GitHub on a programmatic basis, for example, from team-based tools or CLI-driven workflows

GitHub Apps replace [OAuth apps](https://docs.github.com/en/developers/apps/migrating-oauth-apps-to-github-apps#reasons-for-switching-to-github-apps), are used to build [GitHub Actions](https://docs.github.com/en/actions), and work on GitHub.com and [GitHub Enterprise](https://github.com/enterprise) alike. Some APIs are exclusive to GitHub Apps – for example, [Checks](https://docs.github.com/en/rest/reference/checks) and [Content Attachments](https://docs.github.com/en/developers/apps/using-content-attachments).

A GitHub App can be programmed to act [as itself](https://docs.github.com/en/developers/apps/authenticating-with-github-apps#authenticating-as-a-github-app), [as a (scoped) "installation"](https://docs.github.com/en/developers/apps/authenticating-with-github-apps#authenticating-as-an-installation), or [as one of its users](https://docs.github.com/en/developers/apps/identifying-and-authorizing-users-for-github-apps), if permitted.

Also, [GitHub Apps fit together with GitHub Actions](https://docs.github.com/en/actions/creating-actions/about-actions#comparing-github-actions-to-github-apps) like peanut butter and jelly, which is rad. So let's build one! Today, I'll build the **simplest thing possible**, a bot that approves a pull request if "🤖" is in the title.

What will **you** build 👀?

## Probot, the helper framework

Know JavaScript? Great. Probot is a trusty Node.js framework for building GitHub Apps, and we'll use it to make the following steps easier:
1. **Create the App** by registering a set of permissions, webhook events, and metadata
2. **Install the App** on as few or as many repositories as you want
3. **Use the App** to make GitHub API requests

### Create the App

In a terminal with Node.js installed, type `npx create-probot-app pr-bot` and follow the prompts, choosing `basic-js` as the template. `cd pr-bot` when the installation is done.

Open up `app.yml` in your favorite text editor. This is a one-time use creation spec or "manifest" – of course, App settings can be changed later at https://github.com/settings/apps. 

Uncomment `default_events.pull_request` and change `default_permissions.pull_requests` to `write`. When you're done it should look like this:
```yaml
default_events:
  - pull_request
default_permissions:
  metadata: read
  pull_requests: write
description: A silly pull request bot!
public: true
```

Now add the logic of the App in `index.js`. Add this block just below the line, `app.log.info("Yay, the app was loaded!")`:

```js
app.on(
  ["pull_request.opened", "pull_request.edited", "pull_request.reopened"],
  async (context) => {

    if (context.payload.pull_request.title.indexOf('🤖') > -1) {
      await context.octokit.pulls.createReview({
        ...context.pullRequest(),
        event: 'APPROVE'
      })
    }
  }
);
```

`context.octokit` gives us access to an authenticated [octokit/rest.js client](https://octokit.github.io/rest.js/v18/) to make GitHub API calls with ease. (Psst: check out the other official and 3rd party [Octokit libraries](https://docs.github.com/en/rest/overview/libraries), even if you aren't using Probot!)
 
Back in your terminal, run `npm run start` and then click "Register GitHub App" at `http://localhost:3000`:

![create the app](https://user-images.githubusercontent.com/2993937/113418759-17487700-9394-11eb-9fa1-0563f001572f.png)

Follow the prompts to finish creating the app. Notice that an `.env` file has appeared with some secret data only you as App developer have, namely the `APP_ID`, `PRIVATE_KEY`, and `WEBHOOK_SECRET`.

### Install the App

Follow the prompts to install the app on all or select repositories. This lets the App "see and respond" to the resources you configured before (`pull_requests`), but in only these repositories.

### Use the App

In one of these repositories, open a pull request. The `pull_request` webhook was received, but no "🤖" was in the title, so `pr-bot` stayed quiet! Now add a "🤖" in the title and notice the approval!

![use the app](https://user-images.githubusercontent.com/2993937/113420930-31845400-9398-11eb-89a2-5d0032410d13.gif)

But you're not going to use your own machine for long 😉. Probot apps are just Node.js apps, so they can be [deployed](https://probot.github.io/docs/deployment/) to all the environments you'd expect.

## No Probot, no problem

So far we've used Probot as a helper framework to [create](https://docs.github.com/en/developers/apps/creating-a-github-app), [install](https://docs.github.com/en/developers/apps/installing-github-apps), and [use](https://docs.github.com/en/rest) the app to extend our experience on GitHub! Did you know you can easily follow this pattern even without Probot?

### Create the App
Head over to https://github.com/settings/apps/new and fill out the fields, with [Creating a GitHub App - GitHub Docs](https://docs.github.com/en/developers/apps/creating-a-github-app) as your guide. Now you can appreciate the complexity that Probot solves by utilizing the [app manifest flow](https://docs.github.com/en/developers/apps/creating-a-github-app-from-a-manifest) behind the scenes.

![create the app manually](https://user-images.githubusercontent.com/2993937/113431040-2554c280-93a9-11eb-83e8-cd321bc7e9a6.png)

### Install the App

Visit your App's page at https://github.com/apps/yourappname to start an installation process as before.

### Use the App

Now you should have a [private key](https://docs.github.com/en/developers/apps/authenticating-with-github-apps#generating-a-private-key), App ID (found at the top of your app settings page, https://github.com/settings/apps/yourappname), and Installation ID (via API or in post-install URL like https://github.com/settings/installations/1234567). You can use these to form API requests, either [manually](https://docs.github.com/en/developers/apps/authenticating-with-github-apps), via one of the [Octokit libraries](https://docs.github.com/en/rest/overview/libraries), or even [as an action](https://github.com/marketplace?type=actions&query=github+app+token).

Check out this video for a walkthrough example using Go on GitHub Enterprise Server:

[YouTube](https://www.youtube.com/watch?v=iaBEWB1As0k)

## Listing in GitHub Marketplace

[GitHub Marketplace](https://github.com/marketplace) is a one stop shop for [sharing your app with the GitHub community](https://docs.github.com/en/developers/github-marketplace/github-marketplace-overview) and even allowing developers to pay you for it. See [Requirements for listing an app - GitHub Docs](https://docs.github.com/en/developers/github-marketplace/requirements-for-listing-an-app) for instructions!

## Wrapping up

Today, we **created, installed, and used** a simple GitHub App and highlighted some great features about GitHub Apps:
* Flexible, powerful integration model to build rich experiences and programmatic access to GitHub
* Can be discovered, purchased, and sold on GitHub Marketplace
* Fully backed by GitHub and extensively used by integrators and developers

Happy developing! See you around!

## Additional resources:
* https://github.com/github-developer/github-apps-cheat-sheet
* https://docs.github.com/en/rest/overview/libraries
* https://probot.github.io/
* https://docs.github.com/en/developers/apps