# How to extend GitHub and improve your workflow with GitHub Apps

---
title: How to extend GitHub and improve your workflow with GitHub Apps
published: true
description: Learn how to automate your dev and software delivery workflow with GitHub Apps
tags: devops, continuousdeployment, continuousintegration
//cover_image: https://direct_url_to_image.jpg
---

Have you ever wondered if you could extend GitHub to perform specific actions, or use features that reflect your team's workflow? GitHub Apps can do that for you. 

[GitHub Apps](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps) are applications that give you access to GitHub APIs, so that you can build integrations with GitHub, with the benefits of productivity, flexibility and reduced friction in your workflow. They can be installed directly on organizations and user accounts, and granted access to specific repositories. They come with granular permissions and built-in webhooks.

To improve your workflow, you can create a GitHub App that contains multiple scripts or an entire application, and then connect that app to many other tools. For example, you can connect GitHub Apps to GitHub or Slack. For the [Knative project](https://github.com/knative/docs/pulls), we have a GitHub App that manages pull requests. When a PR is created, it checks if the user has accepted the project's CLA and adds a label indicating the status of that check. It does a few more validations before a PR can be merged.

## Building Your First GitHub App

You can create GitHub Apps in different programming languages and register them under your personal account or organization. I'm going to show you how to build a GitHub App in under 5 minutes, using the **Probot** app framework. [Probot](https://probot.github.io/) is a framework for building GitHub Apps in Node.js. It aims to eliminate all the drudgery–like receiving and validating webhooks, and doing authentication handstands–so you can focus on the features you want to build.

The [create-probot-app](https://www.npmjs.com/package/create-probot-app) is the best way to start building a new app. It will generate a new app with everything you need to get started and run your app in production. To get started, open your command line application and run the following command:

```shell
npx create-probot-app my-github-app
```

You will be asked a series of questions. Answer them as you so choose, but for the question `Which template would you like to use?`, choose _basic-js_ (you're free to choose _basic-ts_ if you want to). The necessary files and packages will be downloaded and installed. The list below describes some of the important files in the project:

1. **index.js**: This is the entry point into the application.
2. **app.yml**: This is the GitHub App Manifest used when initializing the app.
3. **Dockerfile**: A Dockerfile that can be used to containerize and deploy the app.

The default event enabled for the app when it is bootstrapped is only the `issues` event. You will later write code to check for comments in issues. For that, you'll need to enable the `issue_comment` event. Open **app.yaml**, go to line 25 and uncomment it. The `default_events` section of the manifest should look like what you see below.

```YAML
default_events:
  # - check_run
  # - check_suite
  # - commit_comment
  # - create
  # - delete
  # - deployment
  # - deployment_status
  # - fork
  # - gollum
  - issue_comment
  - issues
```

Let's inspect the index.js file. The code below is the content of the file.

```javascript
/**
 * This is the main entrypoint to your Probot app
 * @param {import('probot').Probot} app
 */
module.exports = (app) => {
  app.log.info("Yay, the app was loaded!");

  app.on("issues.opened", async (context) => {
    const issueComment = context.issue({
      body: "Thanks for opening this issue!",
    });
    return context.octokit.issues.createComment(issueComment);
  });
};
```

The `app` parameter is an instance of _Probot_ and gives you access to all of the GitHub goodness. `app.on` is used to subscribe to events triggered by GitHub. You have to specify the name of the event and a function to handle the event. 

The `context` passed to the event handler includes everything about the event that was triggered, as well as some helpful properties for doing something useful in response to the event. `context.octokit` is an authenticated GitHub client that can be used to make REST API and GraphQL calls to GitHub, and it allows you to do almost anything programmatically that you can do through a web browser on GitHub. 

In the sample code, `context.octokit` is used to create an issue comment. The `app` and `context` objects both have a `log` object that can be used to log information to the standard output stream.

### Registering the GitHub App

With the application code ready, you can now register it on GitHub. Follow the instructions below to do so.

1. Run the app by running `npm start` in your terminal.
2. Go to http://localhost:3000 in your browser.
3. You should see a web page with buttons to register the app or use an existing one. Go ahead and click the **Register a GitHub App** button.
4. Next, you'll get to decide on an app name that isn't already taken. Note: If you see a message _"Name is already in use"_ although no such app exists, it means that a GitHub organization with that name exists and cannot be used as an app name.
5. After registering your GitHub App, you'll be redirected to install the app on any repositories of your choosing repositories. Select a repository to try it on. You can also check your local **.env** and notice it will be populated with values GitHub sent back in the course of that redirect.
6. Restart the server in your terminal (press `CTRL/CMD + C` to stop the server).

Now that the app is registered and installed in a repository, go to the issues page of the repository and open a new issue. You should notice the GitHub App leave a comment when a new issue is created.

![GitHub App new issue: pmbanugo commented “My first app,” and telerik-github-app bot replied, “Thanks for opening this issue!”](new-issue.PNG "GitHub App new issue")

## Extend the App With probot-commands

Probot doesn't have any official extensions API, but there are some reusable utilities that have been extracted from existing apps. One of these utilities is called [probot-commands](http://github.com/probot/commands). It is an extension that adds slash commands to GitHub. Slash commands are lines that start with `/` in comments on Issues or Pull Requests that allow users to interact directly with your app. We will use it to add labels to issues so that we can filter issues by either `bug` or `feature` labels.

To use this utility, open the terminal and run `npm install --save probot-commands`. Afterward, open index.js and add the code statement below.

```javascript
commands(app, "kind", (context, command) => {
  const labels = command.arguments.split(/, */);
  return context.octokit.issues.addLabels(context.issue({ labels }));
});
```

The code gets the value passed from GitHub and uses it to add labels by calling `context.octokit.issues.addLabels(context.issue({ labels }))`.

Let's try out the new changes. Restart the server and add a comment that begins with `/kind` to the issue you opened in the previous section of this post. For example, enter `/kind bug` as a new comment to the issue.

![To demonstrate a slash command, pmbanugo commented, “/kind feature,” and the telerik-github-app bot added the `feature` label.](slash-command.PNG "slash command")

## Deploying the App

So far you've been running the app locally. You can deploy it to any cloud provider and run it as a Node.js application. The Docker file included can be used to package and deploy it as a containerized app. I'm going to use DigitalOcean App platform as the hosting provider. You can find more details about other hosting options in the [documentation](https://probot.github.io/docs/deployment/#deploy-the-app).

To get started, commit your changes to Git and create a GitHub (or GitLab) repository, then push your changes there.

If you have a DigitalOcean account, log in and go to the _Apps_ [page](https://cloud.digitalocean.com/apps). If you don't have an account, you can [create one using my referral link](https://m.do.co/c/257c8259d8ef), which gives you $100 to try out different things on DigitalOcean (and [I’ll get $25 credit](https://www.digitalocean.com/referral-program/) if you become an active user and spend $25). After creating a new account, go to the Apps [page](https://cloud.digitalocean.com/apps) and click **Launch Your App** button. You will be redirected to a page where you will specify the source for the application. Choose **GitHub** (or GitLab if that's what you use).

You will be redirected to GitHub to authorize and install the DigitalOcean GitHub App (yes, they use GitHub App as well!). Select the user or organization and repositories to give it access to. You can choose to authorize it only for the repository you want to deploy. After the installation and authorization, you will be redirected back to DigitalOcean. Select **GitHub** and choose the repository you want to deploy from the dropdown and select a branch. Then click the **Next** button to proceed.

You will be redirected to a page to configure the app. Click **Edit** beside the _Environment Variables_ to add some environment variables. You need 3 environment variables:

1. **APP_ID**: the ID of the app, which you can get from the app settings page.
2. **WEBHOOK_SECRET**: the Webhook Secret that you generated when you created the app.
3.  And one of the following:

- **PRIVATE_KEY**: the contents of the private key you downloaded after creating the app, OR...
- **PRIVATE_KEY_PATH**: the path to a private key file. _PRIVATE_KEY_ takes precedence over _PRIVATE_KEY_PATH_.

Copy these values from the **.env** file in your project folder (Note: this was generated when you registered the App on GitHub) and click **Next**.

Choose a name and region for the application and click **Next**. You will be redirected to the final page where you need to choose a plan to run the application. For prototype purposes, use the _Basic_ plan and a _container size_ that cost $5/month. Scroll to the bottom of the page and click the **Launch App** button.

It'll take a while for the application to be built. When it's done, you will get a domain that you can then use for the GitHub App. Go to the [GitHub Apps](https://github.com/settings/apps) settings page and click the **Edit** button to update the App. Scroll down to the **Webhook** section and change the _Webhook URL_ to the new domain from DigitalOcean. Click the **Save changes** button to save the changes.

With the app deployed on DigitalOcean and the Webhook URL updated, every new event will be sent to the new URL.

![my-github-app has the URL my-github-app-ewqgo.ondigitalocean.app. We’re looking at its overview page on the DigitalOcean App platform](/deployed-app.png "The deployed app")

## What's Next?

You learned how to automate your workflow and integrate with GitHub using GitHub Apps. It is the officially recommended way to integrate with GitHub because they offer much more granular permissions to access data. GitHub Apps can be installed directly on organizations and user accounts and granted access to specific repositories. You saw how to use Probot to build a Node.js GitHub App, and how to deploy the app to the cloud.

The app you registered by following the instructions in this post is public but it's not discoverable by other GitHub users. You can also share or sell apps in [GitHub Marketplace](https://github.com/marketplace). To learn how to list an app on GitHub Marketplace, see the GitHub documentation "[Getting started with GitHub Marketplace](https://docs.github.com/en/marketplace/getting-started)."

If you need your App to do more things than the permissions enabled when the App was registered, you can add more permissions through the GitHub App settings page. For more details, see "[Editing a GitHub App's permissions](https://docs.github.com/en/apps/managing-github-apps/editing-a-github-app-s-permissions).".

You can get the source code for the sample application on [GitHub](https://github.com/pmbanugo/my-github-app). 

> If you want to see more ways to build GitHub Apps, check out my upcoming [book about building a serverless app platform](https://books.pmbanugo.me/serverless-app-platform) by integrating GitHub, Next.js, Kubernetes and other Cloud Native tools to build a serverless platform

Originally published on [Telerik blog](https://www.telerik.com/blogs)


