forked from mirrors/probot
commit
7dfd119664
|
@ -1,37 +0,0 @@
|
||||||
# Contributing
|
|
||||||
|
|
||||||
## Running Locally
|
|
||||||
|
|
||||||
0. Clone the repository with `git clone https://github.com/bkeepers/PRobot.git`
|
|
||||||
0. Make sure you have a recent version of [Node.js](https://nodejs.org/) installed
|
|
||||||
0. Run `$ script/bootstrap` to install all the project dependencies
|
|
||||||
0. Install [ngrok](https://ngrok.com/download) (`$ brew cask install ngrok` on a mac), which will expose the local server to the internet so GitHub can send webhooks
|
|
||||||
0. Run `$ script/tunnel` to start ngrok, which should output something like `Forwarding https://4397efc6.ngrok.io -> localhost:3000`
|
|
||||||
0. [Register an integration](https://developer.github.com/early-access/integrations/creating-an-integration/) on GitHub with:
|
|
||||||
- **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.
|
|
||||||
0. Download the private key and move it to `private-key.pem` in the project directory
|
|
||||||
0. Edit `.env` and fill in all the environment variables
|
|
||||||
0. 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:
|
|
||||||
|
|
||||||
0. Run `$ script/server`
|
|
||||||
0. Run `$ script/tunnel` in another window
|
|
||||||
0. `ngrok` will use a different URL every time it is restarted, so you will have to go into the [settings for your Integration](https://github.com/settings/installations) 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:
|
|
||||||
|
|
||||||
0. Open up the settings for your installation and click "Install"
|
|
||||||
0. Create a `.probot.js` in your repository with:
|
|
||||||
on("issues.opened").comment("Hello World! Your bot is working!");
|
|
||||||
0. Open a new issue. Your bot should post a comment (you may need to refresh to see it).
|
|
||||||
|
|
||||||
## Debugging
|
|
||||||
|
|
||||||
0. Always run `$ script/bootstrap` and restart the server if package.json has changed.
|
|
||||||
0. To turn on verbose logging, start server by running: `$ LOG_LEVEL=debug script/server`
|
|
||||||
0. To see what requests are going out, start the server by running: `$ LOG_LEVEL=trace script/server`
|
|
19
README.md
19
README.md
|
@ -8,19 +8,18 @@ If you've ever thought, "wouldn't it be cool if GitHub could…"; imma stop you
|
||||||
>
|
>
|
||||||
> –Documentation on [GitHub Integrations](https://developer.github.com/early-access/integrations/)
|
> –Documentation on [GitHub Integrations](https://developer.github.com/early-access/integrations/)
|
||||||
|
|
||||||
Some companies provide [hosted integrations](https://github.com/integrations) that you can install, but there's also a bunch of really cool things you can build yourself, and Probot aims to make that easy.
|
There are some great services that offer [hosted integrations](https://github.com/integrations), but you can build a bunch of really cool things yourself. Probot aims to make that easy.
|
||||||
|
|
||||||
Here are a few examples of things you can build:
|
## Plugins
|
||||||
|
|
||||||
- [autoresponder](https://github.com/probot/autoresponder) replies to opened issues with the contents of `.github/ISSUE_REPLY_TEMPLATE.md`
|
Bots are implemented as plugins, which are easy to write, deploy, and share. Here are just a few examples of things probot can do:
|
||||||
- [stale](https://github.com/probot/stale) closes abandoned issues after a period of inactivity.
|
|
||||||
|
|
||||||
Browse all [probot plugins](https://github.com/search?q=topic%3Aprobot-plugin+org%3Aprobot&type=Repositories).
|
- [stale](https://github.com/probot/stale) - closes abandoned issues after a period of inactivity.
|
||||||
|
- [owners](https://github.com/probot/owners) - @mentions people in Pull Requests based on contents of the OWNERS file
|
||||||
|
- [configurer](https://github.com/probot/configurer) - syncs repository settings defined in `.github/config.yml` to GitHub, enabling Pull Requests for repository settings.
|
||||||
|
|
||||||
|
Check out [all probot plugins](https://github.com/search?q=topic%3Aprobot-plugin&type=Repositories).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Most of the interesting things are built with [plugins](docs/plugins.md), so consider starting by writing a new plugin or improving one of the [existing ones](https://github.com/search?q=topic%3Aprobot-plugin+org%3Aprobot&type=Repositories).
|
Most of the interesting things are built with plugins, so consider starting by [writing a new plugin](docs/plugins.md) or improving one of the [existing ones](https://github.com/search?q=topic%3Aprobot-plugin&type=Repositories).
|
||||||
|
|
||||||
See [CONTRIBUTING.md](CONTRIBUTING.md) for other ways to contribute.
|
|
||||||
|
|
||||||
[![Join the chat at https://gitter.im/bkeepers/PRobot](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bkeepers/PRobot?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
# API
|
||||||
|
|
||||||
|
This is the official probot API. Anything not documented here is subject to change without notice.
|
||||||
|
|
||||||
|
## Robot
|
||||||
|
|
||||||
|
The `robot` parameter available to plugins is an instance of [`Robot`](/lib/robot.js).
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = robot => {
|
||||||
|
// your code here
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### on
|
||||||
|
|
||||||
|
`robot.on` will listen for any GitHub [GitHub webhooks](https://developer.github.com/webhooks/), which are fired for almost every significant action that users take on GitHub. The `on` method takes a callback, which will be invoked with two arguments when GitHub delivers a webhook:
|
||||||
|
|
||||||
|
- `event` - the event that was triggered, including `event.payload` which has the payload from GitHub.
|
||||||
|
- [`context`](#context) - helpers for extracting information from the event, which can be passed to GitHub API calls
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = robot => {
|
||||||
|
robot.on('push', (event, context) => {
|
||||||
|
// Code was pushed to the repo, what should we do with it?
|
||||||
|
robot.log(event);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Most events also include an "action". For example, the [`issues`](https://developer.github.com/v3/activity/events/types/#issuesevent) event has actions of `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `milestoned`, `demilestoned`, `closed`, and `reopened`. Often, your bot will only care about one type of action, so you can append it to the event name with a `.`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = robot => {
|
||||||
|
robot.on('issues.opened', event => {
|
||||||
|
// An issue was just opened.
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### auth
|
||||||
|
|
||||||
|
`robot.auth(id)` will return an authenticated GitHub client that can be used to make API calls. It takes the ID of the installation, which can be extracted from an event:
|
||||||
|
|
||||||
|
```js
|
||||||
|
module.exports = function(robot) {
|
||||||
|
robot.on('issues.opened', async (event, context) => {
|
||||||
|
const github = await robot.auth(event.payload.installation.id);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: `robot.auth` is asynchronous, so it needs to be prefixed with a [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) to wait for the magic to happen.
|
||||||
|
|
||||||
|
The `github` object returned from authenticating is an instance of the [github Node.js module](https://github.com/mikedeboer/node-github), which wraps the [GitHub API](https://developer.github.com/v3/) and allows you to do almost anything programmatically that you can do through a web browser.
|
||||||
|
|
||||||
|
### log
|
||||||
|
|
||||||
|
`robot.log` is a logger backed by [bunyan](https://github.com/trentm/node-bunyan).
|
||||||
|
|
||||||
|
```js
|
||||||
|
robot.log("This is a debug message");
|
||||||
|
robot.log.debug("…so is this");
|
||||||
|
robot.log.trace("Now we're talking");
|
||||||
|
robot.log.info("I thought you should know…");
|
||||||
|
robot.log.warn("Woah there");
|
||||||
|
robot.log.error("ETOOMANYLOGS");
|
||||||
|
robot.log.fatal("Goodbye, cruel world!");
|
||||||
|
```
|
||||||
|
|
||||||
|
The default log level is `debug`, but you can change it by setting the `LOG_LEVEL` environment variable to `trace`, `info`, `warn`, `error`, or `fatal`.
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
[Context](/lib/context.js) has helpers for extracting information from the webhook event, which can be passed to GitHub API calls.
|
||||||
|
|
||||||
|
### `repo`
|
||||||
|
|
||||||
|
Return the `owner` and `repo` params for making API requests against a repository. The object passed in will be merged with the repo params.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const params = context.repo({path: '.github/stale.yml'})
|
||||||
|
// Returns: {owner: 'username', repo: 'reponame', path: '.github/stale.yml'}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `issue`
|
||||||
|
|
||||||
|
Return the `owner`, `repo`, and `number` params for making API requests against an issue or pull request. The object passed in will be merged with the repo params.
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
const params = context.issue({body: 'Hello World!'})
|
||||||
|
// Returns: {owner: 'username', repo: 'reponame', number: 123, body: 'Hello World!'}
|
||||||
|
```
|
||||||
|
|
||||||
|
### isBot
|
||||||
|
|
||||||
|
Returns a boolean if the actor on the event was a bot.
|
|
@ -1,10 +1,12 @@
|
||||||
# Deployment
|
## Deploy
|
||||||
|
|
||||||
Every plugin can either be deployed as a stand-alone bot, or combined with other plugins.
|
Every plugin can either be deployed as a stand-alone bot, or combined with other plugins in one deployment.
|
||||||
|
|
||||||
|
> **Heads up!** Note that most [plugins in the @probot organization](https://github.com/search?q=topic%3Aprobot-plugin+org%3Aprobot&type=Repositories) have an official hosted integration that you can use for your open source project. Use the hosted instance if you don't want to deploy your own.
|
||||||
|
|
||||||
## Combining plugins
|
## Combining plugins
|
||||||
|
|
||||||
To deploy a bot that includes multiple plugins, create a new app that has them both listed as dependencies in `package.json`:
|
To deploy a bot that includes multiple plugins, create a new app that has the plugins listed as dependencies in `package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -26,9 +28,6 @@ To deploy a bot that includes multiple plugins, create a new app that has them b
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying to Heroku
|
## Heroku
|
||||||
|
|
||||||
0. [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) - Click this button and pick an **App Name** that Heroku is happy with, like `your-name-probot`. Before you can complete this, you'll need config variables from the next step.
|
TODO: Generic docs for deploying a plugin to Heroku
|
||||||
0. In another tab, [create an integration](https://developer.github.com/early-access/integrations/creating-an-integration/) on GitHub, using `https://your-app-name.herokuapp.com/` as the **Homepage URL**, **Callback URL**, and **Webhook URL**. The permissions and events that your bot needs access to will depend on what you use it for.
|
|
||||||
0. After creating your GitHub integration, go back to the Heroku tab and fill in the configuration variables with the values for the GitHub Integration
|
|
||||||
0. Create a `.probot.yml` file in your repository. See [Configuring](#configuring).
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Development
|
||||||
|
|
||||||
|
To run a plugin locally, you'll need to create a GitHub Integration and configure it to deliver webhooks to your local machine.
|
||||||
|
|
||||||
|
1. Make sure you have a recent version of [Node.js](https://nodejs.org/) installed
|
||||||
|
1. Install [ngrok](https://ngrok.com/download) (`$ brew cask install ngrok` on a mac), which will expose the local server to the internet so GitHub can send webhooks
|
||||||
|
1. Run `$ ngrok http 3000` to start ngrok, which should output something like `Forwarding https://4397efc6.ngrok.io -> localhost:3000`
|
||||||
|
1. [Create a new GitHub Integration](https://github.com/settings/integrations/new) with:
|
||||||
|
- **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.
|
||||||
|
1. Download the private key and move it to `private-key.pem` in the project directory
|
||||||
|
1. Edit `.env` and set `INTEGRATION_ID` to the ID of the integration you just created.
|
||||||
|
1. With `ngrok` still running, open another terminal and run `$ npm start` to start the server on http://localhost:3000
|
||||||
|
|
||||||
|
You'll need to create a test repository and install your Integration by clicking the "Install" button on the settings page.
|
||||||
|
|
||||||
|
Whenever you com back to work on the app after you've already had it running once, then you need to:
|
||||||
|
|
||||||
|
1. Run `$ npm start`
|
||||||
|
1. Run `$ ngrok http 3000` in another terminal window
|
||||||
|
1. `ngrok` will use a different URL every time it is restarted, so you will have to go into the [settings for your Integration](https://github.com/settings/integrations) and update all the URLs.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
1. Always run `$ npm install` and restart the server if package.json has changed.
|
||||||
|
1. To turn on verbose logging, start server by running: `$ LOG_LEVEL=trace npm start`
|
|
@ -1,6 +1,6 @@
|
||||||
## Plugins
|
# Plugins
|
||||||
|
|
||||||
A plugin is just a [node module](https://nodejs.org/api/modules.html) that exports a function:
|
A plugin is just a [Node.js module](https://nodejs.org/api/modules.html) that exports a function:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = robot => {
|
module.exports = robot => {
|
||||||
|
@ -10,7 +10,7 @@ module.exports = robot => {
|
||||||
|
|
||||||
The `robot` parameter is an instance of [`Robot`](/lib/robot.js) and gives you access to all of the bot goodness.
|
The `robot` parameter is an instance of [`Robot`](/lib/robot.js) and gives you access to all of the bot goodness.
|
||||||
|
|
||||||
### Receiving GitHub webhooks
|
## Receiving GitHub webhooks
|
||||||
|
|
||||||
[GitHub webhooks](https://developer.github.com/webhooks/) are fired for almost every significant action that users take on GitHub, whether it's pushes to code, opening or closing issues, opening or merging pull requests, or commenting on a discussion.
|
[GitHub webhooks](https://developer.github.com/webhooks/) are fired for almost every significant action that users take on GitHub, whether it's pushes to code, opening or closing issues, opening or merging pull requests, or commenting on a discussion.
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ Many robots will spend their entire day responding to these actions. `robot.on`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = robot => {
|
module.exports = robot => {
|
||||||
robot.on('push', event => {
|
robot.on('push', async (event, context) => {
|
||||||
// Code was pushed to the repo, what should we do with it?
|
// Code was pushed to the repo, what should we do with it?
|
||||||
robot.log(event);
|
robot.log(event);
|
||||||
});
|
});
|
||||||
|
@ -31,27 +31,21 @@ Most events also include an "action". For example, the [`issues`](https://develo
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = robot => {
|
module.exports = robot => {
|
||||||
robot.on('issues.opened', event => {
|
robot.on('issues.opened', async (event, context) => {
|
||||||
// An issue was just opened.
|
// An issue was just opened.
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Interacting with GitHub
|
## Interacting with GitHub
|
||||||
|
|
||||||
Probot uses [GitHub Integrations](https://developer.github.com/early-access/integrations/):
|
Probot uses [GitHub Integrations](https://developer.github.com/early-access/integrations/). An integration is a first-class actor on GitHub, like a user (e.g. [@defunkt](https://github/defunkt)) or a organization (e.g. [@github](https://github.com/github)). The integration is given access to a repository or repositories by being "installed" on a user or organization account and can perform actions through the API like [commenting on an issue](https://developer.github.com/v3/issues/comments/#create-a-comment) or [creating a status](https://developer.github.com/v3/repos/statuses/#create-a-status).
|
||||||
|
|
||||||
> Integrations are a new way to extend GitHub. 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. Integrations are first class actors within GitHub.
|
|
||||||
>
|
|
||||||
> –Documentation on [GitHub Integrations](https://developer.github.com/early-access/integrations/)
|
|
||||||
|
|
||||||
An integration is a first-class actor on GitHub, like a user (e.g. [@defunkt](https://github/defunkt)) or a organization (e.g. [@github](https://github.com/github)). That means it can be given access to repositories and perform actions through the API like [commenting on an issue](https://developer.github.com/v3/issues/comments/#create-a-comment) or [creating a status](https://developer.github.com/v3/repos/statuses/#create-a-status). The integration is given access to a repository or repositories by being "installed" on a user or organization account.
|
|
||||||
|
|
||||||
Each event delivered includes an ID of the installation that triggered it, which can be used to authenticate. `robot.auth(id)` will give your plugin an authenticated GitHub client that can be used to make API calls.
|
Each event delivered includes an ID of the installation that triggered it, which can be used to authenticate. `robot.auth(id)` will give your plugin an authenticated GitHub client that can be used to make API calls.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = function(robot) {
|
module.exports = robot => {
|
||||||
robot.on('issues.opened', event => {
|
robot.on('issues.opened', async (event, context) => {
|
||||||
const github = await robot.auth(event.payload.installation.id);
|
const github = await robot.auth(event.payload.installation.id);
|
||||||
// do something useful with the github client
|
// do something useful with the github client
|
||||||
});
|
});
|
||||||
|
@ -65,8 +59,8 @@ The `github` object returned from authenticating is an instance of the [github N
|
||||||
Here is an example of an autoresponder plugin that comments on opened issues:
|
Here is an example of an autoresponder plugin that comments on opened issues:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
module.exports = function(robot) {
|
module.exports = robot => {
|
||||||
robot.on('issues.opened', async function(event, context) {
|
robot.on('issues.opened', async (event, context) => {
|
||||||
const github = await robot.auth(event.payload.installation.id);
|
const github = await robot.auth(event.payload.installation.id);
|
||||||
|
|
||||||
// `context` extracts information from the event, which can be passed to
|
// `context` extracts information from the event, which can be passed to
|
||||||
|
@ -82,18 +76,26 @@ module.exports = function(robot) {
|
||||||
|
|
||||||
See the [full API docs](https://mikedeboer.github.io/node-github/) to see all the ways you can interact with GitHub. Some API endpoints are not available on GitHub Integrations yet, so check [which ones are available](https://developer.github.com/early-access/integrations/available-endpoints/) first.
|
See the [full API docs](https://mikedeboer.github.io/node-github/) to see all the ways you can interact with GitHub. Some API endpoints are not available on GitHub Integrations yet, so check [which ones are available](https://developer.github.com/early-access/integrations/available-endpoints/) first.
|
||||||
|
|
||||||
### Running plugins
|
## Running plugins
|
||||||
|
|
||||||
TODO: link to docs on getting running in development
|
Before you can run your plugin against GitHub, you'll need to set up your [development environment](development.md) and configure a GitHub Integration for testing. You will the the ID and private key of a GitHub Integration to run the bot.
|
||||||
|
|
||||||
|
Once you have an integration created, install `probot`:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm install -g https://github.com/probot/probot
|
$ npm install -g probot
|
||||||
|
```
|
||||||
|
|
||||||
$ probot run ./autoresponder.js
|
and run your bot, replacing `9999` and `private-key.pem` below with the ID and path to the private key of your integration.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ probot run -i 9999 -P private-key.pem ./autoresponder.js
|
||||||
Listening on http://localhost:3000
|
Listening on http://localhost:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
### Distributing
|
Once your bot is running, you'll need to use `ngrok` to receive GitHub webhooks as described in the [development](development.md) documentation.
|
||||||
|
|
||||||
|
## Publishing your bot
|
||||||
|
|
||||||
Plugins can be published in NPM modules, which can either be deployed as stand-alone bots, or combined with other plugins.
|
Plugins can be published in NPM modules, which can either be deployed as stand-alone bots, or combined with other plugins.
|
||||||
|
|
||||||
|
@ -104,18 +106,8 @@ $ curl -L https://github.com/probot/plugin-template/archive/master.tar.gz | tar
|
||||||
$ mv plugin-template probot-myplugin && cd probot-myplugin
|
$ mv plugin-template probot-myplugin && cd probot-myplugin
|
||||||
```
|
```
|
||||||
|
|
||||||
### Logging
|
## Next
|
||||||
|
|
||||||
Probot uses [bunyan](https://github.com/trentm/node-bunyan) for logging. You can call it with `robot.log`.
|
- [See the full Probot API](api.md)
|
||||||
|
- [Tips for development](development.md)
|
||||||
```js
|
- [Deploy your plugin](deployment.md)
|
||||||
robot.log("This is a debug message");
|
|
||||||
robot.log.debug("…so is this");
|
|
||||||
robot.log.trace("Now we're talking");
|
|
||||||
robot.log.info("I thought you should know…");
|
|
||||||
robot.log.warn("Woah there");
|
|
||||||
robot.log.error("ETOOMANYLOGS");
|
|
||||||
robot.log.fatal("Goodbye, cruel world!");
|
|
||||||
```
|
|
||||||
|
|
||||||
The default log level is `debug`, but you can change it by setting the `LOG_LEVEL` environment variable to `trace`, `info`, `warn`, `error`, or `fatal`.
|
|
||||||
|
|
Loading…
Reference in New Issue