Compare commits

...

10 commits

Author SHA1 Message Date
Simon Vieille 2fd887d40a output 2016-01-23 11:54:59 +01:00
Simon Vieille 350af4c943 output 2016-01-23 11:24:19 +01:00
Simon Vieille 4fb251d788 projects directory 2016-01-23 10:49:44 +01:00
Simon Vieille 075380ec23 composer added 2016-01-22 11:08:25 +01:00
Simon Vieille 4b5f65b9df Command runs 2016-01-21 17:42:54 +01:00
Simon Vieille ea4f3445fb Deployment commands 2016-01-21 17:00:53 +01:00
Simon Vieille ca70506e9f composer interpreter 2016-01-21 16:41:30 +01:00
Simon Vieille bd26e8cbfe Deployment commands 2016-01-21 16:38:31 +01:00
Simon Vieille 8484ecc662 Project versionning detection 2016-01-21 16:07:27 +01:00
Simon Vieille f6e605694f Command analyzer 2016-01-21 15:15:45 +01:00

View file

@ -2,25 +2,192 @@
# Deployment script
#
# Commands:
# hubot deploy <project> [from branch <branch>] to <environnement> [after <command>[, <command>, ...]]
# hubot deploy <project> [with <program>] [from branch <branch>] to <target> [after <command>[, <command>, ...]]
#
# URLS:
#
# Notes:
#
fs = require 'fs'
deploymentDirectory = null
module.exports = (robot) ->
robot.hear /deploy ([^\s]+)( from branch ([^\s]+))? to ([^\s]+)( after (.*))?$/i, (res) ->
project = res.match[1]
environnement = res.match[4]
branch = if res.match[3] then res.match[3] else null
commands = if res.match[6] then cleanCommands res.match[6].split(',') else []
robot.hear /deploy set ([^\s]+) +(.+)$/i, (res) ->
if res.match[1] == "directory"
deploymentDirectory = res.match[2]
robot.hear /deploy +([^\s]+)( +with +([^\s]+))?( +from +branch +([^\s]+))? +to +([^\s]+)( +after (.*))?$/i, (res) ->
if ! process.env.hasOwnProperty('HUBO_DEPLOYMENT_PROJECTS_DIRECTORY')
if deploymentDirectory == null
res.reply "You must set the env var HUBO_DEPLOYMENT_PROJECTS_DIRECTORY with the directory of the projects."
res.reply "Temporaly, you can use the command: deploy set directory <directory>"
return
project = res.match[1]
target = res.match[6]
program = if res.match[3] then res.match[3] else null
branch = if res.match[5] then res.match[5] else null
commands = if res.match[8] then cleanCommands res.match[8].split "," else []
if deploymentDirectory != null
directory = deploymentDirectory
else
directory = process.env.HUBO_DEPLOYMENT_PROJECTS_DIRECTORY
directory += "/" + project
try
fs.stat directory, (err, stats) ->
if err != null or !stats.isDirectory
return res.reply "Project not found [" + directory + "]"
try
fs.statSync directory + '/.svn'
pv = new SvnProjectVersionning branch
catch e
try
fs.statSync directory + '/.git'
pv = new GitProjectVersionning branch
catch e
if pv
d = deploy directory, pv, commands, target, program
res.send d
else
res.reply "Not a SVN or GIT repository"
catch e
res.reply "Exception: " + e
class ProjectVersionning
constructor: (@branch) ->
getUpdateCommands: () ->
class SvnProjectVersionning extends ProjectVersionning
getUpdateCommands: () ->
['svn up']
class GitProjectVersionning extends ProjectVersionning
getUpdateCommands: () ->
commands = []
if @branch == null
commands.push 'git pull origin $(git rev-parse --abbrev-ref HEAD)'
else
br = @branch.split "/"
if br.length == 1
commands.push 'git checkout ' + br[0]
commands.push 'git pull origin ' + br[0]
else if br.length == 2
commands.push 'git checkout ' + br[1]
commands.push 'git pull ' + br.join(' ')
commands
logExec = (command, options) ->
exec = require "sync-exec"
exec command, options
deploy = (directory, projectVersionning, commands, target, program) ->
commands = projectVersionning.getUpdateCommands().concat(commands)
canDeploy = true
results = []
for command in commands
if !canDeploy
continue
stmt = logExec command , {cwd: directory}
results.push {
command: command,
status: stmt.status,
stdout: stmt.stdout,
stderr: stmt.stderr,
}
if stmt.status != 0
canDeploy = false
if canDeploy
command = buildDeployCommand(directory, program, target)
stmt = logExec command, {cwd: directory}
results.push {
command: command,
status: stmt.status,
stdout: stmt.stdout,
stderr: stmt.stderr,
}
output = ""
for stmt in results
output += generateOutput stmt
output
generateOutput = (stmt) ->
prefix = "deploy-" + Date.now()
status =
if stmt.status == 0
"<span color='green'>OK</span>"
else
"<span color='red'>Failed</span>"
"""
<p><pre>#{stmt.command}</pre> #{status}</p>
<div>
Outputs: <a href="#" onclick="var e = document.getElementById('#{prefix}-stdout'); if (e.getAttribute('data-show') == 0) {e.style.display = 'block'; e.setAttribute('data-show', '1');} else {e.display = 'none'; e.setAttribute('data-show', '0');}">STDOUT</a> <a href="#" onclick="var e = document.getElementById('#{prefix}-stderr'); if (e.getAttribute('data-show') == 0) {e.style.display = 'block'; e.setAttribute('data-show', '1');} else {e.display = 'none'; e.setAttribute('data-show', '0');}">STDERR</a>
<pre id="#{prefix}-stdout" data-show="0" style="display: none">#{stmt.stdout}</pre>
<pre id="#{prefix}-stderr" data-show="0" style="display: none">#{stmt.stderr}</pre>
</div>
"""
buildDeployCommand = (directory, program, target) ->
if program == 'mage'
command = 'vendor/bin/mage deploy to:' + target
else
interpreter = null
try
fs.statSync directory + '/bin/console'
interpreter = 'php bin/console'
catch e
try
fs.statSync directory + '/app/console'
interpreter = 'php app/console'
catch e
if interpreter != null
command = interpreter + ' project:deploy ' + target + ' --go'
command
cleanCommands = (commands) ->
results = []
commands = commands.map(Function.prototype.call, String.prototype.trim)
commands = commands.map Function.prototype.call, String.prototype.trim
interpreters = {
"sf" : "php symfony",
"sf2" : "php app/console",
"sf3" : "php bin/console",
"composer": "composer"
}
for command in commands
results.push(command) if command != ''
if command != ""
if command.match /(sf[2-3]?|composer):.+/
elements = command.split ":"
interpreter = elements[0]
elements = elements.splice 1
args = elements.join(":")
results.push interpreters[interpreter] + " " + args
else
results.push command
results