GitHub is a wonderful platform for organizing and collaborating on software development, and if your company uses it to full extent, consider yourself lucky. There are so many ways to integrate Hubot with GitHub, it deserves a separate chapter.
If you happen to work on an active GitHub repository, or belong to organization that does everything via GitHub, you should agree on a few things:
First thing you should do is to turn off email notifications. Forget all those filters, just use web notifications (look for a blue dot on top of the page), they are far better. And to get notified about things in real time without leaving junk in your inbox, we will use the power of Hubot. It’s way better to receive notifications about all those issues and pull requests in your chat, not in your mail.
You may think - hey, GitHub has hundreds of service integrations, and you can even propose your own in . And yes, when it comes to getting GitHub events to appear in your chat, sometimes it may fit your needs. For example, GitHub can post information about commits directly to Campfire. But what if you want to edit something? You can’t change how the message looks, you can’t make it tell you about new Pull Requests. Oh, but if you use IRC, then it will tell you about Pull Requests.
That’s why it’s nice to have Hubot in the middle, so you can leverage the power of GitHub to full extent, and have complete control over what you are getting.
To integrate with GitHub API, you first have to create an Auth Token. To do that, you can either go to and click “Create new token” in “Personal Authentication Tokens” panel, or you can do it in command line:
curl -u 'your-github-username' \
-H "X-GitHub-OTP: 123456" \ # Two-Factor auth code, omit if non-relevant
-d '{"scopes":["repo"],"note":"Hubot Auth Token"}' \
https://api.github.com/authorizations
Enter host password for user 'your-github-username':
{
"id": 5415883,
"url": "https://api.github.com/authorizations/5415883",
"app": {
"name": "Hubot Auth Token (API)",
"url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api",
"client_id": "00000000000000000000"
},
"token": "44283ef0f15c645629dd29222410ec9b58507f1b",
"note": "Hubot Auth Token",
"note_url": null,
"created_at": "2014-01-25T17:59:38Z",
"updated_at": "2014-01-25T17:59:38Z",
"scopes": [
"repo"
]
}
Store the token
somewhere safe, as it is nearly as powerful as your password.
Most of GitHub related monitoring is based on . You create a hook, give it an endpoint, and it will make HTTP requests when events occur.
You can create hooks over web interface - go to repository settings, select “Service Hooks”, then “WebHook URLs”. GitHub has recently renewed their hooks management, it is now much more flexible than it was before. Still, my prefered way of doing this is using the command line.
If you will use web based hook management, make sure you always select “Payload version” that ends with json
, or otherwise scripts provided in this book may not work.
There are hooks available for over a dozen events, like push
, issues
, pull_request
, fork
, team_add
, etc. You can find a full and up to date list in .
Let’s create a very simple Hubot script that will be able to receive HTTP requests and dump their contents, so we can use it as a starting point for our integrations.
scripts/github-hook-test.coffee
module.exports =
(robot) ->
robot
.
router
.
get
"/github/test"
,
(req, res) ->
dump
'Received GET:'
,
req
,
res
robot
.
router
.
post
"/github/test"
,
(req, res) ->
dump
'Received POST:'
,
req
,
res
robot
.
router
.
put
"/github/test"
,
(req, res) ->
dump
'Received PUT:'
,
req
,
res
dump =
(message, req, res) ->
console
.
log
message
,
JSON
.
strigify
(
req
.
body
,
null
,
2
)
res
.
end
()
Keep in mind, that GitHub should be able to access Hubot’s HTTP endpoint to post the data. You should also take actions to secure your Hubot HTTP endpoint to prevent malicious attempts to perform unwanted HTTP requests. A common practice is to use firewall to restrict public access and whitelist GitHub IP range. You can find out GitHub IP range on their page, or even better, using our favorite tool - the command line:
hubot@botserv:~$
curl https://api.github.com/meta {
"verifiable_password_authentication": true,
"hooks": [
"192.30.252.0/22"
],
"git": [
"192.30.252.0/22"
]
}
Now, let’s create a hook that will tell us about pushes. You will need to know the public endpoint of your Hubot. To test it, just open http://<hubot.server>/hubot/help
in your browser and see if it shows the help.
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
-d '{"name":"web","active":true,"events":["push"], \
"config":{"url":"http://botserv.your.org:8080/github/test", \
"content_type":"json"}}' \
https://api.github.com/repos/spajus/hubot-example/hooks
{
"url": "https://api.github.com/repos/spajus/hubot-example/hooks/1730429",
"test_url": "https://api.github.com/repos/spajus/hubot-example/hooks/173042\
9/test",
"id": 1730429,
"name": "web",
"active": true,
"events": [
"push"
],
"config": {
"url": "http://botserv.your.org:8080/github/test",
"content_type": "json"
},
"last_response": {
"code": null,
"status": "unused",
"message": null
},
"updated_at": "2014-01-26T06:02:04Z",
"created_at": "2014-01-26T06:02:04Z"
}
After a push is made to the repo, here is what hubot.log
shows:
Received
POST
:
{
"ref"
:
"refs/heads/master"
,
"after"
:
"80398238f9f2952413278ae7a286a9e7b67af9a9"
,
"before"
:
"e52a9c120c7b6636966aa72cf6c37e5707023c14"
,
"created"
:
false
,
"deleted"
:
false
,
"forced"
:
true
,
"compare"
:
"https://github.com/spajus/hubot-example/compare/e52a9c120c7b...\
80398238f9f2"
,
"commits"
:
[
{
"id"
:
"80398238f9f2952413278ae7a286a9e7b67af9a9"
,
"distinct"
:
true
,
"message"
:
"Add GitHub hooks test script"
,
"timestamp"
:
"2014-01-25T22:38:52-08:00"
,
"url"
:
"https://github.com/spajus/hubot-example/commit/80398238f9f29524\
13278ae7a286a9e7b67af9a9"
,
"author"
:
{
"name"
:
"Tomas Varaneckas"
,
"email"
:
"[email protected]"
,
"username"
:
"spajus"
},
"committer"
:
{
"name"
:
"Tomas Varaneckas"
,
"email"
:
"[email protected]"
,
"username"
:
"spajus"
},
"added"
:
[
"scripts/github-hook-test.coffee"
],
"removed"
:
[],
"modified"
:
[]
}
],
"head_commit"
:
{
"id"
:
"80398238f9f2952413278ae7a286a9e7b67af9a9"
,
"distinct"
:
true
,
"message"
:
"Add GitHub hooks test script"
,
"timestamp"
:
"2014-01-25T22:38:52-08:00"
,
"url"
:
"https://github.com/spajus/hubot-example/commit/80398238f9f2952413\
278ae7a286a9e7b67af9a9"
,
"author"
:
{
"name"
:
"Tomas Varaneckas"
,
"email"
:
"[email protected]"
,
"username"
:
"spajus"
},
"committer"
:
{
"name"
:
"Tomas Varaneckas"
,
"email"
:
"[email protected]"
,
"username"
:
"spajus"
},
"added"
:
[
"scripts/github-hook-test.coffee"
],
"removed"
:
[],
"modified"
:
[]
},
"repository"
:
{
"id"
:
15725904
,
"name"
:
"hubot-example"
,
"url"
:
"https://github.com/spajus/hubot-example"
,
"description"
:
"Examples for
\"
Automation and Monitoring with Hubot
\"
boo\
k."
,
"homepage"
:
"https://leanpub.com/automation-and-monitoring-with-hubot"
,
"watchers"
:
0
,
"stargazers"
:
0
,
"forks"
:
0
,
"fork"
:
false
,
"size"
:
204
,
"owner"
:
{
"name"
:
"spajus"
,
"email"
:
"[email protected]"
},
"private"
:
false
,
"open_issues"
:
0
,
"has_issues"
:
true
,
"has_downloads"
:
true
,
"has_wiki"
:
true
,
"language"
:
"CoffeeScript"
,
"created_at"
:
1389156986
,
"pushed_at"
:
1390718321
,
"master_branch"
:
"master"
},
"pusher"
:
{
"name"
:
"spajus"
,
"email"
:
"[email protected]"
}
}
There is a load of information here, and we will make ourselves a script that extracts the interesting bits.
Before we start using those hooks, it’s good to know how to list and remove them. To list all hooks on one GitHub repository, run this:
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
https://api.github.com/repos/spajus/hubot-example/hooks
[
{
"url": "https://api.github.com/repos/spajus/hubot-example/hooks/1730429",
"test_url": "https://api.github.com/repos/spajus/hubot-example/hooks/1730\
429/test",
"id": 1730429,
"name": "web",
...
}
]
To delete the hook, do a DELETE
request providing hook id
:
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
-X DELETE \
https://api.github.com/repos/spajus/hubot-example/hooks/1730429
There is a ready-made Hubot script for displaying pushes - , but we will create ourselves a new one that is a little more dynamic and uses hubot-pubsub
for routing.
scripts/github-pubsub-pushes.coffee
# Description:
# hubot-pubsub based GitHub push notifier
#
# Dependencies:
# "hubot-pubsub": "1.0.0"
#
# URLS:
# POST /github/pushes/pubsub/<pubsub-event>
#
# Authors:
# spajus
module.exports =
(robot) ->
robot
.
router
.
post
"/github/pushes/pubsub/:event"
,
(req, res) ->
res
.
end
(
''
)
event =
req
.
params
.
event
try
payload =
req
.
body
prefix =
">>> "
if
payload
.
commits
.
length
>
0
merge_commit =
false
author =
payload
.
commits
[
0
].
author
.
name
for
commit
in
payload
.
commits
if
commit
.
author
.
name
!=
author
merge_commit =
true
break
if
merge_commit
message =
"
#{
prefix
}#{
payload
.
pusher
.
name
}
merged
#{
payload
.
commits
\
.
length
}
"
+
"commits on
#{
payload
.
repository
.
name
}
:"
+
"
#{
payload
.
ref
.
replace
(
'refs/heads/'
,
''
)
}
"
+
"(compare:
#{
payload
.
compare
}
)"
robot
.
emit
'pubsub:publish'
,
event
,
message
if
payload
.
commits
.
length
<
10
for
commit
in
payload
.
commits
robot
.
emit
'pubsub:publish'
,
event
,
" *
#{
commit
.
author
.
name
}
:
#{
commit
.
message
}
(
#{
com
\
mit
.
url
}
)"
else
message =
"
#{
prefix
}#{
payload
.
commits
[
0
].
author
.
name
}
"
+
"(
#{
payload
.
commits
[
0
].
author
.
username
}
) "
+
"pushed
#{
payload
.
commits
.
length
}
commits to "
+
"
#{
payload
.
repository
.
name
}
:
#{
payload
.
ref
.
replace
(
'refs/h\
eads/'
,
''
)
}
"
if
payload
.
commits
.
length
>
1
message
+=
" (compare:
#{
payload
.
compare
}
)"
robot
.
emit
'pubsub:publish'
,
event
,
message
for
commit
in
payload
.
commits
robot
.
emit
'pubsub:publish'
,
event
,
" *
#{
commit
.
message
}
(
#{
c
\
ommit
.
url
}
)"
else
robot
.
emit
'pubsub:publish'
,
event
,
message
for
commit
in
payload
.
commits
do
(commit) ->
robot
.
emit
'pubsub:publish'
,
event
,
" *
#{
commit
.
message
}
(
#
\
{commit.url})"
else
if
payload
.
created
if
payload
.
base_ref
base_ref =
': '
+
payload
.
base_ref
.
replace
(
'refs/heads/'
,
''
)
else
base_ref =
''
robot
.
emit
'pubsub:publish'
,
event
,
"
#{
prefix
}#{
payload
.
pusher
.
name
\
}
"
+
"created:
#{
payload
.
ref
.
replace
(
'refs/heads/'
,
''
)
}#{
bas
\
e_ref
}
"
if
payload
.
deleted
robot
.
emit
'pubsub:publish'
,
event
,
"
#{
prefix
}#{
payload
.
pusher
.
name
\
}
"
+
"deleted:
#{
payload
.
ref
.
replace
(
'refs/heads/'
,
''
)
}
"
catch
error
console
.
log
"github-pubsub-push error:
#{
error
}
. Payload:
#{
req
.
body
}
"
Script source available at
You will get something like this:
Tomas V. hubot subscribe github.pushes Hubot Subscribed 585164 to github.pushes events Hubot github.pushes: >>> Tomas Varaneckas (spajus) pushed 1 commits to hu\ bot-example:master github.pushes: * Update hubot-pubsub to 1.0.0 (https://github.com/s\ pajus/hubot-example/commit/...)
This script will also tell you about tags and branches.
It is possible to receive a Hubot notification whenever somebody opens or closes an issue on GitHub. It is configurable per repo.
First we create a hook for the script. It will be listening on /github/issues/pubsub/:event
.
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
-d '{"name":"web","active":true,"events":["issues"],\
"config":{"url":"http://botserv.your.org:8080/github/issues/pubsub/github.i\
ssues",\
"content_type":"json"}}' \
https://api.github.com/repos/spajus/hubot-example/hooks
Now, the script:
scripts/github-pubsub-issues.coffee
# Description:
# An HTTP Listener that notifies about new Github issues
#
# Dependencies:
# "hubot-pubsub": "1.0.0"
#
# URLS:
# POST /github/issues/pubsub/<pubsub-event>
#
# Authors:
# spajus
module.exports =
(robot) ->
robot
.
router
.
post
"/github/issues/pubsub/:event"
,
(req, res) ->
res
.
end
(
""
)
event =
req
.
params
.
event
announceIssue
req
.
body
,
(data) ->
robot
.
emit
'pubsub:publish'
,
event
,
data
announceIssue =
(data, cb) ->
if
data
.
action
mentioned =
data
.
issue
.
body
.
match
(
/(^|\s)(@[\w\-\/]+)/g
)
if
mentioned
unique =
(array) ->
output =
{}
output
[
array
[
key
]]
=
array
[
key
]
for
key
in
[
0
...
array
.
length
]
value
for
key
,
value
of
output
mentioned =
mentioned
.
map
(nick) ->
nick
.
trim
()
mentioned =
unique
mentioned
mentioned_line =
"\nMentioned:
#{
mentioned
.
join
(
", "
)
}
"
else
mentioned_line =
''
cb
"Issue
#{
data
.
action
}
: \"
#{
data
.
issue
.
title
}
\" "
+
"by
#{
data
.
issue
.
user
.
login
}
:
#{
data
.
issue
.
html_url
}#{
mentioned_line
}
"
Script source available at
Subscribe your room to github.issues
via hubot-pubsub and here’s what you will get:
Tomas V. hubot subscribe github.issues Hubot Subscribed 585164 to github.issues events github.issues: Issue opened: "Test the issue hook" by spajus: https\ ://github.com/spajus/hubot-example/issues/1 Mentioned: @spajus Tomas V. I'll go close this Hubot github.issues: Issue closed: "Test the issue hook" by spajus: https\ ://github.com/spajus/hubot-example/issues/1 Mentioned: @spajus
Knowing about new pull requests as soon as they appear is essential for maintaining a healthy workflow. If you do pull requests, you must know how long can it take to wait for somebody to review and merge your pull request. It shouldn’t be that way, and when pull request notifications start appearing in developer chatrooms, average response time drops tenfold.
Let’s start by creating a new hook that will post data on /github/pulls/pubsub/:event
.
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
-d '{"name":"web","active":true,"events":["pull_request"],\
"config":{"url":"http://botserv.your.org:8080/github/issues/pubsub/github.p\
ulls",\
"content_type":"json"}}' \
https://api.github.com/repos/spajus/hubot-example/hooks
The script:
scripts/github-pubsub-pulls.coffee
# Description:
# hubot-pubsub based GitHub pull request notifier
#
# Dependencies:
# "hubot-pubsub": "1.0.0"
#
# URLS:
# POST /github/pulls/pubsub/<pubsub-event>
#
# Authors:
# spajus
module.exports =
(robot) ->
robot
.
router
.
post
"/github/pulls/pubsub/:event"
,
(req, res) ->
event =
req
.
params
.
event
res
.
end
(
""
)
announcePullRequest
req
.
body
,
(data) ->
robot
.
emit
'pubsub:publish'
,
event
,
data
announcePullRequest =
(data, cb) ->
if
data
.
action
==
'opened'
mentioned =
data
.
pull_request
.
body
.
match
(
/(^|\s)(@[\w\-\/]+)/g
)
if
mentioned
unique =
(array) ->
output =
{}
output
[
array
[
key
]]
=
array
[
key
]
for
key
in
[
0
...
array
.
length
]
value
for
key
,
value
of
output
mentioned =
mentioned
.
filter
(nick) ->
slashes =
nick
.
match
(
/\//g
)
slashes
is
null
or
slashes
.
length
<
2
mentioned =
mentioned
.
map
(nick) ->
nick
.
trim
()
mentioned =
unique
mentioned
mentioned_line =
"\nMentioned:
#{
mentioned
.
join
(
", "
)
}
"
else
mentioned_line =
''
cb
"New pull request \"
#{
data
.
pull_request
.
title
}
\" "
+
"by
#{
data
.
pull_request
.
user
.
login
}
: "
+
"
#{
data
.
pull_request
.
html_url
}#{
mentioned_line
}
"
Script source available at
Here’s how it looks in action:
Tomas V. hubot subscribe github.pulls Hubot Subscribed 585163 to github.pulls events Tomas V. I'll go make a pull request now... Hubot github.pulls: New pull request "Add GitHub pull request notificatio\ n script" by spajus: https://github.com/spajus/hubot-example/pull/2 Mentioned: @spajus, @other_responsible_guy
When your company grows big, you may start worrying about repository permissions being given to wrong teams or people. Luckily, you Hubot can help. When new team gets added to a repository, team_add
event can be fired. Let’s write ourselves a script for that:
script/github-pubsub-team.coffee
# Description:
# An HTTP Listener that notifies about repository team changes
#
# Dependencies:
# "hubot-pubsub": "1.0.0"
#
# URLS:
# POST /github/team/pubsub/<pubsub-event>
#
# Authors:
# spajus
module.exports =
(robot) ->
robot
.
router
.
post
"/github/team/pubsub/:event"
,
(req, res) ->
res
.
end
(
""
)
event =
req
.
params
.
event
announceTeamChange
req
.
body
,
(data) ->
robot
.
emit
'pubsub:publish'
,
event
,
data
announceTeamChange =
(data, cb) ->
team =
data
.
team
.
name
team_perm =
data
.
team
.
permission
org =
data
.
sender
.
login
repo =
data
.
repository
.
full_name
cb
"@
#{
org
}
/
#{
team
}
received
#{
team_perm
}
rights on
#{
repo
}
"
Script source available at
Run this on every repository to enable team_add
hooks:
hubot@botserv:~$
curl -H "Authorization: token <your_auth_token>"
\
-d '{"name":"web","active":true,"events":["team_add"],\
"config":{"url":"http://botserv.your.org:8080/github/team/pubsub/github.tea\
m",\
"content_type":"json"}}' \
https://api.github.com/repos/<your_org>/<your_repo>/hooks
Subcribe a chatroom to github.team
events, then add a team to repository and see what Hubot tells you:
Tomas V. hubot subscribe github.team Hubot Subscribed 585163 to github.team events Hubot github.team: @example/devs received pull rights on example/app
Tracking repository permissions without organization is also possible. Here’s the script:
script/github-pubsub-member.coffee
# Description:
# An HTTP Listener that notifies about repo membership changes
#
# Dependencies:
# "hubot-pubsub": "1.0.0"
#
# URLS:
# POST /github/member/pubsub/<pubsub-event>
#
# Authors:
# spajus
module.exports =
(robot) ->
robot
.
router
.
post
"/github/member/pubsub/:event"
,
(req, res) ->
res
.
end
(
""
)
event =
req
.
params
.
event
announceMemberChange
req
.
body
,
(data) ->
robot
.
emit
'pubsub:publish'
,
event
,
data
announceMemberChange =
(data, cb) ->
if
data
.
action
who =
data
.
member
.
login
by_who =
data
.
sender
.
login
repo =
data
.
repository
.
full_name
action =
data
.
action
cb
"
#{
repo
}
membership change: @
#{
by_who
}
#{
action
}
@
#{
who
}
"
Script source available at
At the moment of writing, only added
action was sent from GitHub. Still, it’s pretty useful.
Tomas V. hubot subscribe github.member Hubot Subscribed 585163 to github.member events github.member: spajus/hubot-example membership change: @spajus adde\ d @electrotek
To prevent old open issues that nobody bothers to follow up with, we can make Hubot automatically run a daily check and close issues that had no activity for over a month.
The following script will be a little more advanced. It requires additional dependencies and configuration.
scripts/github-old-issues.coffee
# Description
# Find and close old issues in GitHub
#
# Dependencies:
# "githubot": "0.5.0"
# "moment": "2.5.1"
# "hubot-pubsub": "1.0.0"
# "cron": "1.0.3"
# "time": "0.10.0"
#
# Configuration:
# HUBOT_GITHUB_TOKEN (optional, if you want to search in private repos)
# HUBOT_GITHUB_ORG - your GitHub organization
#
# Commands:
# hubot close old issues in <repo> - Close outdated issues in given repo
#
# Author:
# spajus
# Override these with your target repos. Keep list empty if using org.
target_repos =
[
'spajus/hubot-example'
,
'spajus/hubot-control'
]
# Override with your org. Keep blank if non relevant.
target_org =
''
# Set your time zone
timezone =
'America/Los_Angeles'
# Set desired time. 00 00 9 * * 1-5 is monday-friday at 9 AM.
cron_expression =
'00 00 9 * * 1-5'
module.exports =
(robot) ->
github =
require
(
'githubot'
)(
robot
,
apiVersion:
'preview'
)
cronJob =
require
(
'cron'
).
CronJob
moment =
require
(
'moment'
)
new
cronJob
(
cron_expression
,
closeOldIssues
,
null
,
true
,
timezone
)
closeOldIssues =
->
org =
target_org
||
process
.
env
.
HUBOT_GITHUB_ORG
if
org
robot
.
emit
'github:org:issues:close'
,
org
for
repo
in
target_repos
robot
.
emit
'github:repo:issues:close'
,
repo
robot
.
respond
/close old issues (in )?(.+\/[^\s]+)/i
,
(msg) ->
repo =
msg
.
match
[
2
]
closeOldIssuesIn
repo
,
(data) ->
msg
.
send
data
robot
.
on
'github:org:issues:close'
,
(org) ->
github
.
get
"/orgs/
#{
org
}
/repos"
,
(data) ->
for
repo
in
data
closeOldIssuesIn
repo
.
full_name
,
(data) ->
robot
.
emit
'pubsub:publish'
,
'github.issue.close'
,
data
robot
.
on
'github:repo:issues:close'
,
(repo) ->
closeOldIssuesIn
repo
,
(data) ->
robot
.
emit
'pubsub:publish'
,
'github.issue.close'
,
data
closeOldIssuesIn =
(repo, cb) ->
github
.
handleErrors
(response) ->
cb
"Error:
#{
response
.
statusCode
}
#{
response
.
error
}
. Repo:
#{
repo
}
"
github
.
get
"repos/
#{
repo
}
/issues?state=open"
,
(data) ->
reply =
''
found =
false
old_time =
moment
().
subtract
'months'
,
1
for
issue
in
data
issue_time =
moment
issue
.
updated_at
,
'YYYY-MM-DDTHH:mm:ssZ'
if
issue_time
<
old_time
found =
true
post_data =
{
body:
"Closing old issue: updated
#{
issue_time
.
fromNo
\
w
()
}
"
}
github
.
post
"repos/
#{
repo
}
/issues/
#{
issue
.
number
}
/comments"
,
post_d
\
ata
,
(post_resp) ->
console
.
log
"Posted comment:
#{
post_resp
.
html_url
}
"
close_data =
{
state:
'closed'
}
github
.
request
'PATCH'
,
"repos/
#{
repo
}
/issues/
#{
issue
.
number
}
"
,
clo
\
se_data
,
(close_resp) ->
console
.
log
"Closed issue:
#{
close_resp
.
html_url
}
"
reply =
"
#{
reply
}#{
issue
.
title
}
(
#{
issue
.
html_url
}
) updated
#{
issue
\
_time
.
fromNow
()
}
\n"
if
found
cb
"Found
#{
data
.
length
}
open issues in
#{
repo
}
. Closed old ones:\n
#{
\
reply
}
"
else
cb
"No old issues found in
#{
repo
}
"
Script source available at
Before restarting Hubot with this script, make sure to change configuration in first couple of lines, and install the dependencies. Make sure to use npm install --save
so the definitions will get automatically added to package.json
. You will also have set use a valid auth token in using HUBOT_GITHUB_TOKEN
. You can do that in hubot.conf
if you’ve set up Hubot as described in this book.
npm install --save moment time cron githubot
To test if it works, you can manually trigger the closing of old issues by saying hubot close old issues in some/repo
.
Tomas V. hubot close old issues in spajus/hubot-example Hubot No old issues found in spajus/hubot-example