Giter VIP home page Giter VIP logo

probot's Introduction

Probot's logo, a cartoon robot

A framework for building GitHub Apps to automate and improve your workflow

npm Build Status Codecov @ProbotTheRobot on Twitter


If you've ever thought, "wouldn't it be cool if GitHub could…"; I'm going to stop you right there. Most features can actually be added via GitHub 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.

How it works

Probot is a framework for building GitHub Apps in Node.js, written in TypeScript. GitHub Apps can listen to webhook events sent by a repository or organization. Probot uses its internal event emitter to perform actions based on those events. A simple Probot App might look like this:

export default (app) => {
  app.on("issues.opened", async (context) => {
    const issueComment = context.issue({
      body: "Thanks for opening this issue!",
    });
    return context.octokit.issues.createComment(issueComment);
  });

  app.onAny(async (context) => {
    context.log.info({ event: context.name, action: context.payload.action });
  });

  app.onError(async (error) => {
    app.log.error(error);
  });
};

Building a Probot App

If you've landed in this GitHub repository and are looking to start building your own Probot App, look no further than probot.github.io! The Probot website contains our extensive getting started documentation and will guide you through the set up process.

This repository hosts the code for the npm Probot package which is what all Probot Apps run on. Most folks who land in this repository are likely looking to get started building their own app.

Contributing

Probot is built by people just like you! Most of the interesting things are built with Probot, so consider starting by writing a new app or improving one of the existing ones.

If you're interested in contributing to Probot itself, check out our contributing docs to get started.

Want to discuss with Probot users and contributors? Discuss on GitHub!

Ideas

Have an idea for a cool new GitHub App (built with Probot)? That's great! If you want feedback, help, or just to share it with the world you can do so by creating an issue in the probot/ideas repository!

probot's People

Contributors

aarondewes avatar anglinb avatar binarymuse avatar bkeepers avatar boneskull avatar bpscott avatar dependabot[bot] avatar eddman avatar fosefx avatar gimenete avatar gr2m avatar greenkeeper[bot] avatar hiimbex avatar jamesgeorge007 avatar jasonetco avatar kammerjaeger avatar karol-majewski avatar kentaro-m avatar lee-dohm avatar macklinu avatar maximdevoir avatar renovate[bot] avatar seemakamath avatar shaftoe avatar sridharavinash avatar stkent avatar tcbyrd avatar wilhelmklopp avatar wolfy1339 avatar zeke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

probot's Issues

Add option to include configuration from file or another repository

Including configuration from another repository will be incredibly useful for a couple use cases:

  1. Projects that use many repositories, like Atom, can store standard behaviors in one repository, and point various plugins and components to those configurations.
  2. Encouraging reuse and standardization of behaviors across projects

The include feature should work for:

  • one or more files in the same repo
  • one or more repositories (defaulting to .probot.yml)
  • specific paths in other repositories
  • specific ref in other repositories

[Behavior] Maintain a changelog

When a pull request is merged, add a line to CHANGELOG.md or HISTORY.md, with the PR title, number, and if the contributor is not a maintainer, give them props, optionally categorizing the updates based on tags.

