Skip to content

Commit

Permalink
Merge remote-tracking branch 'evan/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
flipflopsimsommer committed Oct 31, 2015
2 parents 2acd4f7 + bd98688 commit a067a97
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 167 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
language: node_js
node_js:
- "0.12"
- "0.10"
- "iojs"
- "4"
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

*A node [gitlab-ci-runner](https://github.com/gitlabhq/gitlab-ci-runner)*

`gcr` v4.x will only support node v4.x+. To use `gcr` with an older version
of node, please use `gcr` v3.x

## Install

```bash
Expand Down
206 changes: 119 additions & 87 deletions lib/build.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
var gcr = require('./gcr')
, spawn = require('child_process').spawn
, rimraf = require('rimraf')
, slide = require('slide')
, chain = slide.chain
, fs = require('fs')
, log = require('npmlog')
, path = require('path')
, util = require('util')
, mkdirp = require('mkdirp')
, argsplit = require('argsplit')
, EE = require('events').EventEmitter
'use strict'

const gcr = require('./gcr')
, spawn = require('child_process').spawn
, rimraf = require('rimraf')
, slide = require('slide')
, chain = slide.chain
, fs = require('fs')
, log = require('npmlog')
, path = require('path')
, util = require('util')
, mkdirp = require('mkdirp')
, argsplit = require('argsplit')
, EE = require('events')

module.exports = Build

Expand All @@ -32,37 +34,37 @@ util.inherits(Build, EE)

Build.prototype.run = function() {
this.state = 'running'
var self = this
this.shouldClone(function(should) {
const self = this
this.shouldClone((should) => {
if (!should) {
self.fetch(function(err) {
if (err) return self.emit('done', false)
this.fetch((err) => {
if (err) return this.emit('done', false)
runCommand(0)
})
} else {
rimraf(self.projectDir, function(err) {
rimraf(self.projectDir, (err) => {
if (err) {
self.state = 'failed'
self.update(function() {
self.emit('done', false)
this.state = 'failed'
this.update(() => {
this.emit('done', false)
})
return
}
self.clone(function(err) {
if (err) return self.emit('done', false)
this.clone((err) => {
if (err) return this.emit('done', false)
runCommand(0)
})
})
}
})

var cmds = this.opts.commands
var len = cmds.length
var dir = this.projectDir
const cmds = this.opts.commands
const len = cmds.length
const dir = this.projectDir
function runCommand(idx) {
if (idx < len) {
log.verbose('[build]', 'running command', idx+1, 'of', len)
var cmd = cmds[idx]
const cmd = cmds[idx]
self.runCommand(cmd, dir, function(err) {
if (err) return self.emit('done', false)
runCommand(idx+1)
Expand All @@ -77,20 +79,19 @@ Build.prototype.run = function() {
}

Build.prototype.clone = function(cb) {
var self = this
var cmd = ['clone', this.opts.repo_url, 'project-'+this.opts.project_id]
var dir = this.projectDir
this.gitCommand(cmd, this.buildDir, function(err) {
const cmd = ['clone', this.opts.repo_url, 'project-'+this.opts.project_id]
const dir = this.projectDir
this.gitCommand(cmd, this.buildDir, (err) => {
if (err) return cb && cb(err)
self.gitCommand(['checkout', self.opts.ref], dir, cb)
this.gitCommand(['checkout', this.opts.ref], dir, cb)
})
}

Build.prototype.fetch = function(cb) {
var self = this
const self = this

var dir = this.projectDir
var repoUrl = this.opts.repo_url
const dir = this.projectDir
const repoUrl = this.opts.repo_url

function resetHard(cb) {
self.gitCommand(['reset', '--hard'], dir, cb)
Expand Down Expand Up @@ -125,11 +126,10 @@ Build.prototype.fetch = function(cb) {
}

Build.prototype.shouldClone = function(cb) {
var self = this
var d = path.join(this.projectDir, '.git')
fs.exists(d, function(e) {
const d = path.join(this.projectDir, '.git')
fs.exists(d, (e) => {
if (!e) return cb(true)
return cb(!self.opts.allow_git_fetch)
return cb(!this.opts.allow_git_fetch)
})
}

Expand All @@ -138,9 +138,9 @@ Build.prototype.append = function(str) {
}

Build.prototype.runCommand = function(cmd, dir, cb) {
var self = this
const self = this
if ('function' === typeof dir) cb = dir, dir = process.cwd()
var env = {
const env = {
CI_SERVER: true
, CI_SERVER_NAME: 'GitLab CI'
, CI_SERVER_VERSION: null
Expand All @@ -159,7 +159,7 @@ Build.prototype.runCommand = function(cmd, dir, cb) {

util._extend(env, process.env)

var opts = {
const opts = {
env: env
, cwd: dir
, timeout: this.opts.timeout
Expand All @@ -171,57 +171,73 @@ Build.prototype.runCommand = function(cmd, dir, cb) {
}

log.verbose('[builder]', 'cmd', cmd)
this.append(util.format('\n%s\n', cmd))
this.append(`\n${cmd}\n`)

var child = spawn('/bin/bash', ['-c', fixedCmd.join(' ')], opts)
const child = spawn('/bin/bash', ['-c', fixedCmd.join(' ')], opts)
var timedout = false
var timer = setTimeout(function() {
var timer = setTimeout(() => {
timedout = true
child.kill()
self.append('\n** TIMEOUT **\n')
this.append('\n** TIMEOUT **\n')
}, this.opts.timeout)
child.stderr.on('data', function(d) {
var data = d.toString()

child.stderr.on('data', (d) => {
const data = d.toString()
log.silly('[builder]', 'stderr', data)
self.append(data)
this.append(data)
})
child.stdout.on('data', function(d) {
var data = d.toString()

child.stdout.on('data', (d) => {
const data = d.toString()
log.silly('[builder]', 'stdout', data)
self.append(data)
this.append(data)
})

child.on('error', (err) => {
if (timer) {
clearTimeout(timer)
timer = null
}
const e = new Error(`Command: [${cmd}] failed ${err.message}`)
this.append(e)
log.error(e, err)
this.state = 'failed'
this.update(function() {
cb && cb(e)
})
})
child.on('close', function(code) {

child.on('close', (code) => {
if (timer) {
clearTimeout(timer)
timer = null
}
if (code !== 0) {
var msg = timedout
const msg = timedout
? 'process timedout'
: 'process exited with code: '+code
var e = new Error(msg)
self.append(util.format(
'Command: [%s] exited with code: %d timedout: %s', cmd, code,
timedout ? 'yes' : 'no'
))
: `process exited with code: ${code}`

const e = new Error(msg)
const to = timedout ? 'yes' : 'no'
this.append(`Command: ${cmd} exited with code: ${code} timedout: ${to}`)
e.command = cmd
e.opts = opts
self.state = 'failed'
self.update(function() {
this.state = 'failed'
this.update(function() {
cb && cb(e)
})
return
}
self.update(function() {
this.update(function() {
cb && cb()
})
})
}

Build.prototype.gitCommand = function(cmd, dir, cb) {
var self = this
const self = this
if ('function' === typeof dir) cb = dir, dir = process.cwd()
var env = {
const env = {
CI_SERVER: true
, CI_SERVER_NAME: 'GitLab CI'
, CI_SERVER_VERSION: null
Expand All @@ -240,60 +256,76 @@ Build.prototype.gitCommand = function(cmd, dir, cb) {

util._extend(env, process.env)

var opts = {
const opts = {
env: env
, cwd: dir
, timeout: this.opts.timeout
}

log.verbose('[builder]', 'cmd', cmd)
self.append(util.format('\n%s %s\n', self.git, cmd.join(' ')))
var child = spawn(this.git, cmd, opts)
self.append(`\n${self.git} ${cmd.join(' ')}\n`)
const child = spawn(this.git, cmd, opts)
var timedout = false
var timer = setTimeout(function() {
var timer = setTimeout(() => {
timedout = true
child.kill()
self.append('\n** TIMEOUT **\n')
this.append('\n** TIMEOUT **\n')
}, this.opts.timeout)
child.stderr.on('data', function(d) {
var data = d.toString()

child.stderr.on('data', (d) => {
const data = d.toString()
log.silly('[builder]', 'stderr', data)
self.append(data)
this.append(data)
})
child.stdout.on('data', function(d) {
var data = d.toString()

child.stdout.on('data', (d) => {
const data = d.toString()
log.silly('[builder]', 'stdout', data)
self.append(data)
this.append(data)
})
child.on('exit', function(code) {

child.on('error', (err) => {
if (timer) {
clearTimeout(timer)
timer = null
}
const e = new Error(`Command: [${cmd}] failed ${err.message}`)
this.append(e)
log.error(e, err)
this.state = 'failed'
this.update(function() {
cb && cb(e)
})
})

child.on('exit', (code) => {
if (timer) {
clearTimeout(timer)
timer = null
}
if (code !== 0) {
var msg = timedout
? 'process timedout'
: 'process exited with code: '+code
var e = new Error(msg)
self.append(util.format(
'Command: [%s %s] exited with code: %d timedout: %s', self.git,
cmd.join(' '), code, timedout ? 'yes' : 'no'
))
: `process exited with code: ${code}`
const e = new Error(msg)
const to = timedout ? 'yes' : 'no'
this.append(`Command: [${self.git} ${cmd.join(' ')}] exited with code: ` +
`${code} timedout: ${to}`)
e.command = cmd
e.opts = opts
self.state = 'failed'
self.update(function() {
this.state = 'failed'
this.update(function() {
cb && cb(e)
})
return
}
self.update(function() {
this.update(function() {
cb && cb()
})
})
}

Build.prototype.update = function(cb) {
var id = this.opts.id
gcr.client.updateBuild(id, this.state, this.output, cb)
const id = this.opts.id
gcr.client.updateBuild(+id, this.state, this.output, cb)
}
Loading

0 comments on commit a067a97

Please sign in to comment.