Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6bd4f01
create-repo
Mar 22, 2018
0518bad
Merge pull request #1 from migarjo/create-repo
Mar 22, 2018
bba0131
Get github token from coffeescript
Mar 22, 2018
af27510
coffeescriptify createrepo
Mar 22, 2018
e8a7ee7
Coffeescriptify take 2
Mar 22, 2018
96f5f0f
Coffeescriptify take 3
Mar 22, 2018
f83b681
Add logging messages
Mar 22, 2018
fafc3c8
Coffeescriptify take 4
Mar 22, 2018
119dd0a
Coffeescriptify take 5
Mar 22, 2018
2113eb4
Add file seeding
Mar 22, 2018
c31e4da
Fix url paths
Mar 22, 2018
3a49163
Add user config to git
Mar 23, 2018
13e454d
Add global to user config
Mar 23, 2018
bca5bc0
Add quotes to user config
Mar 23, 2018
281cb32
Remove global from user config
Mar 23, 2018
2a5c859
String config with commit
Mar 23, 2018
51f10a3
Copy contents of templaterepo
Mar 23, 2018
edd8251
Copy contents with rsync
Mar 23, 2018
5c7cb88
Copy contents with regex
Mar 23, 2018
cfaf035
cleaned up
admiralAwkbar Mar 23, 2018
5198e1f
Update create-and-protect-repo.sh
admiralAwkbar Mar 23, 2018
ccda765
push to file
admiralAwkbar Mar 23, 2018
dbe3052
change order
admiralAwkbar Mar 23, 2018
5abac4d
telling it to shut it
admiralAwkbar Mar 23, 2018
d078f97
Update create-repo.coffee
admiralAwkbar Mar 23, 2018
72cd733
Add script wrapper documentation to readme
Mar 23, 2018
d725c1d
add env vars and always on to readme
admiralAwkbar Mar 23, 2018
8f07c0a
update sync button
admiralAwkbar Mar 23, 2018
ac0296c
removing the log file
admiralAwkbar Mar 23, 2018
474d3bb
removing forever module
admiralAwkbar Mar 23, 2018
669fef1
adding remember
admiralAwkbar Mar 23, 2018
468e23c
fixing file name
admiralAwkbar Mar 23, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,16 @@ Connect to your Azure web portal and authenticate. You will then need to complet
- Go to your newly created application on the dashboard
- Configure environment variables that your Hubot will need to use
- Select `application settings`
- Navigate to `General Settings`
- Select Always On
- Navigate to the `Application Settings` section
- Select `Add new setting` to create key pairs:
- HUBOT_SLACK_TOKEN=Your Created Slack Token
- HUBOT_ADAPTER=slack
- BOT_NAME=YourHubotName
- BOT_EMAIL=YourHubot@email.com
- HUBOT_LOG_LEVEL=debug
- GITHUB_API_TOKEN=YourPACFromGitHub
- Select `Save` from top banner
- *NOTE:* If you are using a different chat tool, you will need to configure different environment variables
- Set up automatic deployment of this app from your GitHub repository
Expand All @@ -57,14 +63,22 @@ Connect to your Azure web portal and authenticate. You will then need to complet


### Deployment
The first time you deploy this you may need to select the `sync button` of `Deployment Options` to start the application the first time.
Any time the master branch of your Azure Hubot repository is updated, it will trigger the Azure Deployment and update the Hubot. The Hubot only takes around 30 seconds to be re-deployed.
*NOTE:* The first deployment will take longer as it will need to pull in many of the base dependencies.
*NOTE:* The first deployment will take longer as it will need to pull in many of the base dependencies.

-------------------------------------

# Hubot / MS-Teams Bot integrations
## Adding scripts to this Bot
Hubot is a node app running coffeescript modules that can be written within the `scripts` folder. One common pattern is to use a coffeescript wrapper that calls scripts in other languages so you can write Hubot in any scripting language you're comfortable with.

## Connect to VSTS
This implementation includes an example of this at `scripts/create-repo.coffee`. This module interprets the input given by the user and calls a bash script at `scripts/shell/create-and-protect-repo.sh` to create a github repository. These example files include documentation to implement this for other uses.

