forked from mirrors/probot
Rework docs for website
This commit is contained in:
parent
e21eb51194
commit
0158c1f167
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
next: docs/hello-world.md
|
||||
permalink: /docs/
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
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 Apps](https://developer.github.com/apps/), which extend GitHub and can be installed directly on organizations and user accounts and granted access to specific repositories. They come with granular permissions and built-in webhooks. Apps are first class actors within GitHub.
|
||||
|
||||
**Probot is a framework for building [GitHub Apps](http://developer.github.com/apps) in [Node.js](https://nodejs.org/)**. It aims to eliminate all the drudgery–like receiving and validating webhooks, and doing authentication handstands–so you can focus on the features you want to build.
|
||||
|
||||
Probot apps are easy to write, deploy, and share. Many of the most popular Probot apps are hosted, so there's nothing for you to deploy and manage. Here are just a few examples of things that have been built with Probot:
|
||||
|
||||
- [stale](/apps/stale/) - closes abandoned issues after a period of inactivity.
|
||||
- [settings](/apps/settings/) - syncs repository settings defined in `.github/config.yml` to GitHub, enabling Pull Requests for repository settings.
|
||||
- [request-info](/apps/request-info/) - requests more info from newly opened Pull Requests and Issues that contain either default titles or whose description is left blank.
|
||||
- [Browse more examples](https://github.com/search?q=topic%3Aprobot-plugin&type=Repositories)
|
||||
|
||||
Ready to get started?
|
|
@ -1,4 +1,4 @@
|
|||
# Best practices for Probot plugins
|
||||
# Best Practices
|
||||
|
||||
First and foremost, your plugin must obey the [The Three Laws of Robotics](https://en.wikipedia.org/wiki/Three_Laws_of_Robotics):
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# Deploy
|
||||
---
|
||||
next: docs/best-practices.md
|
||||
---
|
||||
|
||||
# Deployment
|
||||
|
||||
Every plugin can either be deployed as a stand-alone bot, or combined with other plugins in one deployment.
|
||||
|
||||
|
@ -72,7 +76,7 @@ Probot runs like [any other Node app](https://devcenter.heroku.com/articles/depl
|
|||
-----> Launching... done
|
||||
http://arcane-lowlands-8408.herokuapp.com deployed to Heroku
|
||||
|
||||
1. Your plugin should be up and running! To verify that your plugin
|
||||
1. Your plugin should be up and running! To verify that your plugin
|
||||
is receiving webhook data, you can tail your app's logs:
|
||||
|
||||
$ heroku config:set LOG_LEVEL=trace
|
||||
|
|
|
@ -1,8 +1,57 @@
|
|||
# Development
|
||||
---
|
||||
next: docs/webhooks.md
|
||||
---
|
||||
|
||||
To run a plugin locally, you'll need to create a GitHub App and configure it to deliver webhooks to your local machine.
|
||||
# Developing a Plugin
|
||||
|
||||
To develop a Probot plugin, you will first need a recent version of [Node.js](https://nodejs.org/) installed. Probot uses the `async/await` keywords, so Node.js 7.6 is the minimum required version.
|
||||
|
||||
## Generating a new plugin
|
||||
|
||||
[create-probot-plugin](https://github.com/probot/create-probot-plugin) is the best way to start building a new plugin. It will generate a new plugin with everything you need to get started and run your plugin in production.
|
||||
|
||||
To get started, install the module from npm:
|
||||
|
||||
```
|
||||
$ npm install -g create-probot-plugin
|
||||
```
|
||||
|
||||
Next, run the app:
|
||||
|
||||
```
|
||||
$ create-probot-plugin my-first-plugin
|
||||
```
|
||||
|
||||
This will ask you a series of questions about your plugin, which should look something like this:
|
||||
|
||||
```
|
||||
Let's create a Probot plugin!
|
||||
? Plugin's package name: my-first-plugin
|
||||
? Description of plugin: A "Hello World" GitHub App built with Probot
|
||||
? Plugin author's full name: Brandon Keepers
|
||||
? Plugin author's email address: bkeepers@github.com
|
||||
? Plugin author's homepage:
|
||||
? Plugin's GitHub user or org name: bkeepers
|
||||
? Plugin's repo name: my-first-plugin
|
||||
created file: my-first-plugin/.env.example
|
||||
created file: my-first-plugin/.gitignore
|
||||
created file: my-first-plugin/.travis.yml
|
||||
created file: my-first-plugin/LICENSE
|
||||
created file: my-first-plugin/README.md
|
||||
created file: my-first-plugin/app.json
|
||||
created file: my-first-plugin/index.js
|
||||
created file: my-first-plugin/package-lock.json
|
||||
created file: my-first-plugin/package.json
|
||||
created file: my-first-plugin/docs/deploy.md
|
||||
Done!
|
||||
```
|
||||
|
||||
The most important files note here are `index.js`, which is where the code for your plugin will go, and `package.json`, which makes this a standard [npm module](https://docs.npmjs.com/files/package.json).
|
||||
|
||||
## Configure a GitHub App
|
||||
|
||||
To run your plugin in development, you will need to configure a GitHub App to deliver webhooks to your local machine.
|
||||
|
||||
1. Make sure you have a recent version of [Node.js](https://nodejs.org/) installed
|
||||
1. [Create a new GitHub App](https://github.com/settings/apps/new) with:
|
||||
- **Webhook URL**: Set to `https://example.com/` and we'll update it in a minute.
|
||||
- **Webhook Secret:** `development`
|
||||
|
@ -14,11 +63,22 @@ To run a plugin locally, you'll need to create a GitHub App and configure it to
|
|||
|
||||
You'll need to create a test repository and install your app by clicking the "Install" button on the settings page of your app.
|
||||
|
||||
Whenever you come back to work on the app after you've already had it running once, you should only need to run `$ npm start`.
|
||||
## Running the plugin
|
||||
|
||||
Once you've set the `APP_ID` of your GitHub app in `.env` and downloaded the private key, you're ready to run your bot.
|
||||
|
||||
```
|
||||
$ npm start
|
||||
> probot run ./index.js
|
||||
|
||||
Yay, the plugin was loaded!
|
||||
18:11:55.838Z DEBUG PRobot: Loaded plugin: ./index.js
|
||||
Listening on https://bkeepers.localtunnel.me
|
||||
```
|
||||
|
||||
Optionally, you can also run your plugin through [nodemon](https://github.com/remy/nodemon#nodemon) which will listen on any files changes in your local development environment and automatically restart the server. After installing nodemon, you can run `nodemon --exec "npm start"` and from there the server will automatically restart upon file changes.
|
||||
|
||||
## Debugging
|
||||
|
||||
1. Always run `$ npm install` and restart the server if package.json has changed.
|
||||
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`
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
next: docs/http.md
|
||||
---
|
||||
|
||||
# Interacting with GitHub
|
||||
|
||||
Probot uses [GitHub Apps](https://developer.github.com/apps/). An app is a first-class actor on GitHub, like a user (e.g. [@defunkt](https://github/defunkt)) or an organization (e.g. [@github](https://github.com/github)). The app 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).
|
||||
|
||||
`context.github` is an authenticated GitHub client that can be used to make API calls. It 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.
|
||||
|
||||
Here is an example of an autoresponder plugin that comments on opened issues:
|
||||
|
||||
```js
|
||||
module.exports = robot => {
|
||||
robot.on('issues.opened', async context => {
|
||||
// `context` extracts information from the event, which can be passed to
|
||||
// GitHub API calls. This will return:
|
||||
// {owner: 'yourname', repo: 'yourrepo', number: 123, body: 'Hello World!}
|
||||
const params = context.issue({body: 'Hello World!'})
|
||||
|
||||
// Post a comment on the issue
|
||||
return context.github.issues.createComment(params);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
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 Apps yet, so check [which ones are available](https://developer.github.com/v3/apps/available-endpoints/) first.
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
next: docs/development.md
|
||||
---
|
||||
|
||||
# Hello World
|
||||
|
||||
A Probot plugin is just a [Node.js module](https://nodejs.org/api/modules.html) that exports a function:
|
||||
|
||||
```js
|
||||
module.exports = robot => {
|
||||
// your code here
|
||||
};
|
||||
```
|
||||
|
||||
The `robot` parameter is an instance of [`Robot`](https://probot.github.io/probot/latest/Robot.html) and gives you access to all of the bot goodness.
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
next: docs/simulating-webhooks.md
|
||||
---
|
||||
|
||||
# HTTP Routes
|
||||
|
||||
Calling `robot.route('/my-plugin')` will return an [express](http://expressjs.com/) router that you can use to expose HTTP endpoints from your plugin.
|
||||
|
||||
```js
|
||||
module.exports = robot => {
|
||||
// Get an express router to expose new HTTP endpoints
|
||||
const app = robot.route('/my-plugin');
|
||||
|
||||
// Use any middleware
|
||||
app.use(require('express').static(__dirname + '/public'));
|
||||
|
||||
// Add a new route
|
||||
app.get('/hello-world', (req, res) => {
|
||||
res.end('Hello World');
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
Visit https://localhost:3000/my-plugin/hello-world to access the endpoint.
|
||||
|
||||
It is strongly encouraged to use the name of your package as the prefix so none of your routes or middleware conflict with other plugins. For example, if [`probot/owners`](https://github.com/probot/owners) exposed an endpoint, the plugin would call `robot.route('/owners')` to prefix all endpoints with `/owners`.
|
||||
|
||||
See the [express documentation](http://expressjs.com/en/guide/routing.html) for more information.
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
next: docs/deployment.md
|
||||
---
|
||||
|
||||
# Pagination
|
||||
|
||||
Many GitHub API endpoints are paginated. The `github.paginate` method can be used to get each page of the results.
|
||||
|
||||
```js
|
||||
context.github.paginate(context.github.issues.getAll(context.repo()), res => {
|
||||
res.data.issues.forEach(issue => {
|
||||
robot.console.log('Issue: %s', issue.title);
|
||||
});
|
||||
});
|
||||
```
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
next: docs/pagination.md
|
||||
---
|
||||
|
||||
# Simulating Webhooks
|
||||
|
||||
As you are developing your plugin, you will likely want to test it by repeatedly trigging the same webhook. You can simulate a webhook being delivered by saving the payload to a file, and then calling `probot simulate` from the command line.
|
||||
|
||||
To save a copy of the payload, go to the [settings](https://github.com/settings/apps) page for your App, and go to the **Advanced** tab. Click on one of the **Recent Deliveries** to expand it and see the details of the webhook event. Copy the JSON from the the **Payload** and save it to a new file. (`test/fixtures/issues.labeled.json` in this example).
|
||||
|
||||

|
||||
|
||||
Next, simulate this event being delivered by running:
|
||||
|
||||
```
|
||||
$ node_modules/.bin/probot simulate issues test/fixtures/issues.labeled.json ./index.js
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
next: docs/pagination.md
|
||||
---
|
||||
|
||||
# Testing
|
||||
|
||||
We highly recommend working in the style of [test-driven development](http://agiledata.org/essays/tdd.html) when creating probot plugins. It frustrating to constantly create real GitHub events in order to test a plugin. Redelivering webhooks is possible and can be accessed in your app's [settings](https://github.com/settings/apps) page under the **Advanced** tab. We do offer the above documented `simulate` method to help make this easier; however, by writing your tests first, you can avoid repeatedly recreating actual events from GitHub to check if your code is working.
|
||||
|
||||
For our testing examples, we use [mocha](https://mochajs.org/) and [expect](https://github.com/mjackson/expect), but there are other options that can perform similar operations. Here's an example of creating a robot instance and mocking out the GitHub API:
|
||||
|
||||
```js
|
||||
// Requiring our testing framework
|
||||
const expect = require('expect');
|
||||
// Requiring probot allows us to mock out a robot instance
|
||||
const {createRobot} = require('probot');
|
||||
// Create a fixtures folder in your test folder
|
||||
// Then put any larger testing payloads in there
|
||||
const payload = require('./fixtures/payload');
|
||||
|
||||
describe('your-plugin', () => {
|
||||
let robot;
|
||||
let github;
|
||||
|
||||
beforeEach(() => {
|
||||
// Here we create a robot instance
|
||||
robot = createRobot();
|
||||
// Here we initialize the plugin on the robot instance
|
||||
plugin(robot);
|
||||
// This is an easy way to mock out the GitHub API
|
||||
github = {
|
||||
issues: {
|
||||
createComment: expect.createSpy().andReturn(Promise.resolve({
|
||||
// Whatever the GitHub API should return
|
||||
}))
|
||||
}
|
||||
}
|
||||
// Passes the mocked out GitHub API into out robot instance
|
||||
robot.auth = () => Promise.resolve(github);
|
||||
});
|
||||
|
||||
describe('your functionality', () => {
|
||||
it('performs an action', async () => {
|
||||
// Simulates delivery of a payload
|
||||
await robot.receive(payload);
|
||||
// This test would pass if in your main code you called `context.github.issues.createComment`
|
||||
expect(github.issues.createComment).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
A good testing example from [update-docs](github.com/behaviorbot/update-docs) can be found [here](https://github.com/behaviorbot/update-docs/blob/master/test/index.js), and another one from [owners](github.com/probot/owners) can be found [here](https://github.com/probot/owners/blob/master/test/owner-notifier.js).
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
next: docs/github-api.md
|
||||
---
|
||||
|
||||
# Receiving 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', async context => {
|
||||
// Code was pushed to the repo, what should we do with it?
|
||||
robot.log(context);
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
The robot can listen to any of the [GitHub webhook events](https://developer.github.com/webhooks/#events). The `context` object includes all of the information about the event that was triggered, and `context.payload` has the payload delivered by GitHub.
|
||||
|
||||
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', async context => {
|
||||
// An issue was just opened.
|
||||
});
|
||||
};
|
||||
```
|
Loading…
Reference in New Issue