GitHub App to Add or Remove Labels to Issues

Github app(or a Github bot) is a first-class actor on Github which is used to take redundant work off of repository maintainer’s hands. A first-class actor on Github means that it has the ability to do what the maintainer wants and has programmed the bot to do, given the proper permissions beforehand. The bot works by receiving webhooks of the events fired on Github(a comment asking the bot to remove assignees, add labels, move the issue to another repo), and then triggering appropriate code(the code is event styled, which should be apparent later in the article) in response to it. The triggered code makes the bot do things. One of the works that can be outsourced to the bot is managing labels to issues. In this article, we will use Probot to build a Github app to add or remove labels to issues.
Framework used: Probot
We’ll also use the probot-commands npm module to input the command.

Initial setup of GitHub App

To setup the github app, one can go through the probot’s documentation. As setup is not the focus of this article, we’ll remix a Probot app on Glitch. The link for this setup can be found here.
The README.md in the Glitch remix has a fantastic guide on setting up the app.

To check for the proper app set up, run the default code that got supplied with the app install by making an issue on the repo(presuming the app is installed on the repo).
indexjs-first-code-snippet

Output: The bot(GitHub app) should write a comment like below.
proper-app-setup

If this is not the output, it means that the app is not properly installed and one should consult the docs here.



After the app setup is complete and initial tests are done(to ensure the app is configured properly and working), its time to install the npm modules that we’ll need.

Install dependencies/modules

We’ll need a probot-commands npm module for this app to work. To install them, go to ‘package.json’ file from the navigation pane on the left side. On the top-left corner of the editor, find a button labeled ‘Add Package‘. Using this button, add ‘probot-commands‘ to the app.
After these two modules are added, go to ‘index.js‘ file(using the navigation pane in the left side) and add

const commands = require("probot-commands");

on top of index.js file, like this:
probotcommands module added to indexjs

At this point, we should be good to go to develop the core logic for adding or removing the labels to issues.
The index.js code is here.

Code(from index.js file of the project):

Here, we’ll use the probot-commands module to identify commands from the issue comments. More details about how the commands module works can be found on their GitHub repo. As a short introduction, the structure of a ‘slash command’ is like this:

/keywordToIdentifyCommand arg1 arg2 arg3

//In our app, we'll use the following command structure
/lm [add/remove], label1, label2, label3

command-syntax-structure

issuecomment created code for label addremove logic

Explanation:

Logic:

  1. Listen to the event: a new comment on the issue is created
  2. If the content of the comment contains a ‘slash command’ starting with /lm, execute the following code.
  3. Split the commands on the ‘, ‘ and assign to a new var(labelvals, here). For example, if the slash command is ‘lm add, bug, easy’, we’ll get an array [‘add’, ‘bug’, ‘easy’]
  4. Slice the array obtained to get the values of labels in an array ‘labels’, for example, [‘bug’, ‘easy’]
  5. Check for the ‘add’ or ‘remove’ argument. If ‘add’, then do x, else if ‘remove’, then do y.
  6. If ‘add’, supply the entire array to method ‘addLabels’. Else if ‘remove’, iteratively pass ‘labels’ elements to the method ‘removeLabel’.
    Note: In the remove section, as no method exists to bulk remove the list of labels, we iteratively remove the labels one at a time.
  7. If neither ‘add’ nor ‘remove’ is supplied, create a comment to let people know of an unsuccessful attempt.

The final work is something like this, in action:
final gh interface to demo command work

TIP: It is unwise to let anybody(in terms of user’s permission level) execute such commands. So, it is a good idea to encapsulate the code block in an ‘if’ check to check for permission levels.

filter_none

edit
close

play_arrow

link
brightness_4
code

if ((context.payload.issue.author_association === "OWNER") || 
    (context.payload.issue.author_association === "COLLABORATOR")) 
{
    // commands... code block here
  
}

chevron_right





My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.