6.1 KiB
Contributing
Running Locally
- Clone the repository with
git clone https://github.com/bkeepers/PRobot.git
- Make sure you have a recent version of Node.js installed
- Run
$ script/bootstrap
to install all the project dependencies - Install ngrok (
$ brew cask install ngrok
on a mac), which will expose the local server to the internet so GitHub can send webhooks - Run
$ script/tunnel
to start ngrok, which should output something likeForwarding https://4397efc6.ngrok.io -> localhost:3000
- Register an integration on GitHub with:
- Homepage URL, Callback URL, and Webhook URL: The full ngrok url above. For example:
https://4397efc6.ngrok.io/
- Secret:
development
- Permissions & events needed will depend on how you use the bot, but for development it may be easiest to enable everything.
- Download the private key and move it to
private-key.pem
in the project directory - Edit
.env
and fill in all the environment variables - With
ngrok
still running, open another terminal and run$ script/server
to start the server on http://localhost:3000
Whenever you com back to work on the app after you've already had it running once, then you need to:
- Run
$ script/server
- Run
$ script/tunnel
in another window ngrok
will use a different URL every time it is restarted, so you will have to go into the settings for your Integration and update all the URLs.
Testing
To test with a real GitHub repository, you'll need to create a test repository and install the integration you created above:
- Open up the settings for your installation and click "Install"
- Create a
.probot.js
in your repository with: on("issues.opened").comment("Hello World! Your bot is working!"); - Open a new issue. Your bot should post a comment (you may need to refresh to see it).
Debugging
- Always run
$ script/bootstrap
and restart the server if package.json has changed. - To turn on verbose logging, start server by running:
$ LOG_LEVEL=debug script/server
- To see what requests are going out, start the server by running:
$ LOG_LEVEL=trace script/server
Adding an action
TODO: This is out of date and will be updated after plugin API is settled.
Actions are called when a webhook is delivered and any conditions are met. For example, this configuration in .probot
calls two actions when a new issue is opened:
on issues.opened
then
label("triage") # <-- `label` is an action
and close # <-- and so is `close`
;
These actions are defined in lib/actions/label.js
and lib/actions/close.js
.
Implementing new actions is relatively straight forward. Create a file in lib/actions/{name}.js
, replacing name
with the name of the action, and add the new action in lib/actions.js
. An action is a function that takes two arguments and returns a Promise
:
module.exports = function (context, args) {
return Promise.resolve('This action is a no-op');
};
The two arguments are:
- The aptly named
context
argument provides context for the current webhook. There are two properties that will likely be most helpful:context.github
is an authenticated instance of the GitHub API client. See the node-github documentation for more information.context.payload
is the webhook payload. Depending on the type of event, the payload will be slightly different. See the GitHub webhook docs for more information.
args
is any arguments passed to the action. For thelabel
action called in the example above,args
will be the string"triage"
.
Actions must return a Promise
that gets resolved when the action completes. Fortunately, the GitHub API client available in context.github
returns promises, so you can usually just return the API call. For example, here is the full implementation of the react
action:
module.exports = function (context, react) {
return context.github.reactions.createForIssue(
context.payload.toIssue({content: react})
);
};
Note that context.payload.toIssue()
will extract the owner
, repo
, and number
params from the issues
or pull_request
events.
That's it! You now have everything you need to implement an action. If you're looking for ideas of new actions to add, check out this tracking issue for unimplemented GitHub actions.
Adding a condition
TODO: This is out of date and will be updated after plugin API is settled.
Conditions are called when a webhook is delivered and are used to determine if the actions should be called. For example, this configuration in .probot
checks if an issue or pull request has a label before closing it:
on issues.labeled or pull_request.labeled
if labeled("wontfix") # <-- `labeled` is a condition
then close;
This condition is defined in lib/conditions/labeled.js
.
Like adding an action, adding a new condition is straight forward. Create a file in lib/conditions/{name}.js
, replacing name
with the name of the condition, and add the new condition in lib/conditions.js
. A condition is a function that takes two arguments and returns true
or false
:
module.exports = function (context, args) {
return context.payload.sender.login === "bkeepers";
};
Check out docs for adding an action for more information on the two arguments.
And that's it! You now have everything you need to add a condition.