# Description: # Deployment script # # Commands: # hubot deploy [with ] [from branch ] to [after [, , ...]] # # URLS: # # Notes: # fs = require 'fs' deploymentDirectory = null module.exports = (robot) -> 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 " 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 "OK" else "Failed" """

#{stmt.command}
#{status}

Outputs: STDOUT STDERR
""" 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 interpreters = { "sf" : "php symfony", "sf2" : "php app/console", "sf3" : "php bin/console", "composer": "composer" } for command in commands 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