Skip to content

Commit

Permalink
Merge pull request #104 from probot/moar-docs
Browse files Browse the repository at this point in the history
Doc updates
  • Loading branch information
bkeepers committed Mar 20, 2017
2 parents 57d5ef5 + 6ac5b45 commit 7dfd119
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 91 deletions.
37 changes: 0 additions & 37 deletions CONTRIBUTING.md

This file was deleted.

19 changes: 9 additions & 10 deletions README.md
Expand Up @@ -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/)
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.

## 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).
Check out [all probot plugins](https://github.com/search?q=topic%3Aprobot-plugin&type=Repositories).

See [CONTRIBUTING.md](CONTRIBUTING.md) for other ways to contribute.
## Contributing

[![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).
98 changes: 98 additions & 0 deletions docs/api.md
@@ -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.
15 changes: 7 additions & 8 deletions docs/deployment.md
@@ -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

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
{
Expand All @@ -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.
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
27 changes: 27 additions & 0 deletions docs/development.md
@@ -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`
64 changes: 28 additions & 36 deletions docs/plugins.md
@@ -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
module.exports = robot => {
Expand All @@ -10,15 +10,15 @@ module.exports = robot => {

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.

Many robots will spend their entire day responding to these actions. `robot.on` will listen for any GitHub webhook events:

```js
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?
robot.log(event);
});
Expand All @@ -31,27 +31,21 @@ Most events also include an "action". For example, the [`issues`](https://develo

```js
module.exports = robot => {
robot.on('issues.opened', event => {
robot.on('issues.opened', async (event, context) => {
// An issue was just opened.
});
};
```

### Interacting with GitHub
## Interacting with GitHub

Probot uses [GitHub Integrations](https://developer.github.com/early-access/integrations/):

> 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.
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).

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);
// do something useful with the github client
});
Expand All @@ -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:

```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);

// `context` extracts information from the event, which can be passed to
Expand All @@ -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.

### 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 probot
```
$ npm install -g https://github.com/probot/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.

Expand All @@ -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
```

### Logging

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!");
```
## Next

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 comments on commit 7dfd119

Please sign in to comment.