Comparing version 0.2.0 to 0.2.1
@@ -1,8 +0,10 @@ | ||
# 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 | ||
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`: | ||
@@ -29,7 +31,4 @@ ```json | ||
### 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. | ||
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). | ||
TODO: Generic docs for deploying a plugin to Heroku |
@@ -1,4 +0,4 @@ | ||
## 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: | ||
@@ -13,3 +13,3 @@ ```js | ||
### Receiving GitHub webhooks | ||
## Receiving GitHub webhooks | ||
@@ -22,3 +22,3 @@ [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. | ||
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? | ||
@@ -36,3 +36,3 @@ robot.log(event); | ||
module.exports = robot => { | ||
robot.on('issues.opened', event => { | ||
robot.on('issues.opened', async (event, context) => { | ||
// An issue was just opened. | ||
@@ -43,17 +43,11 @@ }); | ||
### 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. | ||
```js | ||
module.exports = function(robot) { | ||
robot.on('issues.opened', event => { | ||
module.exports = robot => { | ||
robot.on('issues.opened', async (event, context) => { | ||
const github = await robot.auth(event.payload.installation.id); | ||
@@ -72,4 +66,4 @@ // do something useful with the github client | ||
```js | ||
module.exports = function(robot) { | ||
robot.on('issues.opened', async function(event, context) { | ||
module.exports = robot => { | ||
robot.on('issues.opened', async (event, context) => { | ||
const github = await robot.auth(event.payload.installation.id); | ||
@@ -90,15 +84,23 @@ | ||
### 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 | ||
``` | ||
### 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. | ||
@@ -113,16 +115,6 @@ | ||
### Logging | ||
## Next | ||
Probot uses [bunyan](https://github.com/trentm/node-bunyan) for logging. You can call it with `robot.log`. | ||
```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`. | ||
- [See the full Probot API](api.md) | ||
- [Tips for development](development.md) | ||
- [Deploy your plugin](deployment.md) |
@@ -0,1 +1,2 @@ | ||
const cacheManager = require('cache-manager'); | ||
const createWebhook = require('github-webhook-handler'); | ||
@@ -7,2 +8,7 @@ const createIntegration = require('github-integration'); | ||
module.exports = options => { | ||
const cache = cacheManager.caching({ | ||
store: 'memory', | ||
ttl: 60 * 60 // 1 hour | ||
}); | ||
const webhook = createWebhook({path: '/', secret: options.secret}); | ||
@@ -15,3 +21,3 @@ const integration = createIntegration({ | ||
const server = createServer(webhook); | ||
const robot = createRobot(integration, webhook); | ||
const robot = createRobot(integration, webhook, cache); | ||
@@ -18,0 +24,0 @@ // Show trace for any unhandled rejections |
const bunyan = require('bunyan'); | ||
const bunyanFormat = require('bunyan-format'); | ||
const GitHubApi = require('github'); | ||
const Bottleneck = require('bottleneck'); | ||
const Context = require('./context'); | ||
@@ -12,5 +14,6 @@ | ||
class Robot { | ||
constructor(integration, webhook) { | ||
constructor(integration, webhook, cache) { | ||
this.integration = integration; | ||
this.webhook = webhook; | ||
this.cache = cache; | ||
} | ||
@@ -28,4 +31,11 @@ | ||
auth(id) { | ||
return this.integration.asInstallation(id); | ||
async auth(id) { | ||
const token = await this.cache.wrap(`integration:${id}:token`, () => { | ||
this.log.info(`creating token for installation ${id}`); | ||
return this.integration.createToken(id); | ||
}, {ttl: 60 * 60}); | ||
const github = new GitHubApi({debug: process.env.LOG_LEVEL === 'trace'}); | ||
github.authenticate({type: 'token', token: token.token}); | ||
return rateLimitedClient(github); | ||
} | ||
@@ -38,2 +48,13 @@ | ||
// Hack client to only allow one request at a time with a 1s delay | ||
// https://github.com/mikedeboer/node-github/issues/526 | ||
function rateLimitedClient(github) { | ||
const limiter = new Bottleneck(1, 1000); | ||
const oldHandler = github.handler; | ||
github.handler = (msg, block, callback) => { | ||
limiter.submit(oldHandler.bind(github), msg, block, callback); | ||
}; | ||
return github; | ||
} | ||
// Add level methods on the logger | ||
@@ -40,0 +61,0 @@ ['trace', 'debug', 'info', 'warn', 'error', 'fatal'].forEach(level => { |
{ | ||
"name": "probot", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "a trainable robot that responds to activity on GitHub", | ||
@@ -17,6 +17,9 @@ "repository": "https://github.com/probot/probot", | ||
"dependencies": { | ||
"bottleneck": "^1.15.1", | ||
"bunyan": "^1.8.5", | ||
"bunyan-format": "^0.2.1", | ||
"cache-manager": "^2.4.0", | ||
"commander": "^2.9.0", | ||
"dotenv": "~4.0.0", | ||
"github": "^8.1.0", | ||
"github-integration": "^1.0.0", | ||
@@ -30,3 +33,3 @@ "github-webhook-handler": "^0.6.0", | ||
"mocha": "^3.0.2", | ||
"xo": "^0.18.0" | ||
"xo": "^0.19.0" | ||
}, | ||
@@ -33,0 +36,0 @@ "xo": { |
# Probot | ||
Probot is bot framework for GitHub. It's like [Hubot](https://hubot.github.com/), but for GitHub instead of chat. | ||
Probot is a bot framework for GitHub. It's like [Hubot](https://hubot.github.com/), but for GitHub instead of chat. | ||
@@ -11,17 +11,16 @@ If you've ever thought, "wouldn't it be cool if GitHub could…"; imma stop you right there. Most features can actually be added via [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` | ||
- [stale](https://github.com/probot/stale) closes abandoned issues after a period of inactivity. | ||
Bots are implemented as plugins, which are easy to write, deploy, and share. Here are just a few examples of things probot can do: | ||
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 | ||
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). | ||
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) | ||
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). |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44939
30
582
11
26
5
+ Addedbottleneck@^1.15.1
+ Addedcache-manager@^2.4.0
+ Addedgithub@^8.1.0
+ Addedasync@1.5.2(transitive)
+ Addedbottleneck@1.16.0(transitive)
+ Addedcache-manager@2.11.1(transitive)
+ Addedlodash.clonedeep@4.5.0(transitive)
+ Addedlru-cache@4.0.0(transitive)
+ Addedpseudomap@1.0.2(transitive)
+ Addedyallist@2.1.2(transitive)