├── .gitattributes ├── .gitignore ├── .verb.md ├── lib ├── handlers │ ├── issues │ │ ├── success.js │ │ ├── error.js │ │ ├── config.js │ │ ├── render.js │ │ ├── post-comment.js │ │ └── index.js │ └── index.js └── utils.js ├── .editorconfig ├── templates └── response.hbs ├── .travis.yml ├── examples └── express.js ├── LICENSE ├── package.json ├── index.js ├── test ├── test.js └── fixtures │ ├── payload-opened.json │ ├── payload-created.json │ └── payload-opened-long.json └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.sublime-* 3 | _gh_pages 4 | bower_components 5 | node_modules 6 | npm-debug.log 7 | actual 8 | test/actual 9 | temp 10 | tmp 11 | TODO.md 12 | vendor 13 | .idea 14 | benchmark 15 | coverage 16 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | ```js 4 | var AssembleBot = require('{%= name %}'); 5 | ``` 6 | 7 | ## API 8 | {%= apidocs("index.js") %} 9 | 10 | ## Handlers 11 | 12 | This bot implements the following github webhook event handlers: 13 | 14 | {%= apidocs("./src/handlers/issues.js") %} 15 | -------------------------------------------------------------------------------- /lib/handlers/issues/success.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function error(cb, data) { 11 | return cb(null, data); 12 | }; 13 | -------------------------------------------------------------------------------- /lib/handlers/issues/error.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function error(cb, err) { 11 | if (typeof err === 'string') { 12 | err = new Error(err); 13 | } 14 | cb(err); 15 | }; 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = false 15 | 16 | [{,test/}{actual,fixtures}/**] 17 | trim_trailing_whitespace = false 18 | insert_final_newline = false 19 | 20 | [templates/**] 21 | trim_trailing_whitespace = false 22 | insert_final_newline = false 23 | -------------------------------------------------------------------------------- /lib/handlers/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var handlers = require('export-dirs')(__dirname); 11 | 12 | module.exports = function(options) { 13 | return function plugin(bot) { 14 | for(var key in handlers) { 15 | if (key === '_') continue; 16 | var handler = handlers[key]; 17 | handler(bot, options); 18 | } 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /lib/handlers/issues/config.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | // var GithubContent = require('github-content'); 11 | 12 | /** 13 | * Pull down the config from github. 14 | */ 15 | 16 | module.exports = function config(payload, opts) { 17 | return function(cb) { 18 | cb(null, 'response'); 19 | 20 | // var client = new GithubContent(opts); 21 | // client.file('templates/' + filename, function(err, file) { 22 | // if (err) return cb(err); 23 | // cb(null, file.contents); 24 | // }); 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /templates/response.hbs: -------------------------------------------------------------------------------- 1 | 2 | @{{issue.user.login}} Thanks for the issue! If you're reporting a bug, please be sure to include: 3 | 4 | - The version of `assemble` you are using. 5 | - Your assemblefile.js (This can be in a gist) 6 | - The commandline output. (Screenshot or gist is fine) 7 | - What you expected to happen instead. 8 | 9 | {{#is repository.name "assemble"}} 10 | If your issue is related to one of the following, please open an issue there: 11 | {{#each ../others}} 12 | - [{{name}}]({{issue repo data}}) {{description}} 13 | {{/each}} 14 | {{/is}} 15 | 16 | If this is an implementation or usage-related question, please move the question to [stackoverflow](http://stackoverflow.com/questions/ask) and link back to this issue. 17 | -------------------------------------------------------------------------------- /lib/handlers/issues/render.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var path = require('path'); 11 | 12 | module.exports = function(app, data) { 13 | app.create('templates'); 14 | app.templates([path.join(__dirname, '../../..', 'templates', '*.hbs')]); 15 | 16 | return function(name, cb) { 17 | var tmpl = app.templates.getView(name); 18 | if (!tmpl) { 19 | return cb(new Error('Cannot find template "' + name + '"')); 20 | } 21 | 22 | tmpl.render(data, function(err, results) { 23 | if (err) return cb(err); 24 | cb(null, results.content); 25 | }); 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '0.10' 5 | - '0.12' 6 | - '4.0' 7 | - stable 8 | matrix: 9 | fast_finish: true 10 | allow_failures: 11 | - node_js: '0.10' 12 | - node_js: '0.12' 13 | env: 14 | global: 15 | secure: dDg6K9sizJ1yTYHwAI7I7j1JZpJi04Ep5NNCZ5aDARGT51P5VKHC2HGSusBbg5H8jw7DTSzYf4vJj6i7ybVRjesKKydm5shR6Us8BzoY9GQdYb9bzgxv3OLIthGytDW1CJ7HmwfH03/gnjZ048zrlJG2cXPtfqaLaTvOiFX1WLXPnO9frxVkBUrEuwICuzUaf+dDtU6O/v6VWvtr2xC8XidDJ/bbNkkvJyIg9L5mFvKlrCDQ27Pi02kPuq1dgryHka/gT6j2NeUoP80K92pNnpvOfgzmfeQNmP6+L2UVIckyYbDOvlarTVDw6JWv5qb6goVXgM3Jd1tON7M8gQj9rLh8I5iWveCPDpa7ILlhiHP2fzYhJQ4G8hBzGcaxqkS2RZjqmpxmwrRsDhkuhafEmteUO9GVS2BYNihvaBdjp9y570kalKb9DHT5dKCtCpg3JGmdSz/z1hn3Vyg5iwtLQrLZ5nzZGucECt3KgPOsHTKh+U/gKa0lvvunD8p/DqYnCyQwNg5grEOkMEkHp5rVLhyVwuEFBlLq8OTiomRdHyEQ9gtQlVa3QeYHxDKw22Vs4BGEmbpgdL4Gt8TecxK82Zwr09vtHbVsVgVSZiJ+HEEQVch+2rFF3JHwnyb+B/fXu+VzBZS40ouXOFsz7f/+y+NsPXTDzKUEsmS+KOIKaN8= 16 | -------------------------------------------------------------------------------- /lib/handlers/issues/post-comment.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | var utils = require('../../utils'); 10 | 11 | module.exports = function(token, opts) { 12 | return function(body, cb) { 13 | var github = new utils.Github({token: token}); 14 | opts.body = body; 15 | github.post('/repos/:owner/:repo/issues/:number/comments', opts, function(err, data, res) { 16 | if (err) { 17 | err.code = 500; 18 | return cb(err); 19 | } 20 | if (res.statusCode < 200 || res.statusCode >= 300) { 21 | err = new Error(res.statusMessage); 22 | err.code = +res.statusCode; 23 | return cb(err); 24 | } 25 | 26 | cb(null, { 27 | status: 'success', 28 | code: res.statusCode, 29 | message: res.statusMessage 30 | }); 31 | }); 32 | }; 33 | }; 34 | -------------------------------------------------------------------------------- /examples/express.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var body = require('body-parser'); 4 | var express = require('express'); 5 | var middleware = require('githubbot-connect'); 6 | var AssembleBot = require('../'); 7 | 8 | /** 9 | * Create a new express app and use the body-parser middleware 10 | */ 11 | 12 | var app = express(); 13 | app.use(body.json()); 14 | 15 | /** 16 | * Create a new bot instance with a github token 17 | */ 18 | 19 | var bot = new AssembleBot({GITHUB_TOKEN: 'xxxxxxxxxxxxxxxx'}); 20 | 21 | /** 22 | * Use the `githubbot-connect` plugin to add a `middleware` method to the `bot` instance. 23 | */ 24 | 25 | bot.use(middleware({send: true})); 26 | 27 | /** 28 | * Create a bot middleware at the `webhook` endpoint in the express app. 29 | * This middleware will forward requests to the correct payload handler registered 30 | * on the `bot` instance. 31 | */ 32 | 33 | app.post('/webhook', bot.middleware({send: true})); 34 | 35 | /** 36 | * Start listening for requests. 37 | */ 38 | 39 | app.listen(process.env.PORT || 8080, function() { 40 | console.log('Node app is running on port', process.env.PORT || 8080); 41 | }); 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015, Brian Woodward. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var utils = require('lazy-cache')(require); 8 | 9 | /** 10 | * Temporarily re-assign `require` to trick browserify and 11 | * webpack into reconizing lazy dependencies. 12 | * 13 | * This tiny bit of ugliness has the huge dual advantage of 14 | * only loading modules that are actually called at some 15 | * point in the lifecycle of the application, whilst also 16 | * allowing browserify and webpack to find modules that 17 | * are depended on but never actually called. 18 | */ 19 | 20 | var fn = require; 21 | require = utils; 22 | 23 | /** 24 | * Lazily required module dependencies 25 | */ 26 | 27 | require('assemble-core', 'Assemble'); 28 | require('assemble-loader', 'loader'); 29 | require('async'); 30 | require('engine-handlebars', 'engine'); 31 | require('github-base', 'Github'); 32 | require('handlebars-helpers', 'helpers'); 33 | require('helper-issue', 'issue'); 34 | 35 | /** 36 | * Restore `require` 37 | */ 38 | 39 | require = fn; 40 | 41 | utils.truncate = function(str, len) { 42 | if (str.length > len) { 43 | return str.substr(0, len); 44 | } 45 | return str; 46 | }; 47 | 48 | /** 49 | * Expose `utils` modules 50 | */ 51 | 52 | module.exports = utils; 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "assemblebot", 3 | "description": "Bot for responding to github issues opened on assemble repositories.", 4 | "version": "0.2.4", 5 | "homepage": "https://github.com/assemble/assemblebot", 6 | "author": "Brian Woodward (https://github.com/doowb)", 7 | "repository": "assemble/assemblebot", 8 | "bugs": { 9 | "url": "https://github.com/assemble/assemblebot/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "lib/", 15 | "templates/" 16 | ], 17 | "main": "index.js", 18 | "engines": { 19 | "node": ">=0.10.0" 20 | }, 21 | "scripts": { 22 | "test": "mocha" 23 | }, 24 | "dependencies": { 25 | "assemble-core": "^0.14.3", 26 | "assemble-loader": "^0.3.0", 27 | "async": "^1.5.2", 28 | "engine-handlebars": "^0.8.0", 29 | "export-dirs": "^0.2.4", 30 | "github-base": "^0.4.1", 31 | "githubbot": "^0.1.2", 32 | "handlebars-helpers": "github:assemble/handlebars-helpers#dev", 33 | "helper-issue": "^0.3.0", 34 | "lazy-cache": "^1.0.3" 35 | }, 36 | "devDependencies": { 37 | "body-parser": "^1.14.2", 38 | "express": "^4.13.4", 39 | "githubbot-connect": "^0.1.0", 40 | "gulp-format-md": "^0.1.7", 41 | "mocha": "^2.3.4" 42 | }, 43 | "keywords": [], 44 | "verb": { 45 | "toc": false, 46 | "layout": "default", 47 | "tasks": [ 48 | "readme" 49 | ], 50 | "plugins": [ 51 | "gulp-format-md" 52 | ], 53 | "related": { 54 | "list": [ 55 | "assemble", 56 | "githubbot", 57 | "base-bot" 58 | ] 59 | }, 60 | "reflinks": [ 61 | "assemble-core", 62 | "verb" 63 | ], 64 | "lint": { 65 | "reflinks": true 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var GithubBot = require('githubbot'); 11 | var handlers = require('./lib/handlers'); 12 | var utils = require('./lib/utils'); 13 | 14 | /** 15 | * Main class for creating a new AssembleBot instance. This bot extends [GithubBot][githubbot] 16 | * and creates an instance of [assemble-core][] that can be used to render response templates. 17 | * 18 | * ```js 19 | * var bot = new AssembleBot({GITHUB_TOKEN: 'xxxxxxxxxxxxxxx'}); 20 | * ``` 21 | * 22 | * @param {Object} `options` Options to use to configure the bot. 23 | * @param {String} `options.GITHUB_TOKEN` Personal github token the bot uses to post to github issues. 24 | * @api public 25 | */ 26 | 27 | function AssembleBot(options) { 28 | if (!(this instanceof AssembleBot)) { 29 | return new AssembleBot(options); 30 | } 31 | GithubBot.call(this, options); 32 | this.initAssemble(); 33 | this.use(handlers(this.options)); 34 | } 35 | 36 | /** 37 | * Extend `GithubBot` 38 | */ 39 | 40 | GithubBot.extend(AssembleBot); 41 | 42 | /** 43 | * Create an instance of [assemble-core] with some configured defaults: 44 | * 45 | * - uses [assemble-loader] 46 | * - uses [engine-handlebars] for ".hbs" files. 47 | * - uses [handlebars-helpers] 48 | * - uses [helper-issue] 49 | */ 50 | 51 | AssembleBot.prototype.initAssemble = function() { 52 | this.define('assemble', new utils.Assemble()); 53 | this.assemble.use(utils.loader()); 54 | this.assemble.engine('hbs', utils.engine); 55 | this.assemble.helpers(utils.helpers()); 56 | this.assemble.helper('issue', utils.issue); 57 | }; 58 | 59 | /** 60 | * Exposes `AssembleBot` 61 | */ 62 | 63 | module.exports = AssembleBot; 64 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var assert = require('assert'); 11 | var AssembleBot = require('../'); 12 | 13 | var config = {}; 14 | try { 15 | config = require('../tmp/config.js'); 16 | } catch(err) { 17 | config.GITHUB_TOKEN = process.env.GITHUB_TOKEN; 18 | } 19 | 20 | if (!config.GITHUB_TOKEN) { 21 | throw new Error('Tests require a GITHUB_TOKEN to either be in "' + process.cwd() + '/tmp/config.js" or on process.env.GITHUB_TOKEN'); 22 | } 23 | 24 | var payloads = { 25 | created: require('./fixtures/payload-created.json'), 26 | opened: require('./fixtures/payload-opened.json'), 27 | long: require('./fixtures/payload-opened-long.json') 28 | }; 29 | 30 | /* deps: mocha */ 31 | describe('assemblebot', function() { 32 | var bot = new AssembleBot(config); 33 | 34 | it('should register an issues handler', function() { 35 | assert(bot._callbacks['$issues'].length > 0); 36 | }); 37 | 38 | it('should handle an opened issues payload', function(done) { 39 | bot.handleIssues(payloads.opened, function(err, results) { 40 | if (err) return done(err); 41 | assert.deepEqual(results, { 42 | status: 'success', 43 | code: 201, 44 | message: 'Created' 45 | }); 46 | done(); 47 | }); 48 | }); 49 | 50 | it('should handle an opened issues payload with a long body', function(done) { 51 | bot.handleIssues(payloads.long, function(err, results) { 52 | if (err) return done(err); 53 | assert.deepEqual(results, { 54 | status: 'success', 55 | code: 201, 56 | message: 'Created' 57 | }); 58 | done(); 59 | }); 60 | }); 61 | 62 | it('should ignore a created issue payload', function(done) { 63 | bot.handleIssues(payloads.created, function(err, results) { 64 | if (err) return done(err); 65 | assert.deepEqual(results, { 66 | code: 200, 67 | status: 'success', 68 | action: 'created', 69 | message: 'No action taken' 70 | }); 71 | done(); 72 | }); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # assemblebot [![NPM version](https://img.shields.io/npm/v/assemblebot.svg)](https://www.npmjs.com/package/assemblebot) [![Build Status](https://img.shields.io/travis/assemble/assemblebot.svg)](https://travis-ci.org/assemble/assemblebot) 2 | 3 | > Bot for responding to github issues opened on assemble repositories. 4 | 5 | ## Install 6 | 7 | Install with [npm](https://www.npmjs.com/): 8 | 9 | ```sh 10 | $ npm install assemblebot --save 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```js 16 | var AssembleBot = require('assemblebot'); 17 | ``` 18 | 19 | ## API 20 | 21 | ### [AssembleBot](index.js#L27) 22 | 23 | Main class for creating a new AssembleBot instance. This bot extends [GithubBot](https://github.com/doowb/githubbot) and creates an instance of [assemble-core](https://github.com/assemble/assemble-core) that can be used to render response templates. 24 | 25 | **Params** 26 | 27 | * `options` **{Object}**: Options to use to configure the bot. 28 | * `options.GITHUB_TOKEN` **{String}**: Personal github token the bot uses to post to github issues. 29 | 30 | **Example** 31 | 32 | ```js 33 | var bot = new AssembleBot({GITHUB_TOKEN: 'xxxxxxxxxxxxxxx'}); 34 | ``` 35 | 36 | ## Handlers 37 | 38 | This bot implements the following github webhook event handlers: 39 | 40 | ## Related projects 41 | 42 | * [assemble](https://www.npmjs.com/package/assemble): Assemble is a powerful, extendable and easy to use static site generator for node.js. Used… [more](https://www.npmjs.com/package/assemble) | [homepage](https://github.com/assemble/assemble) 43 | * [base-bot](https://www.npmjs.com/package/base-bot): Simple bot that knows how to handle events when told too. Use base bot to… [more](https://www.npmjs.com/package/base-bot) | [homepage](https://github.com/doowb/base-bot) 44 | * [githubbot](https://www.npmjs.com/package/githubbot): Starting point for registering event handlers and handling payloads coming from github webhooks. Allows usage… [more](https://www.npmjs.com/package/githubbot) | [homepage](https://github.com/doowb/githubbot) 45 | 46 | ## Contributing 47 | 48 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/doowb/assemblebot/issues/new). 49 | 50 | ## Building docs 51 | 52 | Generate readme and API documentation with [verb][]: 53 | 54 | ```sh 55 | $ npm install verb && npm run docs 56 | ``` 57 | 58 | Or, if [verb][] is installed globally: 59 | 60 | ```sh 61 | $ verb 62 | ``` 63 | 64 | ## Running tests 65 | 66 | Install dev dependencies: 67 | 68 | ```sh 69 | $ npm install -d && npm test 70 | ``` 71 | 72 | ## Author 73 | 74 | **Brian Woodward** 75 | 76 | * [github/doowb](https://github.com/doowb) 77 | * [twitter/doowb](http://twitter.com/doowb) 78 | 79 | ## License 80 | 81 | Copyright © 2016 [Brian Woodward](https://github.com/doowb) 82 | Released under the [MIT license](https://github.com/assemble/assemblebot/blob/master/LICENSE). 83 | 84 | *** 85 | 86 | _This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on March 16, 2016._ -------------------------------------------------------------------------------- /lib/handlers/issues/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * assemblebot 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var post = require('./post-comment'); 11 | var error = require('./error'); 12 | var config = require('./config'); 13 | var render = require('./render'); 14 | var success = require('./success'); 15 | 16 | /** 17 | * Handles responding to newely open github issues. 18 | * 19 | * Will post a comment on a newely open github issue as the configured github user. 20 | * Uses a template that can be rendered with the issue payload providing more context and a richer response. 21 | * 22 | * See the github webhook [issues event](https://developer.github.com/v3/activity/events/types/#issuesevent) for specification of payload object. 23 | * 24 | * ```js 25 | * bot.handleIssues(payload, function(err, results) { 26 | * if (err) return console.error(err); 27 | * console.log(results); 28 | * }); 29 | * ``` 30 | * 31 | * @api public 32 | * @name issues 33 | */ 34 | 35 | var utils = require('../../utils'); 36 | 37 | module.exports = function(bot, options) { 38 | options = options || {}; 39 | 40 | bot.onIssues(function(payload, cb) { 41 | if (payload.action !== 'opened') { 42 | return success(cb, { 43 | code: 200, 44 | status: 'success', 45 | action: payload.action, 46 | message: 'No action taken' 47 | }); 48 | } 49 | 50 | if (!options.GITHUB_TOKEN) { 51 | return error(res, 'Invalid GITHUB_TOKEN'); 52 | } 53 | 54 | var token = options.GITHUB_TOKEN; 55 | 56 | // options to use when pulling down files from this repo. 57 | var repoOpts = { 58 | token: token, 59 | owner: 'assemble', 60 | repo: 'assemblebot' 61 | }; 62 | 63 | // options used to post comments 64 | var commentOpts = { 65 | owner: payload.repository.owner.login, 66 | repo: payload.repository.name, 67 | number: payload.issue.number 68 | }; 69 | 70 | var data = { 71 | title: utils.truncate(payload.issue.title, 50), 72 | body: utils.truncate(payload.issue.body, 100) 73 | }; 74 | 75 | // sets up common libraries that people ask questions about on the main `assemble` repo. 76 | payload.others = [ 77 | { 78 | name: 'grunt-assemble', 79 | repo: 'assemble/grunt-assemble', 80 | description: 'Issues with using assemble in grunt or the grunt-assemble library.', 81 | data: {} 82 | }, 83 | { 84 | name: 'handlebars-helpers', 85 | repo: 'assemble/handlebars-helpers', 86 | description: 'Issues with using handlebars helpers from the handlebars-helpers library.', 87 | data: {} 88 | } 89 | ]; 90 | 91 | utils.async.waterfall([ 92 | config(payload, repoOpts), 93 | render(bot.assemble, payload), 94 | post(token, commentOpts), 95 | ], function(err, results) { 96 | if (err) return error(cb, err); 97 | success(cb, results); 98 | }); 99 | }); 100 | }; 101 | -------------------------------------------------------------------------------- /test/fixtures/payload-opened.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "opened", 3 | "issue": { 4 | "url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2", 5 | "labels_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/labels{/name}", 6 | "comments_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/comments", 7 | "events_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/events", 8 | "html_url": "https://github.com/assemblebot/issue-tests/issues/2", 9 | "id": 123552350, 10 | "number": 2, 11 | "title": "another", 12 | "user": { 13 | "login": "assemblebot", 14 | "id": 16341238, 15 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 16 | "gravatar_id": "", 17 | "url": "https://api.github.com/users/assemblebot", 18 | "html_url": "https://github.com/assemblebot", 19 | "followers_url": "https://api.github.com/users/assemblebot/followers", 20 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 21 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 22 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 23 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 24 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 25 | "repos_url": "https://api.github.com/users/assemblebot/repos", 26 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 27 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 28 | "type": "User", 29 | "site_admin": false 30 | }, 31 | "labels": [ 32 | 33 | ], 34 | "state": "open", 35 | "locked": false, 36 | "assignee": null, 37 | "milestone": null, 38 | "comments": 0, 39 | "created_at": "2015-12-22T20:39:29Z", 40 | "updated_at": "2015-12-22T20:39:29Z", 41 | "closed_at": null, 42 | "body": "one" 43 | }, 44 | "repository": { 45 | "id": 48202132, 46 | "name": "issue-tests", 47 | "full_name": "assemblebot/issue-tests", 48 | "owner": { 49 | "login": "assemblebot", 50 | "id": 16341238, 51 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 52 | "gravatar_id": "", 53 | "url": "https://api.github.com/users/assemblebot", 54 | "html_url": "https://github.com/assemblebot", 55 | "followers_url": "https://api.github.com/users/assemblebot/followers", 56 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 57 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 58 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 59 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 60 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 61 | "repos_url": "https://api.github.com/users/assemblebot/repos", 62 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 63 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 64 | "type": "User", 65 | "site_admin": false 66 | }, 67 | "private": false, 68 | "html_url": "https://github.com/assemblebot/issue-tests", 69 | "description": "Test the issues bot.", 70 | "fork": false, 71 | "url": "https://api.github.com/repos/assemblebot/issue-tests", 72 | "forks_url": "https://api.github.com/repos/assemblebot/issue-tests/forks", 73 | "keys_url": "https://api.github.com/repos/assemblebot/issue-tests/keys{/key_id}", 74 | "collaborators_url": "https://api.github.com/repos/assemblebot/issue-tests/collaborators{/collaborator}", 75 | "teams_url": "https://api.github.com/repos/assemblebot/issue-tests/teams", 76 | "hooks_url": "https://api.github.com/repos/assemblebot/issue-tests/hooks", 77 | "issue_events_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/events{/number}", 78 | "events_url": "https://api.github.com/repos/assemblebot/issue-tests/events", 79 | "assignees_url": "https://api.github.com/repos/assemblebot/issue-tests/assignees{/user}", 80 | "branches_url": "https://api.github.com/repos/assemblebot/issue-tests/branches{/branch}", 81 | "tags_url": "https://api.github.com/repos/assemblebot/issue-tests/tags", 82 | "blobs_url": "https://api.github.com/repos/assemblebot/issue-tests/git/blobs{/sha}", 83 | "git_tags_url": "https://api.github.com/repos/assemblebot/issue-tests/git/tags{/sha}", 84 | "git_refs_url": "https://api.github.com/repos/assemblebot/issue-tests/git/refs{/sha}", 85 | "trees_url": "https://api.github.com/repos/assemblebot/issue-tests/git/trees{/sha}", 86 | "statuses_url": "https://api.github.com/repos/assemblebot/issue-tests/statuses/{sha}", 87 | "languages_url": "https://api.github.com/repos/assemblebot/issue-tests/languages", 88 | "stargazers_url": "https://api.github.com/repos/assemblebot/issue-tests/stargazers", 89 | "contributors_url": "https://api.github.com/repos/assemblebot/issue-tests/contributors", 90 | "subscribers_url": "https://api.github.com/repos/assemblebot/issue-tests/subscribers", 91 | "subscription_url": "https://api.github.com/repos/assemblebot/issue-tests/subscription", 92 | "commits_url": "https://api.github.com/repos/assemblebot/issue-tests/commits{/sha}", 93 | "git_commits_url": "https://api.github.com/repos/assemblebot/issue-tests/git/commits{/sha}", 94 | "comments_url": "https://api.github.com/repos/assemblebot/issue-tests/comments{/number}", 95 | "issue_comment_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/comments{/number}", 96 | "contents_url": "https://api.github.com/repos/assemblebot/issue-tests/contents/{+path}", 97 | "compare_url": "https://api.github.com/repos/assemblebot/issue-tests/compare/{base}...{head}", 98 | "merges_url": "https://api.github.com/repos/assemblebot/issue-tests/merges", 99 | "archive_url": "https://api.github.com/repos/assemblebot/issue-tests/{archive_format}{/ref}", 100 | "downloads_url": "https://api.github.com/repos/assemblebot/issue-tests/downloads", 101 | "issues_url": "https://api.github.com/repos/assemblebot/issue-tests/issues{/number}", 102 | "pulls_url": "https://api.github.com/repos/assemblebot/issue-tests/pulls{/number}", 103 | "milestones_url": "https://api.github.com/repos/assemblebot/issue-tests/milestones{/number}", 104 | "notifications_url": "https://api.github.com/repos/assemblebot/issue-tests/notifications{?since,all,participating}", 105 | "labels_url": "https://api.github.com/repos/assemblebot/issue-tests/labels{/name}", 106 | "releases_url": "https://api.github.com/repos/assemblebot/issue-tests/releases{/id}", 107 | "created_at": "2015-12-17T22:41:27Z", 108 | "updated_at": "2015-12-17T22:41:27Z", 109 | "pushed_at": "2015-12-17T22:41:27Z", 110 | "git_url": "git://github.com/assemblebot/issue-tests.git", 111 | "ssh_url": "git@github.com:assemblebot/issue-tests.git", 112 | "clone_url": "https://github.com/assemblebot/issue-tests.git", 113 | "svn_url": "https://github.com/assemblebot/issue-tests", 114 | "homepage": null, 115 | "size": 0, 116 | "stargazers_count": 0, 117 | "watchers_count": 0, 118 | "language": null, 119 | "has_issues": true, 120 | "has_downloads": true, 121 | "has_wiki": true, 122 | "has_pages": false, 123 | "forks_count": 0, 124 | "mirror_url": null, 125 | "open_issues_count": 2, 126 | "forks": 0, 127 | "open_issues": 2, 128 | "watchers": 0, 129 | "default_branch": "master" 130 | }, 131 | "sender": { 132 | "login": "assemblebot", 133 | "id": 16341238, 134 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 135 | "gravatar_id": "", 136 | "url": "https://api.github.com/users/assemblebot", 137 | "html_url": "https://github.com/assemblebot", 138 | "followers_url": "https://api.github.com/users/assemblebot/followers", 139 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 140 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 141 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 142 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 143 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 144 | "repos_url": "https://api.github.com/users/assemblebot/repos", 145 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 146 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 147 | "type": "User", 148 | "site_admin": false 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /test/fixtures/payload-created.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "created", 3 | "issue": { 4 | "url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2", 5 | "labels_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/labels{/name}", 6 | "comments_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/comments", 7 | "events_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/events", 8 | "html_url": "https://github.com/assemblebot/issue-tests/issues/2", 9 | "id": 123552350, 10 | "number": 2, 11 | "title": "another", 12 | "user": { 13 | "login": "assemblebot", 14 | "id": 16341238, 15 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 16 | "gravatar_id": "", 17 | "url": "https://api.github.com/users/assemblebot", 18 | "html_url": "https://github.com/assemblebot", 19 | "followers_url": "https://api.github.com/users/assemblebot/followers", 20 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 21 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 22 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 23 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 24 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 25 | "repos_url": "https://api.github.com/users/assemblebot/repos", 26 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 27 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 28 | "type": "User", 29 | "site_admin": false 30 | }, 31 | "labels": [ 32 | 33 | ], 34 | "state": "open", 35 | "locked": false, 36 | "assignee": null, 37 | "milestone": null, 38 | "comments": 1, 39 | "created_at": "2015-12-22T20:39:29Z", 40 | "updated_at": "2015-12-22T20:39:30Z", 41 | "closed_at": null, 42 | "body": "one" 43 | }, 44 | "comment": { 45 | "url": "https://api.github.com/repos/assemblebot/issue-tests/issues/comments/166724454", 46 | "html_url": "https://github.com/assemblebot/issue-tests/issues/2#issuecomment-166724454", 47 | "issue_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2", 48 | "id": 166724454, 49 | "user": { 50 | "login": "assemblebot", 51 | "id": 16341238, 52 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 53 | "gravatar_id": "", 54 | "url": "https://api.github.com/users/assemblebot", 55 | "html_url": "https://github.com/assemblebot", 56 | "followers_url": "https://api.github.com/users/assemblebot/followers", 57 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 58 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 59 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 60 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 61 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 62 | "repos_url": "https://api.github.com/users/assemblebot/repos", 63 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 64 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 65 | "type": "User", 66 | "site_admin": false 67 | }, 68 | "created_at": "2015-12-22T20:39:30Z", 69 | "updated_at": "2015-12-22T20:39:30Z", 70 | "body": "\n@assemblebot Thanks for the issue! If you're reporting a bug, please be sure to include:\n\n- The version of `assemble` you are using.\n- Your assemblefile.js (This can be in a gist)\n- The commandline output. (Screenshot or gist is fine)\n- What you expected to happen instead.\n\n\n" 71 | }, 72 | "repository": { 73 | "id": 48202132, 74 | "name": "issue-tests", 75 | "full_name": "assemblebot/issue-tests", 76 | "owner": { 77 | "login": "assemblebot", 78 | "id": 16341238, 79 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 80 | "gravatar_id": "", 81 | "url": "https://api.github.com/users/assemblebot", 82 | "html_url": "https://github.com/assemblebot", 83 | "followers_url": "https://api.github.com/users/assemblebot/followers", 84 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 85 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 86 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 87 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 88 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 89 | "repos_url": "https://api.github.com/users/assemblebot/repos", 90 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 91 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 92 | "type": "User", 93 | "site_admin": false 94 | }, 95 | "private": false, 96 | "html_url": "https://github.com/assemblebot/issue-tests", 97 | "description": "Test the issues bot.", 98 | "fork": false, 99 | "url": "https://api.github.com/repos/assemblebot/issue-tests", 100 | "forks_url": "https://api.github.com/repos/assemblebot/issue-tests/forks", 101 | "keys_url": "https://api.github.com/repos/assemblebot/issue-tests/keys{/key_id}", 102 | "collaborators_url": "https://api.github.com/repos/assemblebot/issue-tests/collaborators{/collaborator}", 103 | "teams_url": "https://api.github.com/repos/assemblebot/issue-tests/teams", 104 | "hooks_url": "https://api.github.com/repos/assemblebot/issue-tests/hooks", 105 | "issue_events_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/events{/number}", 106 | "events_url": "https://api.github.com/repos/assemblebot/issue-tests/events", 107 | "assignees_url": "https://api.github.com/repos/assemblebot/issue-tests/assignees{/user}", 108 | "branches_url": "https://api.github.com/repos/assemblebot/issue-tests/branches{/branch}", 109 | "tags_url": "https://api.github.com/repos/assemblebot/issue-tests/tags", 110 | "blobs_url": "https://api.github.com/repos/assemblebot/issue-tests/git/blobs{/sha}", 111 | "git_tags_url": "https://api.github.com/repos/assemblebot/issue-tests/git/tags{/sha}", 112 | "git_refs_url": "https://api.github.com/repos/assemblebot/issue-tests/git/refs{/sha}", 113 | "trees_url": "https://api.github.com/repos/assemblebot/issue-tests/git/trees{/sha}", 114 | "statuses_url": "https://api.github.com/repos/assemblebot/issue-tests/statuses/{sha}", 115 | "languages_url": "https://api.github.com/repos/assemblebot/issue-tests/languages", 116 | "stargazers_url": "https://api.github.com/repos/assemblebot/issue-tests/stargazers", 117 | "contributors_url": "https://api.github.com/repos/assemblebot/issue-tests/contributors", 118 | "subscribers_url": "https://api.github.com/repos/assemblebot/issue-tests/subscribers", 119 | "subscription_url": "https://api.github.com/repos/assemblebot/issue-tests/subscription", 120 | "commits_url": "https://api.github.com/repos/assemblebot/issue-tests/commits{/sha}", 121 | "git_commits_url": "https://api.github.com/repos/assemblebot/issue-tests/git/commits{/sha}", 122 | "comments_url": "https://api.github.com/repos/assemblebot/issue-tests/comments{/number}", 123 | "issue_comment_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/comments{/number}", 124 | "contents_url": "https://api.github.com/repos/assemblebot/issue-tests/contents/{+path}", 125 | "compare_url": "https://api.github.com/repos/assemblebot/issue-tests/compare/{base}...{head}", 126 | "merges_url": "https://api.github.com/repos/assemblebot/issue-tests/merges", 127 | "archive_url": "https://api.github.com/repos/assemblebot/issue-tests/{archive_format}{/ref}", 128 | "downloads_url": "https://api.github.com/repos/assemblebot/issue-tests/downloads", 129 | "issues_url": "https://api.github.com/repos/assemblebot/issue-tests/issues{/number}", 130 | "pulls_url": "https://api.github.com/repos/assemblebot/issue-tests/pulls{/number}", 131 | "milestones_url": "https://api.github.com/repos/assemblebot/issue-tests/milestones{/number}", 132 | "notifications_url": "https://api.github.com/repos/assemblebot/issue-tests/notifications{?since,all,participating}", 133 | "labels_url": "https://api.github.com/repos/assemblebot/issue-tests/labels{/name}", 134 | "releases_url": "https://api.github.com/repos/assemblebot/issue-tests/releases{/id}", 135 | "created_at": "2015-12-17T22:41:27Z", 136 | "updated_at": "2015-12-17T22:41:27Z", 137 | "pushed_at": "2015-12-17T22:41:27Z", 138 | "git_url": "git://github.com/assemblebot/issue-tests.git", 139 | "ssh_url": "git@github.com:assemblebot/issue-tests.git", 140 | "clone_url": "https://github.com/assemblebot/issue-tests.git", 141 | "svn_url": "https://github.com/assemblebot/issue-tests", 142 | "homepage": null, 143 | "size": 0, 144 | "stargazers_count": 0, 145 | "watchers_count": 0, 146 | "language": null, 147 | "has_issues": true, 148 | "has_downloads": true, 149 | "has_wiki": true, 150 | "has_pages": false, 151 | "forks_count": 0, 152 | "mirror_url": null, 153 | "open_issues_count": 2, 154 | "forks": 0, 155 | "open_issues": 2, 156 | "watchers": 0, 157 | "default_branch": "master" 158 | }, 159 | "sender": { 160 | "login": "assemblebot", 161 | "id": 16341238, 162 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 163 | "gravatar_id": "", 164 | "url": "https://api.github.com/users/assemblebot", 165 | "html_url": "https://github.com/assemblebot", 166 | "followers_url": "https://api.github.com/users/assemblebot/followers", 167 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 168 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 169 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 170 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 171 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 172 | "repos_url": "https://api.github.com/users/assemblebot/repos", 173 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 174 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 175 | "type": "User", 176 | "site_admin": false 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /test/fixtures/payload-opened-long.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "opened", 3 | "issue": { 4 | "url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2", 5 | "labels_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/labels{/name}", 6 | "comments_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/comments", 7 | "events_url": "https://api.github.com/repos/assemblebot/issue-tests/issues/2/events", 8 | "html_url": "https://github.com/assemblebot/issue-tests/issues/2", 9 | "id": 123552350, 10 | "number": 2, 11 | "title": "StringReplaceGlobalRegExpWithFunction error ?", 12 | "user": { 13 | "login": "assemblebot", 14 | "id": 16341238, 15 | "avatar_url": "https://avatars.githubusercontent.com/u/16341238?v=3", 16 | "gravatar_id": "", 17 | "url": "https://api.github.com/users/assemblebot", 18 | "html_url": "https://github.com/assemblebot", 19 | "followers_url": "https://api.github.com/users/assemblebot/followers", 20 | "following_url": "https://api.github.com/users/assemblebot/following{/other_user}", 21 | "gists_url": "https://api.github.com/users/assemblebot/gists{/gist_id}", 22 | "starred_url": "https://api.github.com/users/assemblebot/starred{/owner}{/repo}", 23 | "subscriptions_url": "https://api.github.com/users/assemblebot/subscriptions", 24 | "organizations_url": "https://api.github.com/users/assemblebot/orgs", 25 | "repos_url": "https://api.github.com/users/assemblebot/repos", 26 | "events_url": "https://api.github.com/users/assemblebot/events{/privacy}", 27 | "received_events_url": "https://api.github.com/users/assemblebot/received_events", 28 | "type": "User", 29 | "site_admin": false 30 | }, 31 | "labels": [ 32 | 33 | ], 34 | "state": "open", 35 | "locked": false, 36 | "assignee": null, 37 | "milestone": null, 38 | "comments": 0, 39 | "created_at": "2015-12-22T20:39:29Z", 40 | "updated_at": "2015-12-22T20:39:29Z", 41 | "closed_at": null, 42 | "body": "I actually wanted to reproduce another issue in assemble 0.9.2, but came across this one.\r\nHave a very basic assemblefile.js (code can be found [here](https://github.com/stefanwalther/assemble-bug-parsing)):\r\n\r\n```js\r\n'use strict';\r\nvar assemble = require( 'assemble' );\r\nvar path = require( 'path' );\r\nvar extname = require( 'gulp-extname' );\r\n\r\nvar app = assemble();\r\n\r\napp.option( 'renameKey', function ( fp ) {\r\n\treturn path.basename( fp, path.extname( fp ) );\r\n} );\r\napp.option( 'layout', 'default' );\r\n\r\napp.task( 'init', function ( cb ) {\r\n\tapp.helper( 'markdown', require( 'helper-markdown' ) );\r\n\tapp.layouts( './src/layouts/**/*.hbs' );\r\n\tcb();\r\n} );\r\n\r\napp.task( 'default', ['init'], function () {\r\n\treturn app.pages.src( './content/**/*.{md,hbs}' )\r\n\t\t.pipe( app.renderFile() )\r\n\t\t.pipe( extname() )\r\n\t\t.pipe( app.dest( './.build' ) );\r\n} );\r\n\r\nmodule.exports = app;\r\n\r\n```\r\n\r\nWhen running `assemble` I get the following:\r\n- Operating system Mac OSX 10.11.3\r\n- Node.Js: 4.3.0\r\n\r\n```bash\r\n[18:45:45] cwd set to ~/git/_playground/assemble-bug-parsing\r\n[18:45:45] using assemblefile ~/git/_playground/assemble-bug-parsing/assemblefile.js\r\n[18:45:45] starting assemble \r\n[18:45:45] starting default \r\n[18:45:45] starting init \r\n[18:45:45] finished init 134.76ms \r\n\r\n<--- Last few GCs --->\r\n\r\n 1789 ms: Scavenge 1214.2 (1456.9) -> 1214.2 (1457.9) MB, 1.0 / 0 ms [allocation failure].\r\n 1790 ms: Scavenge 1215.2 (1457.9) -> 1215.2 (1457.9) MB, 0.3 / 0 ms [allocation failure].\r\n 1791 ms: Scavenge 1215.2 (1457.9) -> 1215.8 (1457.9) MB, 0.7 / 0 ms [allocation failure].\r\n 1823 ms: Mark-sweep 1215.8 (1457.9) -> 1215.8 (1457.9) MB, 32.7 / 0 ms [last resort gc].\r\n 1856 ms: Mark-sweep 1215.8 (1457.9) -> 1215.7 (1457.9) MB, 32.7 / 0 ms [last resort gc].\r\n\r\n\r\n<--- JS stacktrace --->\r\n\r\n==== JS stack trace =========================================\r\n\r\nSecurity context: 0x2097e87b4629 \r\n 1: StringReplaceGlobalRegExpWithFunction [native string.js:~291] [pc=0x362e52b0c5c8] (this=0x2334d181c5c9 ,A=0x2002ee39f991 \\n\\n\\n\\n\\n
\\n\\n\\x09{% body %}\\n\\n
\\n\\n\\n>,H=0x1a076c3fc789 ,O=0x1a076c3fc741