|  |  |  | @ -7,11 +7,11 @@ import alfred.web.core.build.BuildContext | 
		
	
		
			
				|  |  |  |  | import alfred.web.core.build.BuildId | 
		
	
		
			
				|  |  |  |  | import alfred.web.core.build.Builds | 
		
	
		
			
				|  |  |  |  | import alfred.web.core.build.ProcessInfo | 
		
	
		
			
				|  |  |  |  | import alfred.web.core.build.Workspace | 
		
	
		
			
				|  |  |  |  | import alfred.web.core.build.Workspaces | 
		
	
		
			
				|  |  |  |  | import org.slf4j.Logger | 
		
	
		
			
				|  |  |  |  | import org.slf4j.LoggerFactory | 
		
	
		
			
				|  |  |  |  | import org.springframework.stereotype.Service | 
		
	
		
			
				|  |  |  |  | import java.nio.file.Path | 
		
	
		
			
				|  |  |  |  | import java.util.concurrent.TimeUnit | 
		
	
		
			
				|  |  |  |  | import kotlin.collections.forEach | 
		
	
		
			
				|  |  |  |  | import kotlin.jvm.java | 
		
	
	
		
			
				
					|  |  |  | @ -26,6 +26,8 @@ class GitRunner( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     val scriptsDir = ".alfred" | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     val scriptFiles = listOf("pre.sh", "job.sh", "post.sh") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     fun run(buildId: BuildId, rev: String): ProcessInfo { | 
		
	
		
			
				|  |  |  |  |         val config = builds.buildConfig(buildId) | 
		
	
		
			
				|  |  |  |  |         val logFile = builds.createLogFile(buildId) | 
		
	
	
		
			
				
					|  |  |  | @ -40,54 +42,56 @@ class GitRunner( | 
		
	
		
			
				|  |  |  |  |             rev = rev | 
		
	
		
			
				|  |  |  |  |         ) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         Thread { | 
		
	
		
			
				|  |  |  |  |         processes.startThread { | 
		
	
		
			
				|  |  |  |  |             workspaces.withWorkspace(ctx) { wsPath -> | 
		
	
		
			
				|  |  |  |  |                 logFile.header(buildId, rev, wsPath) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 clone(ctx, wsPath) | 
		
	
		
			
				|  |  |  |  |                 checkout(ctx, wsPath) | 
		
	
		
			
				|  |  |  |  |                 execScripts(ctx, wsPath) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 logFile.footer() | 
		
	
		
			
				|  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |         }.start() | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         return ProcessInfo(-1, logFile) | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private fun clone(ctx: BuildContext, wsPath: Path) { | 
		
	
		
			
				|  |  |  |  |         ctx.log("build ${ctx.buildId}: cloning ${ctx.config.gitRepo} into $wsPath") | 
		
	
		
			
				|  |  |  |  |     private fun clone(ctx: BuildContext, ws: Workspace) { | 
		
	
		
			
				|  |  |  |  |         ctx.log("build ${ctx.buildId}: cloning ${ctx.config.gitRepo} into $ws") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         val cloneProc = processes.builder(ctx.config, ctx.logFile, "") | 
		
	
		
			
				|  |  |  |  |         val proc = processes.builder(ctx.config, ctx.logFile, "") | 
		
	
		
			
				|  |  |  |  |             .command("git", "clone", ctx.config.gitRepo, ".") | 
		
	
		
			
				|  |  |  |  |             .directory(wsPath.toFile()) | 
		
	
		
			
				|  |  |  |  |             .directory(ws.toFile()) | 
		
	
		
			
				|  |  |  |  |             .start() | 
		
	
		
			
				|  |  |  |  |         handles.add(Handle(cloneProc.toHandle(), ctx.buildId)) | 
		
	
		
			
				|  |  |  |  |         handles.add(Handle(proc.toHandle(), ctx.buildId)) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         val cloneSuccess = cloneProc.waitFor(ctx.config.gitCloneTimeout, TimeUnit.SECONDS) | 
		
	
		
			
				|  |  |  |  |         val cloneSuccess = proc.waitFor(ctx.config.gitCloneTimeout, TimeUnit.SECONDS) | 
		
	
		
			
				|  |  |  |  |         if (!cloneSuccess) { | 
		
	
		
			
				|  |  |  |  |             throw FailedToClone(ctx.buildId, ctx.config.gitRepo ?: "[no repo configured]") | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private fun checkout(ctx: BuildContext, ws: Workspace) { | 
		
	
		
			
				|  |  |  |  |         ctx.log("build ${ctx.buildId}: checkout rev ${ctx.rev}") | 
		
	
		
			
				|  |  |  |  |         val checkoutProc = processes.builder(ctx.config, ctx.logFile, "") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         val proc = processes.builder(ctx.config, ctx.logFile, "") | 
		
	
		
			
				|  |  |  |  |             .command("git", "checkout", ctx.rev) | 
		
	
		
			
				|  |  |  |  |             .directory(wsPath.toFile()) | 
		
	
		
			
				|  |  |  |  |             .directory(ws.toFile()) | 
		
	
		
			
				|  |  |  |  |             .start() | 
		
	
		
			
				|  |  |  |  |         handles.add(Handle(checkoutProc.toHandle(), ctx.buildId)) | 
		
	
		
			
				|  |  |  |  |         handles.add(Handle(proc.toHandle(), ctx.buildId)) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         val checkoutSuccess = checkoutProc.waitFor(ctx.config.gitCloneTimeout, TimeUnit.SECONDS) | 
		
	
		
			
				|  |  |  |  |         val checkoutSuccess = proc.waitFor(ctx.config.gitCloneTimeout, TimeUnit.SECONDS) | 
		
	
		
			
				|  |  |  |  |         if (!checkoutSuccess) { | 
		
	
		
			
				|  |  |  |  |             throw FailedToCheckout(ctx.buildId, ctx.config.gitRepo!!, ctx.rev) | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private fun execScripts(ctx: BuildContext, wsPath: Path) { | 
		
	
		
			
				|  |  |  |  |         val scriptFiles = listOf("pre.sh", "job.sh", "post.sh") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private fun execScripts(ctx: BuildContext, ws: Workspace) { | 
		
	
		
			
				|  |  |  |  |         ctx.log("build ${ctx.buildId}: looking for scripts $scriptFiles in $scriptsDir/") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         scriptFiles.forEach { script -> | 
		
	
		
			
				|  |  |  |  |             val scriptFile = shFile(wsPath, script) | 
		
	
		
			
				|  |  |  |  |             val scriptFile = shFile(ws, script) | 
		
	
		
			
				|  |  |  |  |             if (scriptFile.exists()) { | 
		
	
		
			
				|  |  |  |  |                 ctx.log("build ${ctx.buildId}: found script $script, running it") | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -95,7 +99,7 @@ class GitRunner( | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |                 val scriptProcess = processes.builder(ctx.config, ctx.logFile, ctx.rev) | 
		
	
		
			
				|  |  |  |  |                     .command(scriptFile.absolutePath) | 
		
	
		
			
				|  |  |  |  |                     .directory(wsPath.toFile()) | 
		
	
		
			
				|  |  |  |  |                     .directory(ws.toFile()) | 
		
	
		
			
				|  |  |  |  |                     .start() | 
		
	
		
			
				|  |  |  |  |                 handles.add(Handle(scriptProcess.toHandle(), ctx.buildId)) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -109,8 +113,8 @@ class GitRunner( | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     private fun shFile(wsPath: Path, name: String) = | 
		
	
		
			
				|  |  |  |  |         wsPath.resolve(scriptsDir).resolve(name).toFile() | 
		
	
		
			
				|  |  |  |  |     private fun shFile(ws: Workspace, name: String) = | 
		
	
		
			
				|  |  |  |  |         ws.resolve(scriptsDir).resolve(name).toFile() | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     val logger: Logger = LoggerFactory.getLogger(this::class.java) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | 
 |