@jekyllbot does this (with a slightly different behavior that I don't like), but the end result could look somethign like this:

## Head

### Minor

* Make the button red (#123, props @bkeepers)

### Major

* Button is now a switch (#456)

### Development

* Add Rubocop (#789)

Syntax errors in examples

A bunch of the examples either have syntax errors or use features that are not implemented. Ideally those would be separated into examples that work and examples that are aspirational (bonus points for tests that check that it is at least is valid syntax).

Figure out deployment story

Since people will be able to write their own behaviors as node modules (#4), this bot should be dead simple for anyone deploy and add their behaviors.

A Deploy to Heroku button would be ideal. There will also likely be some configuration depending on how the GitHub integration works (#5).

[Behavior] watchers: @mention people or teams when a label is applied

When a label is applied, this behavior should look up watchers, which includes users or teams and the labels they are watching, and post a comment that @mentions them:

Configuration:

  • Watchers - list of users or teams and the labels they are watching
  • Message - the template of a message to post when a label is added. e.g. Hey {{ watchers }}, this was labeled \{{ label }}.

Examples:

Conditions to implement

Conditions are the when part of a behavior. They will be necessary for filtering out events based on the criteria.

  • payload - filter by attributes of the event payload
    • contains
    • matches

What else?

[Behavior] @mention `OWNERS` based on modified files

OWNERS is a pattern for declaring who is responsible for different parts of the project. It could be used to automatically @mention reviewers based on files changed, similar to mention-bot (#10).

Configuration:

Examples:

  • Know of any projects that use a behavior like this?

Plugin API

Before the first release, there should be a clearly defined plugin API and easy way to create new behaviors as node packages. The plugin API should have convenience methods for performing common actions on the item that triggered the event (e.g. comment on a PR, update statuses, apply labels, etc.).

The naive example in the README right now is something like this:

robot.on('pull', function(event) {
  robot.comment("Thanks for the pull request! We'll review it within 72 hours!");
});

The first behavior is looking something like this:

module.exports = {
  webhook: 'issues', // name of webhook event
  action: function(event, github) {
    // event - the webhook event
    // github - API client: https://mikedeboer.github.io/node-github/
  }
};

I'm planning to implement a few other behaviors before figuring out what the API should look like.

Create test infrastructure for probot

We want to make it super-simple to test Probot plugins. To that end, there are some things that we would like to provide:

  • An easy way to create a robot instance for testing
  • Test robot will respond to github requests with randomized test data
  • Test robot will respond to github requests with errors
  • A way to trigger test webhooks for integration testing

Rebooting PRobot

I still think PRobot is a good idea, but I'm going to be honest and say that it really sucks right now. You can't do much with the current feature set, and implementing new features is hard and confusing.

After talking with @groundwater, I would like to take PRobot in a very different direction for a while. Feedback on this would be appreciated.

Thus far the aim has been to expose useful GitHub APIs through a jQuery-style API that is safe-ish to run on a single hosted instance. Eventually, I think that is the right idea, but right now, it's a premature optimization. It makes it much less useful because people can only use PRobot for things have been implemented in this custom API.

So I'd like to remove the existing API right now, focus on building a good stand-alone bot framework that can make use of any existing node libraries, and then later figure out how to provide a simple API and run it on a hosted instance.

Here's basically the new proposed roadmap:

  • v0.1 - GitHub bot framework
  • v1.0 - Hosted GitHub Integration
  • v2.0 - High-Level API

v0.1- GitHub bot framework

This will make it really easy to create new bots by abstracting the details of handling webhooks and building a GitHub Integration.

For example, here is an autoresponder module that comments on opened issues with the template in github/AUTOREPLY_TEMPLATE.md:

// Export a function that takes `robot` as an argument
module.exports = function(robot) {
  // `robot.on` will listen for any GitHub webhook events
  robot.on('issues.opened', async function(event, context) {
    // `context` extracts information from the event, which can be passed to
    // GitHub API calls.
    const options = context.repo({path: '.github/AUTOREPLY_TEMPLATE.md'});
    // This returns:
    //   {owner: 'yourname', repo: 'yourrepo', path: '.github/AUTOREPLY_TEMPLATE.md'}

    // `context.github` is an instance of the NodeJS wrapper for the GitHub API
    // https://mikedeboer.github.io/node-github/
    const data = await context.github.repos.getContent(options);
    const template = new Buffer(data.content, 'base64').toString();

    return context.github.issues.createComment(context.issue({body: template}));
  });
}

This bot would be run locally with the probot command, which will start up a server and listen for GitHub webhooks:

$ probot autoresponder.js
Listening on http://localhost:5000

Here's a more sophisticated bot based on github-configurer, which will update GitHub settings for a repository whenever .github/config.yml is modified.

module.exports = robot => robot.on('push', push);

const configurer = require('github-configurer');
const FILE_NAME = '.github/config.yml';

async function push(event, context) {
  const payload = event.payload;
  const defaultBranch = payload.ref === 'refs/heads/' + payload.repository.default_branch;

  const configModified = payload.commits.find(commit => {
    return commit.added.includes(FILE_NAME) || commit.modified.includes(FILE_NAME);
  });

  if (defaultBranch && configModified) {
    const options = {
      owner: payload.repository.owner.name,
      repo: payload.repository.name,
      path: FILE_NAME
    };

    const data = await context.github.repos.getContent(options);
    const content = new Buffer(data.content, 'base64').toString();
    return configurer(context.github, options, content).update();
  }
}

These examples can be published as behaviors in NPM modules (e.g. probot-autoresponder and probot-configurer) and deployed as stand-alone bots, or combined into one instance.

For example, if you wanted to deploy a bot for your project that included both of these behaviors, you could just create a new app that has them both listed as dependencies in package.json:

{
  "name": "my-probot",
  "priate": true,
  "dependencies": {
    "probot-autoresponder": "~1.0",
    "probot-configurer": "~1.0",
  },
  "scripts": {
    "start": "probot"
 }
}

Running the $ npm start on this app would start up a bot that included both of these behaviors.

This approach creates a ton of flexibility. The core of probot will handle the GitHub Integration and provide some basic services. Behaviors will be relatively easy to implement and reuse, and more importantly they'll be free to experiment and explore new patterns.

Hosted GitHub Integration

Later we can explore the idea of providing a single hosted integration and allowing people to run their probot behaviors directly from their repository via a .probot.js file.

High-Level API (current version)

Finally, after there is some adoption and people are writing a lot of behaviors, I'd like to revisit the idea of exposing a friendlier and more expressive API that allows combining common actions in a chainable manner like we currently have:

on('issues.labeled')
  .filter(event => event.payload.label.name == 'plugins')
  .comment('Hey @jekyll/plugins, the `plugins` label was added');

Thoughts?

cc @lee-dohm @zeke @migarjo @jonico

Actions to implement

Here are a list of actions that need implemented. If anyone wants to jump in, these are pretty easy to implement. Check out the docs for adding an action or one of the merged PRs listed below as an example.

Issues

  • assign (#19)
  • comment (#13)
  • create issue
  • create milestone
  • delete comment
  • delete label (#13)
  • delete milestone
  • label (#13)
  • remove all labels
  • replace labels
  • unassign (#20)
  • update issue
  • update comment
  • lock (#22)
  • unlock (#22)
  • update milestone

Pull Requests

  • create pull request
  • create comment
  • create comment reply
  • delete comment
  • update comment
  • merge
  • update pull request

Reactions

  • create for commit comment
  • create for issue
  • create for issue comment
  • create for pull request review comment
  • delete

Organizations

  • add to organization
  • add to team
  • add team to repository
  • create team
  • create hook
  • delete team
  • delete hook
  • remove team from repo
  • update hook
  • update team
  • ping hook
  • publicize membership
  • conceal membership
  • remove from all teams
  • remove from organization
  • remove from team

Personal Acess Token never used

I am facing a problem with the getContent method which is supposed to fetch a .probot.yml file from my test repo:

github.repos.getContent() is fed the right owner and repo parameters from repository.full_name.split(), but once I create an issue, the bot crashes with the following log:

`C:\Users\Serge\Projects\PRobot\lib\configuration.js:11
}).then(data => {
^

TypeError: Cannot read property 'then' of undefined
at Function.load (C:\Users\Serge\Projects\PRobot\lib\configuration.js:11:7)
at EventEmitter.webhook.on.event (C:\Users\Serge\Projects\PRobot\server.js:33:26)
at emitOne (events.js:96:13)
at EventEmitter.emit (events.js:188:7)
at BufferList._callback (C:\Users\Serge\Projects\PRobot\node_modules\github-webhook-handler\github-webhook-handler.js:98:15)
at BufferList.end (C:\Users\Serge\Projects\PRobot\node_modules\bl\bl.js:98:10)
at IncomingMessage.onend (_stream_readable.js:511:10)
at IncomingMessage.g (events.js:291:16)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:185:7)`

I am not sure whether the problem is with the token I have generated and that I am feeding to the bot as an environment variable (which on the github settings page says "last used: never"), or if the problem has something to do with the configuration.js file.

[Behavior] Auto-assign maintainer to new issues

Another behavior of @jekyllbot (that's relatively new), when an issue comes in and @mentions an affinity team, one of the team captains are randomly assigned the issue. They're obviously free to unassigned or change assignment, but it creates a sense of distributed ownership of issues, based on where they are in the codebase.

dotenv-safe

Hey I just noticed dotenv in this PR: #36

I've had good luck with dotenv-safe which works just like dotenv, but also checks that everything in your .env is present in your .env.example

Logging

Figuring out what is going on when things break is a bit of a disaster right now. It would be great to have a verbose logging mode to be able to see what is going on in development.

/cc @seemakamath

Filter by attributes of the payload

Rules should be filterable by attributes of the payload.

Here are a few examples that were added in #13, which will likely changed based on implementation:

# Misc examples
  when:
    payload:
      sender.login: bkeepers
      issue.title:
        contains: "[WIP]"
      issue.body:
        matches: /^$/
      issue.labels
        contains: "bug"

  # Close issues with no body
  - on:
      - issues.opened
    when:
      payload:
        body:
          matches: /^$/
    then:
      comment: "Hey @{{ user.login }}, you didn't include a description of the problem, so we're closing this issue."

  # Perform actions based on content of comments
  - on: issue_comment.opened
    when:
      payload:
        issue.body:
          matches: /^@probot assign @(\w+)$/
    then:
      assign: {{ matches[0] }}
  - on: issue_comment.opened
    when:
      payload:
        issue.body:
          matches: /^@probot label @(\w+)$/
    then:
      label: {{ matches[0] }}

# Close issues that don't use the issue template
- on: issues.opened
  when:
    - payload:
        issue.body:
          not:
            contains: /### Prerequisites.*### Description.*### Steps to Reproduce.*### Versions/
  then:
    comment:
      from_file: .github/MISSING_ISSUE_TEMPLATE_AUTOREPLY.md
    label: insufficient-info
    close: true

`probot install` command

@sridharavinash suggested that it'd be nice to have probot install plugin-name, which will:

  • npm install --save probot-plugin-name
  • Add plugin-name to plugins in package.json

[Behavior] set expectations for response time

Acknowledging contributions in a timely matter and setting expectations for response is one of the most important things you can do to keep a contributor engaged. Based on recent activity, a bot should be able to let contributors know when they can expect to receive a response. This could maybe be added to autoresponder, or as a separate behavior.

Configuration:

  • message template - e.g. Thanks for contributing! Based on recent activity, expect a response in {{ time_to_response }}.

Examples:

  • Know of any projects that use a behavior like this?

Provide a way to utilize the `HTTPServer` instance used by probot

I'm looking at a use case where I want to make some kind of web panel for managing plugins, in my mind this would be exposed on localhost:3000/panel. To do this I need access to the internal HTTP server so I can add a new listener on a given path.

Not sure if this is in scope for ProBot but my overall goal is to provide another module probot-swarm which allows you to run multiple plugins in one instance and each plugin can expose settings which will be controlled by the web panel. So things like response messages can be configured easily without rebuilding the plugin source.

Probot won't start with bad private key name

Probot failed to start using the default private-key filename style from GitHub. Probot successfully started after renaming the key. See the before and after below:

Before (failing)

Jamies-MacBook-Pro-2:probot-freeze jbjonesjr$ npm start --private-key probot-freeze.2017-04-07.private-key.pem

> [email protected] start /Users/jbjonesjr/github/probot/probot-freeze
> probot run ./index.js "probot-freeze.2017-04-07.private-key.pem"

Missing GitHub Integration private key.
Use --private-key flag or set PRIVATE_KEY environment variable.

After (success)

Jamies-MacBook-Pro-2:probot-freeze jbjonesjr$ npm start --private-key private-key.pem

> [email protected] start /Users/jbjonesjr/github/probot/probot-freeze
> probot run ./index.js "private-key.pem"

Filters don't have access to the GitHub API

Having access to the GitHub API via the Context object is necessary to implement more advanced filters, specifically things like "is the last person who commented a member of the organization?" or "is the author of the issue or PR a member of the organization?"

Probably the best solution should be to pass the Context object as the only parameter. This way examples can easily be changed from:

on('issues.opened')
  .filter((event) => {
      return !event.issue.body.match(/### Steps to Reproduce/)
       || event.issue.body.includes('- [ ]')
    })
  .comment(contents('.github/MISSING_ISSUE_TEMPLATE_AUTOREPLY.md'))
  .label('insufficient-info')
  .close();

to:

on('issues.opened')
  .filter(({event}) => {
      return !event.issue.body.match(/### Steps to Reproduce/)
       || event.issue.body.includes('- [ ]')
    })
  .comment(contents('.github/MISSING_ISSUE_TEMPLATE_AUTOREPLY.md'))
  .label('insufficient-info')
  .close();

[Testing] X-Hub-Signature does not match blob signature

Steps:

  1. Setup webhook for test repository.
  2. Forward calls to localhost:3000 using ngrok.
  3. Run script/server with valid GITHUB_TOKEN passed.
  4. Open a new issue and wait for webhook to handle.

Behavior:

localhost crashes with the following output:

> [email protected] start C:\Users\Serge\Projects\PRobot
> node server.js

Listening on http://localhost:3000
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: X-Hub-Signature does not match blob signature
    at hasError (C:\Users\Serge\Projects\PRobot\node_modules\github-webhook-handler\github-webhook-handler.js:46:17)
    at BufferList._callback (C:\Users\Serge\Projects\PRobot\node_modules\github-webhook-handler\github-webhook-handler.js:77:16)
    at BufferList.end (C:\Users\Serge\Projects\PRobot\node_modules\bl\bl.js:98:10)
    at IncomingMessage.onend (_stream_readable.js:511:10)
    at IncomingMessage.g (events.js:291:16)
    at emitNone (events.js:86:13)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

As I am new to the API in general I am likely missing an obvious step to setup my test environment.

Use pegjs-util

From pegjs-util:

This is a small utility class for the excellent PEG.js parser generator which wraps around PEG.js's central parse function and provides three distinct convenience features: Parser Tree Token Unrolling, Abstract Syntax Tree Node Generation and Cooked Error Reporting.

The grammar is currently doing token unrolling and AST generation manually right now, and I've already run into issues with error reporting for syntax errors.

[Behavior] mention-bot

mention-bot, which @mentions potential reviewers based on recent git history, works as a node module and should be relatively straight forward to turn it into a behavior.

Proper error handling

There is absolutely no error handling right now, and there are at least a few kinds of errors that are already common. Promises are heavily used already, so it should be pretty straight forward to hook in some kind of proper error handling.

Handle organization events

PRobot currently only dispatches webhook events that have a repository in the payload. There are several events (like organization, membership, and team) that aren't associated with an organization.

@Migaro and I talked briefly about this, and one option for events without a repository is to look for a repo named something like probot-scripts in the organization, and evaluate the configuration from that repository.

Use content from repository in action

Keeping the content for actions in the repository will make it easier for maintainers to evolve them, will make the bot config easier to read, and will make it easier for behaviors to be reused.

At the moment, comment is the only action that can use this, but there may eventually be others.

Here's an example of how this could work:

- then:
    comment:
      from_file: ".github/REPLY_TEMPLATE.md"

By default, ignore events triggered by the bot

@jonico made a great suggestion to default to ignoring events triggered by the bot to avoid the possibilities of infinite loops.

It would be the equivalent of adding a default filter on all workflows:

on('issues.opened')
  // ignore events from the demo installation
  .filter(event => event.payload.sender.login != 'probot-demo[bot]' )
  // or just ignore all bots
  .filter(event => event.payload.sender.type != 'Bot' )
  .close();

I haven't thought much about configuration, but here are a few options:

Configure

One option is to have a configure function for setting defaults, and allow the on listener to take those options for overriding on specific workflows:

configure({ignoreOwnEvents: false});

// Uses default configuration
on('issue_comment.create').close();

// Override default configuration
on('issue_comment.create', {ignoreOwnEvents: true}).close();

Middleware

Another approach could be like "middleware":

use(filter.ignoreOwnEvents);

// Default, which 
on('issue_comment.create').close();

// Disable middleware for a specific workflow
on('issue_comment.create', {"filter.ignoreOwnEvents": false}).

Create Laws of Probotics

Whether this is a list of best practices or code that enforces certain rules in probot plugins, we need to have things in place to prevent things like this from happening:

c6-kepsvsaacodi

Use something besides "@" for accessing payload values

Currently @ is used to access payload values:

if @pull_request.title contains "WIP"

Since @ is used for @mentions on GitHub, I imagine there will be use cases later on where the grammar should handle user and team mentions.

  • if $pull_request.title contains "WIP"
  • if {{pull_request.title}} contains "WIP" - This is ugly, but mustache syntax can already be used in string templates, so consistency might be nice.
  • ???

Add "not" operator

I punted on this in #46 because I couldn't decide on syntax. Hera are a few options:

  1. unary operator: not(@issue.body contains "- [ ]")
  2. not prefix for each existing operator: @issue.body does not contain "foo", @sender.login is not "bkeepers", @issue.body does not match "regex"
  3. other ideas?

Autodiscover plugins

When deploying multiple plugins in one instance, it might be nice to just auto-discover plugins from node modules.

One idea for how this would work would be to find any plugins with the keyword probot-plugin in their package.json.

This could make #97 easier, or negate the need for it entirely.

private key pulled from env expects a string

I'm not sure if this is a bug or if it is expected behavior.

If you set PRIVATE_KEY in your environment, it had better be the key itself instead of the path to the key file, or SSL will bonk:

(node:44369) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: error:0906D06C:PEM routines:PEM_read_bio:no start line

Timers and scheduled tasks

Some of the most important automation is not triggered by activity, but it is inactivity. This bot should have a way to do work on regular intervals or at some predetermined time in the future.

Timers

These would be behaviors that run at regular intervals and do regular maintenance. The only difference between these and the existing behaviors is that they're triggered by a timer and not a an action.

Examples:

  • Bump inactive threads
  • Close stale issues and pull requests
  • Create a release

Scheduled actions

These are one-off actions that just need to happen at some predetermined time in the future.

Examples:

  • Temporarily ban bad actors and automatically un-ban them after some interval
  • Miscellaneous reminders, like "review this after v2.1 is out"

  • Figure out config syntax for timers
  • Figure out how scheduled actions are triggered (hubot-like mentions in a comment? e.g. @probot remind me to check this out in 3 weeks
  • Figure out persistence for scheduled actions

Know of any prior art in bots that have good patterns for these?

`include` and `contents` fails when used in another repository

include and contents currently default to the repository that the event was triggered on, not the repository that the configuration was loaded from.

Given this config in a repo called this/repo:

include("other/repo:config.js");

And config.js in other/repo contains:

include('issue-triage.js');
on("issues.opened").comment(contents(".github/ISSUE_REPLY_TEMPLATE.md"));

This should look for issue-triage.js and .github/ISSUE_REPLY_TEMPLATE.md in other/repo, but both currently look in this/repo. include and contents should be relative to the repository they are being loaded from, not the repo that the event was triggered on.

Figure out a better configuration syntax

The configuration syntax is pretty ugly. It'll work for some early prototyping, but it would be great to come up with something better.

A real grammer

Some kind of real grammar could be interesting. For example here's what we have now:

behaviors:
  # Auto-respond to new issues and pull requests
  - on:
      - issues.opened
      - pull_request.opened
    then:
      comment: "Thanks for your contribution! Expect a reply within 48 hours."
      label: triage

  # Auto-close new pull requests
  - on: pull_request.opened
    then:
      comment: "Sorry @{{ user.login }}, pull requests are not accepted on this repository."
      close: true

  # Perform actions based on content of comments
  - on: issue_comment.opened
    when:
      payload:
        issue.body:
          matches: /^@probot assign @(\w+)$/
    then:
      assign: {{ matches[0] }}
  - on: issue_comment.opened
    when:
      payload:
        issue.body:
          matches: /^@probot label @(\w+)$/
    then:
      label: {{ matches[0] }}

would become:

on issues.opened
then comment("Thanks for your contribution! Expect a reply within 48 hours.")
and label("triage");

on pull_request.opened 
then comment("Sorry @{{ user.login }}, pull requests are not accepted on this repository.")
and close;

on issue_comment.created
when comment.body matches(/^@probot assign @(\w+)$/)
then assign(matches[0])

on issue_comment.created
when comment.body matches(/^@probot label @(\w+)$/)
then label(matches[0])

I have no idea how it would work in practice though.

How secure is Node's vm for running untrusted code?

Thanks to @paulcbetts' suggestion and @mcolyer's work, PRobot is now configured via JavaScript. Before investing too much in this direction, I'd like to gain confidence that this approach can safely run un-trusted scripts.

For background on this project: this is a bot that anyone can install on their repository. It will read the .probot.js file in the repository to configure workflows that trigger in response to webhooks. Those workflow include actions on the repository, such as commenting, managing labels and assignees, or eventually anythign you can do through the GitHub API.

The current implementation uses Node's vm API to create a new context. At the moment, the sandbox only exposes an on method, which creates a new Workflow. The functions on workflow mostly just mutate data, which is used afterward to determinee behavior.

A few questions to start:

  • Is there any way for code executed into the new context to access code/secrets/anything from the calling context without it being passed in?
  • Is there a better/safer way to accomplish this? Should we look into separate processes that use RPC?

cc @mcolyer @paulcbetts @zeke @nathansobo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.