-------------------------------------

## Hubot / MS-Teams Bot integrations

### Connect to VSTS
You will want to connect the bot from your Chat tooling into VSTS.
This integration should be able to complete at the minimum the following actions:
- Show queue
Expand All @@ -73,7 +87,7 @@ This integration should be able to complete at the minimum the following actions

Other actions are greatly encouraged, and can be seen as enhancements.

## Connect to GitHub
### Connect to GitHub
You will want to connect the bot from your Chat tooling into GitHub.
This integration should be able to complete at the minimum the following actions:
- List Repositories
Expand All @@ -82,18 +96,18 @@ This integration should be able to complete at the minimum the following actions

Other actions are greatly encouraged, and can be seen as enhancements.

## Monitoring
### Monitoring
Having your bot be able to connect to your monitoring environment is a great step in maturity.
The ability to query information or metrics gives you a quick insight to your environment from your chat environment.
This allows teams to collaborate in real time about the environment and have a record of what is happening.
This allows teams to collaborate in real time about the environment and have a record of what is happening.
Commands that allow you to fetch metrics and graphs, as well as check endpoints can greatly increase your culture and promote your environments.


## Sparkles
### Sparkles
[Sparkles](https://github.com/pmn/sparkles/blob/master/scripts/sparkles.coffee)
Giving your teammates points for doing something special is a great way to build culture and promote sharing.
This can be added and enhance your culture.

## Remember
### Remember
This is a fairly common script that allows your bot to remember basic strings.
This is useful to remember common end points, or other common data that needs to be stored in chat.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"description": "(Your very own Hubot)",
"dependencies": {
"coffee-script": "^1.12.6",
"forever": "^0.15.3",
"hubot": "^2.19.0",
"hubot-diagnostics": "0.0.2",
"hubot-google-images": "^0.2.7",
Expand Down
101 changes: 101 additions & 0 deletions scripts/Basic-Remember.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Description
# Remembers a key and value
#
# Commands:
# hubot what is|remember <key> - Returns a string
# hubot remember <key> is <value>. - Returns nothing. Remembers the text for next time!
# hubot what do you remember - Returns everything hubot remembers.
# hubot forget <key> - Removes key from hubots brain.
# hubot what are your favorite memories? - Returns a list of the most remembered memories.
# hubot random memory - Returns a random string
#
# Dependencies:
# "underscore": "*"
#
#

_ = require('underscore')

module.exports = (robot) ->
memoriesByRecollection = () -> robot.brain.data.memoriesByRecollection ?= {}
memories = () -> robot.brain.data.remember ?= {}

findSimilarMemories = (key) ->
searchRegex = new RegExp(key, 'i')
Object.keys(memories()).filter (key) -> searchRegex.test(key)

robot.respond /(?:what is|rem(?:ember)?)\s+(.*)/i, (msg) ->
words = msg.match[1]
if match = words.match /(.*?)(\s+is\s+([\s\S]*))$/i
msg.finish()
key = match[1].toLowerCase()
value = match[3]
currently = memories()[key]
if currently
msg.send "But #{key} is already #{currently}. Forget #{key} first."
else
memories()[key] = value
msg.send "OK, I'll remember #{key}."
else if match = words.match /([^?]+)\??/i
msg.finish()

key = match[1].toLowerCase()
value = memories()[key]

if value
memoriesByRecollection()[key] ?= 0
memoriesByRecollection()[key]++
else
if match = words.match /\|\s*(grep\s+)?(.*)$/i
searchPattern = match[2]
matchingKeys = findSimilarMemories(searchPattern)
if matchingKeys.length > 0
value = "I remember:\n#{matchingKeys.join('\n')}"
else
value = "I don't remember anything matching `#{searchPattern}`"
else
matchingKeys = findSimilarMemories(key)
if matchingKeys.length > 0
keys = matchingKeys.join('\n')
value = "I don't remember `#{key}`. Did you mean:\n#{keys}"
else
value = "I don't remember anything matching `#{key}`"

msg.send value

robot.respond /forget\s+(.*)/i, (msg) ->
key = msg.match[1].toLowerCase()
value = memories()[key]
delete memories()[key]
delete memoriesByRecollection()[key]
msg.send "I've forgotten #{key} is #{value}."

robot.respond /what do you remember/i, (msg) ->
msg.finish()
keys = []
keys.push key for key of memories()
msg.send "I remember:\n#{keys.join('\n')}"

robot.respond /what are your favorite memories/i, (msg) ->
msg.finish()
sortedMemories = _.sortBy Object.keys(memoriesByRecollection()), (key) ->
memoriesByRecollection()[key]
sortedMemories.reverse()

msg.send "My favorite memories are:\n#{sortedMemories[0..20].join('\n')}"

robot.respond /(me|random memory|memories)$/i, (msg) ->
msg.finish()
randomKey = msg.random(Object.keys(memories()))
msg.send randomKey
msg.send memories()[randomKey]

robot.respond /mem(ory)? bomb x?(\d+)/i, (msg) ->
keys = []
keys.push value for key,value of memories()
unless msg.match[2]
count = 10
else
count = parseInt(msg.match[2])

msg.send(msg.random(keys)) for [1..count]
49 changes: 49 additions & 0 deletions scripts/create-repo.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Description:
# Coffeescript to create and protect repo in GitHub.
#
# Notes:
# This is a great example script of how to take input from chat tool
# and start a more native script outside of coffeescript
# This example shows taking a command, and starting a shell script
# and pushing its output back to the chat tool

# Start the listener
module.exports = (robot) ->

#####################################
# LOOP Look for create_repo command #
#####################################
# Look for the create_repo command and take the input as the repo name
robot.respond /create_repo (.*)/i, (msg) ->
# initialize the arguements array so we can pass arguements to script
args = []
# Read in the regex and remove all whitespace
reponame = msg.match[1].replace /^\s+|\s+$/g, ""
# Check to see if the reponame has any space chars inside of it
# We cannot create a repo with spaces!
spaceIndex = reponame.indexOf " "
if spaceIndex != -1
msg.send "Repository names cannot have spaces"
else
# Repo has no spaces, we need to set the variables to pass to script
# Pushing the values into the arguements array
args.push(reponame)
args.push(process.env.GITHUB_API_TOKEN)
args.push(process.env.BOT_NAME)
args.push(process.env.BOT_EMAIL)
# Instantiate child process to be able to create a subprocess
{spawn} = require 'child_process'
# Create new subprocess and have it run the script
# This will start the script and pass it the arguements we have set above
# This is basically running the command: ./create-and-protect-repo.sh "reponame" "GITHUB_API_TOKEN" "BOT_NAME" "BOT_EMAIL"
cmd = spawn('/home/site/wwwroot/scripts/shell/create-and-protect-repo.sh', args)
# Catch stdout and output into hubot's log
cmd.stdout.on 'data', (data) ->
# Print all output from the script running into the chat tool
msg.send "```\n#{data.toString()}\n```"
console.log data.toString().trim()
# Catch stderr and output into hubot's log
cmd.stderr.on 'data', (data) ->
# Print all output from the script running into the chat tool
console.log data.toString().trim()
msg.send "```\n#{data.toString()}\n```"
128 changes: 128 additions & 0 deletions scripts/shell/create-and-protect-repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/bin/sh

#############################################################
# Shell script to Create and Initialize GitHub repository #
# The script will also set basic configs and protect master #
# Owner: Dow DevOps #
#############################################################

###################
# Input Variables #
###################
REPO_NAME=$1 # Name of the GitHub Repository
API_TOKEN=$2 # GitHub Personal Access Token
BOT_NAME=$3 # Name of the Hubot pulled from Env
BOT_EMAIL=$4 # Email for the Hubot pulled from Env
ORG_NAME='Migarjo-Test-Org' # Name of the master Org
TEMPLATE_REPO='dow-dmc' # Teplate repo to clone
TEAM_ID='2237075' # Team ID for Dow
LOG_FILE='createRepo.log' # File to push output
STATUS_CHECK_NAME='Some Status Check' # Name of the default status check that should pass

##############
#### MAIN ####
##############

################################################################################
# Test the input for sanity
################################################################################
# Test REPO_NAME
#echo $REPO_NAME
test -z $REPO_NAME && echo "REPO_NAME Required!" 1>&2 && exit 1

# TEST API_TOKEN
#echo $API_TOKEN
test -z $API_TOKEN && echo "API_TOKEN Required!" 1>&2 && exit 1

################################################################################
# Curl to GitHub to create repository
# Curl Example: https://developer.github.com/v3/repos/#create
################################################################################
echo "------------------------------------------"
echo "Creating Repository:[$ORG_NAME/$REPO_NAME]..."
echo "------------------------------------------"
curl -s -H "Authorization: token $API_TOKEN" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/orgs/$ORG_NAME/repos" \
-d "{\"name\":\"$REPO_NAME\", \
\"private\":\"true\", \
\"has_issues\":\"true\", \
\"has_projects\":\"true\", \
\"has_wiki\":\"true\", \
\"team_id\":\"$TEAM_ID\", \
\"auto_init\":\"true\"}" 2>&1 >> $LOG_FILE

############################################
# Check that the shell returned successful #
############################################
if [ $? != 0 ]; then
echo "ERROR! Failed to create Repo:[$ORG_NAME/$REPO_NAME]!"
exit 1
else
echo "Successfully Initialized Repo:[$ORG_NAME/$REPO_NAME]"
fi

################################################################################
# Initalize the repo with basic Files
################################################################################

echo "------------------------------------------"
echo "Initializing Repository templates..."
echo "------------------------------------------"

# Remove any left over cloned directories
rm -rf $TEMPLATE_REPO $REPO_NAME

# Clone the base and template repo
git clone --quiet https://$API_TOKEN@github.com/$ORG_NAME/$TEMPLATE_REPO.git 2>&1 >> $LOG_FILE
git clone --quiet https://$API_TOKEN@github.com/$ORG_NAME/$REPO_NAME.git 2>&1 >> $LOG_FILE

# Remove the .git from template repo so we dont copy that over
rm -rf $TEMPLATE_REPO/.git

# Copy all files and hidden files from template to new repo
cp -R $TEMPLATE_REPO/* $REPO_NAME/
cp -R $TEMPLATE_REPO/.[a-zA-Z0-9]* $REPO_NAME/

# Remove the logfile before we commit it
rm -f $LOG_FILE

# Git add the files
cd $REPO_NAME
git add . 2>&1 >> $LOG_FILE

# Config the git user and commit the code to the new repo
git config user.email \'$BOT_EMAIL\'; git config user.name \'$BOT_NAME\'; git commit --quiet -m "Initial commit with documents" 2>&1 >> $LOG_FILE

# Push the code back to GitHub
git push --quiet 2>&1 >> $LOG_FILE

# Remove the repos from the system as housekeeping
rm -rf $TEMPLATE_REPO $REPO_NAME


################################################################################
# Curl to GitHub to protect branch
# Example: https://developer.github.com/v3/repos/branches/#update-branch-protection
################################################################################
echo "------------------------------------------"
echo "Protecting the master Branch..."
echo "------------------------------------------"
curl -s -H "Authorization: token $API_TOKEN" -H "Accept: application/vnd.github.v3+json" \
-X PUT "https://api.github.com/repos/$ORG_NAME/$REPO_NAME/branches/master/protection" \
-d "{\"enforce_admins\": true, \
\"required_status_checks\": { \
\"strict\": true, \
\"contexts\": [\"$STATUS_CHECK_NAME\"]}, \
\"required_pull_request_reviews\": { \
\"dismiss_stale_reviews\": true , \
\"require_code_owner_reviews\": true },\
\"restrictions\": null }" 2>&1 >> $LOG_FILE

############################################
# Check that the shell returned successful #
############################################
if [ $? != 0 ]; then
echo "ERROR! Failed to protect Repo:[$ORG_NAME/$REPO_NAME]!"
exit 1
else
echo "Successfully protected Repo:[$ORG_NAME/$REPO_NAME]"
fi