public function fire($job, $message) { $siteId = $message['siteId']; $buildId = $message['id']; $branch = $message['branch']; $dc = new DC($siteId); $df = new DeployInfo($siteId); $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId; $commitRoot = "{$root}/commit/"; $branchPath = "{$commitRoot}/{$branch}"; $gitOrigin = $dc->get(DC::GIT_ORIGIN); $buildCommand = 'make deploy'; $defaultBranch = 'default'; $developRoot = "{$root}/branch/{$defaultBranch}"; Log::info("\n---------------------------\njob id : {$job->getJobId()} start"); $progress = 0; $redis = app('redis')->connection(); $lock = new \Eleme\Rlock\Lock($redis, JobLock::buildLock($developRoot), array('timeout' => 600000, 'blocking' => false)); if (!$lock->acquire()) { Log::info("Job : {$job->getJobId()} Release"); $job->release(30); return; } try { if (!File::exists($developRoot)) { Log::info('Git clone'); (new Process('mkdir -p ' . $commitRoot))->mustRun(); (new Process('mkdir -p ' . $developRoot))->mustRun(); (new Process('git clone ' . $gitOrigin . ' ' . $developRoot . ' --depth 20'))->setTimeout(600)->mustRun(); } $build = $df->get($buildId); $build['result'] = 'Fetch Origin'; $build['last_time'] = date('Y-m-d H:i:s'); $df->save($build); Log::info("git fetch origin"); (new Process("git fetch origin", $developRoot))->setTimeout(600)->mustRun(); $progress = 1; (new Process("cp -r {$developRoot} {$branchPath}", $commitRoot))->mustRun(); $revParseProcess = new Process("git rev-parse origin/{$branch}", $branchPath); $revParseProcess->run(); if (!$revParseProcess->isSuccessful()) { throw new Exception('Error Message : ' . $revParseProcess->getErrorOutput()); } $commit = trim($revParseProcess->getOutput()); $commitPath = "{$commitRoot}/{$commit}"; $build['result'] = 'Building'; $build['last_time'] = date('Y-m-d H:i:s'); $df->save($build); $needBuild = true; if ($commit !== $branch) { if (File::exists($commitPath)) { File::deleteDirectory($branchPath); $needBuild = false; } else { $progress = 2; File::move($branchPath, $commitPath); } } if ($needBuild) { Log::info("Build {$siteId} branch: {$branch}"); (new Process("git checkout {$commit}", $commitPath))->mustRun(); Log::info("make deploy"); (new Process($buildCommand, $commitPath))->setTimeout(600)->mustRun(); } (new CommitVersion($siteId))->add($commit); $build['commit'] = $commit; $build['result'] = 'Build Success'; $build['last_time'] = date('Y-m-d H:i:s'); $df->save($build); Log::info($job->getJobId() . " finish\n---------------------------"); } catch (Exception $e) { $build['errMsg'] = $e->getMessage(); $build['result'] = 'Error'; $build['last_time'] = date('Y-m-d H:i:s'); $df->save($build); switch ($progress) { case 2: (new Process('rm -rf ' . $commitPath))->run(); case 1: (new Process('rm -rf ' . $branchPath))->run(); } Log::error($e->getMessage()); Log::info($job->getJobId() . " Error Finish\n---------------------------"); } $lock->release(); $job->delete(); }
public function fire($job, $message) { Log::info("\n---------------------------\njob id : {$job->getJobId()} start"); $commit = $message['commit']; $siteId = $message['siteId']; $pr = new PullRequest($siteId); $commitInfo = $pr->get($commit); $repoName = $commitInfo->repo; $gitOrigin = "git@github.com:{$repoName}.git"; $dc = new DC($siteId); $branch = $commitInfo->branch; $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId; $branchRoot = "{$root}/pull_requests/repo/{$repoName}"; $commitPath = "{$root}/pull_requests/commit/{$commit}"; $progress = 0; $cmd = ''; $lock = new Eleme\Rlock\Lock(app('redis')->connection(), JobLock::pullRequestBuildLock($repoName), array('timeout' => 600000, 'blocking' => false)); if (!$lock->acquire()) { Log::info("Job locked, now {$job->getJobId()} Release"); $job->release(30); return; } try { if (!File::exists($branchRoot)) { Log::info('Git clone'); $cmd = 'mkdir -p ' . $branchRoot; (new Process($cmd))->mustRun(); $cmd = "mkdir -p {$root}/pull_requests/commit/"; (new Process($cmd))->mustRun(); $progress = 1; $cmd = "git clone {$gitOrigin} {$branchRoot} --depth 10"; (new Process($cmd))->setTimeout(600)->mustRun(); $progress = 2; } Log::info("git fetch origin"); $cmd = "git fetch -f origin {$branch}:{$branch} --depth 20"; (new Process($cmd, $branchRoot))->setTimeout(600)->mustRun(); if (File::exists($commitPath)) { $cmd = "rm -rf {$commitPath}"; (new Process($cmd))->setTimeout(600)->mustRun(); } $progress = 3; $cmd = "cp -r {$branchRoot} {$commitPath}"; Log::info($cmd); (new Process($cmd))->setTimeout(600)->mustRun(); $cmd = "git checkout {$branch}"; Log::info($cmd); (new Process($cmd, $commitPath))->mustRun(); $cmd = "git checkout {$commit}"; Log::info($cmd); (new Process($cmd, $commitPath))->mustRun(); $commitInfo->buildStatus = 'Building'; $pr->save($commitInfo); $progress = 4; $cmd = $dc->get(DC::BUILD_COMMAND); Log::info($cmd); (new Process($cmd, $commitPath))->setTimeout(600)->mustRun(); $commitInfo->buildStatus = 'Success'; $pr->save($commitInfo); $progress = 5; $commitInfo->testStatus = 'Testing'; $pr->save($commitInfo); $cmd = $dc->get(DC::TEST_COMMAND); if (!empty($cmd)) { Log::info($cmd); (new Process($cmd, $commitPath))->setTimeout(600)->mustRun(); } $commitInfo->testStatus = 'Success'; $pr->save($commitInfo); } catch (Exception $e) { Log::info("ERROR!!! : " . $e->getMessage()); $commitInfo->buildStatus = 'Error'; $commitInfo->testStatus = 'Error'; $commitInfo->errorMsg = "Command : {$cmd}\nError Message : {$e->getMessage()}"; switch ($progress) { case 5: $commitInfo->buildStatus = 'Success'; break; case 4: (new Process("rm -rf {$commitPath}"))->run(); case 3: case 2: $commitInfo->testStatus = 'Abort'; break; case 1: (new Process("rm -rf {$branchRoot}"))->run(); $commitInfo->testStatus = 'Abort'; break; } $pr->save($commitInfo); } $lock->release(); Log::info("progress : {$progress}"); Log::info("job id : {$job->getJobId()} finish"); $job->delete(); }
public function fire($job, $message) { $this->warnings = array(); $commit = $message['commit']; $hostType = $message['hostType']; $siteId = $message['siteId']; $dc = new DC($siteId); $staticDir = $dc->get(DC::STATIC_DIR); if (isset($message['type']) && $message['type'] == self::TYPE_PULL_REQUEST) { $id = $message['id']; $this->type = self::TYPE_PULL_REQUEST; $this->pr = new PullRequestDeploy($siteId); $this->prDeployInfo = $this->pr->get($id); $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/pull_requests'; $commitPath = "{$root}/commit/{$commit}"; } else { $this->type = self::TYPE_NORMAL_DEPLOY; $this->dfManger = new DeployInfo($siteId); $id = $message['id']; $this->deployInfo = $this->dfManger->get($id); $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/commit'; $commitPath = "{$root}/{$commit}"; } $LOCAL_STATIC_DIR = "{$commitPath}/{$staticDir}"; $LOCAL_DIR = $commitPath; $remoteUser = $dc->get(DC::REMOTE_USER); $remoteOwner = $dc->get(DC::REMOTE_OWNER); $RSYNC_EXCLUDE = "{$commitPath}/" . $dc->get(DC::RSYNC_EXCLUDE); $REMOTE_STATIC_DIR = $dc->get(DC::REMOTE_STATIC_DIR); $REMOTE_DIR = $dc->get(DC::REMOTE_APP_DIR); $staticScript = ScriptCommand::complie($dc->get(DC::DEPLOY_STATIC_SCRIPT), $siteId); $webScript = ScriptCommand::complie($dc->get(DC::DEPLOY_WEB_SCRIPT), $siteId); $this->updateStatus('Deploying'); Log::info("\n---------------------------\njob id : {$job->getJobId()} start "); Log::info("commit deploy: {$commit}"); //本地同步锁,不能在同一个commit下同步 $redis = app('redis')->connection(); $commitLock = new \Eleme\Rlock\Lock($redis, JobLock::buildLock($commitPath), array('timeout' => 600000, 'blocking' => false)); if (!$commitLock->acquire()) { Log::info("Job : {$job->getJobId()} Release"); $job->release(30); } $rsyLock = NULL; try { $hosts = (new SiteHost($siteId, $hostType, SiteHost::STATIC_HOST))->getList(); $staticHosts = new SplQueue(); foreach ($hosts as $h) { $staticHosts->push($h); } $hosts = (new SiteHost($siteId, $hostType, SiteHost::WEB_HOST))->getList(); $webHosts = new SplQueue(); foreach ($hosts as $h) { $webHosts->push($h); } /***************************************** * * 执行静态文件同步 * *****************************************/ //执行同步前本地命令 $this->processCommands($staticScript['before']['handle']); while (!$staticHosts->isEmpty()) { $host = $staticHosts->shift(); $rsyLock = new \Eleme\Rlock\Lock($redis, JobLock::rsyLock($host['hostip']), array('timeout' => 600000, 'blocking' => false)); if ($rsyLock->acquire()) { try { $HOST_NAME = $host['hostname']; //执行同步前每次都执行的本地命令 $this->processCommands($staticScript['before']['local']); //执行同步前每次都执行的远端命令 $this->processCommands($staticScript['before']['remote'], $HOST_NAME); Log::info("deploying static files to {$HOST_NAME}."); (new Process($this->remoteProcess($HOST_NAME, "sudo mkdir -p {$REMOTE_STATIC_DIR}")))->mustRun(); (new Process($this->remoteProcess($HOST_NAME, "sudo chown {$remoteUser} -R {$REMOTE_STATIC_DIR}")))->mustRun(); (new Process("rsync -az --progress --force --delay-updates --exclude-from={$RSYNC_EXCLUDE} {$LOCAL_STATIC_DIR}/ {$HOST_NAME}:{$REMOTE_STATIC_DIR}/", $commitPath))->setTimeout(600)->mustRun(); (new Process($this->remoteProcess($HOST_NAME, "sudo chown {$remoteOwner} -R {$REMOTE_STATIC_DIR}")))->mustRun(); //执行同步后每次都执行的本地命令 $this->processCommands($staticScript['after']['local']); //执行同步后每次都执行的远端命令 $this->processCommands($staticScript['after']['remote'], $HOST_NAME); $rsyLock->release(); } catch (Exception $e) { $rsyLock->release(); throw $e; } } else { // 正在同步,重新放回队列 $staticHosts->push($host); } } //执行同步后本地命令 $this->processCommands($staticScript['after']['handle']); /***************************************** * * 执行WEB应用同步 * *****************************************/ //执行同步前本地命令 $this->processCommands($webScript['before']['handle']); while (!$webHosts->isEmpty()) { $host = $webHosts->shift(); $rsyLock = new \Eleme\Rlock\Lock($redis, JobLock::rsyLock($host['hostip']), array('timeout' => 600000, 'blocking' => false)); if ($rsyLock->acquire()) { try { $HOST_NAME = $host['hostname']; //执行同步前每次都执行的本地命令 $this->processCommands($webScript['before']['local']); //执行同步前每次都执行的远端命令 $this->processCommands($webScript['before']['remote'], $HOST_NAME); Log::info("deploying web apps to {$HOST_NAME}."); (new Process($this->remoteProcess($HOST_NAME, "sudo mkdir -p {$REMOTE_DIR}")))->mustRun(); (new Process($this->remoteProcess($HOST_NAME, "sudo chown {$remoteUser} -R {$REMOTE_DIR}")))->mustRun(); (new Process("rsync -azq --progress --force --delete --delay-updates --exclude-from={$RSYNC_EXCLUDE} {$LOCAL_DIR}/ {$HOST_NAME}:{$REMOTE_DIR}/", $commitPath))->setTimeout(600)->mustRun(); (new Process($this->remoteProcess($HOST_NAME, "sudo chown {$remoteOwner} -R {$REMOTE_DIR}")))->mustRun(); //执行同步后每次都执行的本地命令 $this->processCommands($webScript['after']['local']); //执行同步后每次都执行的远端命令 $this->processCommands($webScript['after']['remote'], $HOST_NAME); $rsyLock->release(); } catch (Exception $e) { $rsyLock->release(); throw $e; } } else { $webHosts->push($host); } } //执行同步后本地命令 $this->processCommands($webScript['after']['handle']); $errMsg = ''; foreach ($this->warnings as $w) { $errMsg .= "{$w}\n"; } $errMsg = empty($errMsg) ? null : $errMsg; $this->updateStatus('Deploy Success', $errMsg); Log::info($job->getJobId() . " finish"); } catch (Exception $e) { //if ($rsyLock != null) $rsyLock->release(); $this->updateStatus('Error', "file : " . $e->getFile() . "\nline : " . $e->getLine() . "\n Error Msg : " . $e->getMessage()); Log::error($e->getMessage()); Log::info($job->getJobId() . " Error Finish\n---------------------------"); } $commitLock->release(); $job->delete(); }
public function fire(Worker $worker, $message) { $this->warnings = array(); $commit = $message['commit']; $hostType = $message['hostType']; $siteId = $message['siteId']; $dc = new DC($siteId); $staticDir = $dc->get(DC::STATIC_DIR); $gitOrigin = $dc->get(DC::GIT_ORIGIN); if (isset($message['type']) && $message['type'] == self::TYPE_PULL_REQUEST) { $id = $message['id']; $this->type = self::TYPE_PULL_REQUEST; $this->pr = new PullRequestDeploy($siteId); $this->prDeployInfo = $this->pr->get($id); $operateUser = $this->prDeployInfo->operateUser; $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/pull_requests'; $commitPath = "{$root}/commit/{$commit}"; } else { $this->type = self::TYPE_NORMAL_DEPLOY; $this->dfManger = new DeployInfo($siteId); $id = $message['id']; $this->deployInfo = $this->dfManger->get($id); $operateUser = $this->deployInfo['user']; $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/commit'; $commitPath = "{$root}/{$commit}"; } $LOCAL_STATIC_DIR = "{$commitPath}/{$staticDir}/"; $LOCAL_DIR = $commitPath . '/'; $remoteUser = $dc->get(DC::REMOTE_USER); $remoteOwner = $dc->get(DC::REMOTE_OWNER); $ifContent = $dc->get(DC::IDENTIFYFILE); if (!empty($ifContent)) { $passphrase = $dc->get(DC::PASSPHRASE); $identifyfile = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/identify.key'; file_put_contents($identifyfile, $ifContent); chmod($identifyfile, 0600); } else { $passphrase = null; $identifyfile = null; } $RSYNC_EXCLUDE = "{$commitPath}/" . $dc->get(DC::RSYNC_EXCLUDE); $REMOTE_STATIC_DIR = $dc->get(DC::REMOTE_STATIC_DIR) . '/'; $REMOTE_DIR = $dc->get(DC::REMOTE_APP_DIR) . '/'; $staticScript = ScriptCommand::complie($dc->get(DC::DEPLOY_STATIC_SCRIPT), $siteId); $webScript = ScriptCommand::complie($dc->get(DC::DEPLOY_WEB_SCRIPT), $siteId); Log::info("--- {$worker->getJobId()} ---"); Log::info("Commit deploy: {$commit}"); //本地同步锁 $redis = app('redis')->connection(); $commitLock = new \Eleme\Rlock\Lock($redis, JobLock::buildLock($siteId . $hostType), array('timeout' => 600000, 'blocking' => false)); if (!$commitLock->acquire()) { Log::info("worker : {$worker->getJobId()} Release"); $worker->release(30); return; } $this->updateStatus('Deploying'); $rsyLock = NULL; try { $REMOTE_DIR = $this->clearDirString($REMOTE_DIR); $REMOTE_STATIC_DIR = $this->clearDirString($REMOTE_STATIC_DIR); $hosts = (new SiteHost($siteId, $hostType, SiteHost::STATIC_HOST))->getList(); $staticHosts = new SplQueue(); foreach ($hosts as $h) { $staticHosts->push($h); } $hosts = (new SiteHost($siteId, $hostType, SiteHost::WEB_HOST))->getList(); $webHosts = new SplQueue(); foreach ($hosts as $h) { $webHosts->push($h); } /***************************************** * * 执行静态文件同步 * *****************************************/ $worker->report(''); //执行同步前本地命令 $this->processCommands($staticScript['before']['handle']); while (!$staticHosts->isEmpty()) { $host = $staticHosts->shift(); $rsyLock = new \Eleme\Rlock\Lock($redis, JobLock::rsyLock($host['hostip']), array('timeout' => 180000, 'blocking' => false)); $worker->report(''); if ($rsyLock->acquire()) { try { $HOST_NAME = $host['hostname']; $PORT = $host['hostport']; //执行同步前每次都执行的本地命令 $this->processCommands($staticScript['before']['local']); //执行同步前每次都执行的远端命令 $this->processCommands($staticScript['before']['remote'], $HOST_NAME, $host['hostip'], $remoteUser, $identifyfile, $passphrase, $PORT); Log::info("deploying static files to {$HOST_NAME}."); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo mkdir -p {$REMOTE_STATIC_DIR}", $identifyfile, $passphrase, null, $PORT); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo chown {$remoteUser} -R {$REMOTE_STATIC_DIR}", $identifyfile, $passphrase, null, $PORT); $this->rsyncProcess($HOST_NAME, $host['hostip'], $remoteUser, $RSYNC_EXCLUDE, $LOCAL_STATIC_DIR, $REMOTE_STATIC_DIR, RsyncProcess::KEEP_FILES, $identifyfile, $passphrase, $commitPath, $PORT); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo chown {$remoteOwner} -R {$REMOTE_STATIC_DIR}", $identifyfile, $passphrase, null, $PORT); //执行同步后每次都执行的本地命令 $this->processCommands($staticScript['after']['local']); //执行同步后每次都执行的远端命令 $this->processCommands($staticScript['after']['remote'], $HOST_NAME, $host['hostip'], $remoteUser, $identifyfile, $passphrase, $PORT); $rsyLock->release(); } catch (Exception $e) { $rsyLock->release(); throw $e; } } else { // 正在同步,重新放回队列 $staticHosts->push($host); } } //执行同步后本地命令 $this->processCommands($staticScript['after']['handle']); /***************************************** * * 执行WEB应用同步 * *****************************************/ //执行同步前本地命令 $this->processCommands($webScript['before']['handle']); while (!$webHosts->isEmpty()) { $host = $webHosts->shift(); $worker->report(''); $rsyLock = new \Eleme\Rlock\Lock($redis, JobLock::rsyLock($host['hostip']), array('timeout' => 180000, 'blocking' => false)); if ($rsyLock->acquire()) { try { $HOST_NAME = $host['hostname']; $PORT = $host['hostport']; //执行同步前每次都执行的本地命令 $this->processCommands($webScript['before']['local']); //执行同步前每次都执行的远端命令 $this->processCommands($webScript['before']['remote'], $HOST_NAME, $host['hostip'], $remoteUser, $identifyfile, $passphrase, $PORT); Log::info("deploying web apps to {$HOST_NAME}."); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo mkdir -p {$REMOTE_DIR}", $identifyfile, $passphrase, null, $PORT); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo chown {$remoteUser} -R {$REMOTE_DIR}", $identifyfile, $passphrase, null, $PORT); $this->rsyncProcess($HOST_NAME, $host['hostip'], $remoteUser, $RSYNC_EXCLUDE, $LOCAL_DIR, $REMOTE_DIR, RsyncProcess::FORCE_DELETE, $identifyfile, $passphrase, $commitPath, $PORT); $this->sshProcess($HOST_NAME, $host['hostip'], $remoteUser, "sudo chown {$remoteOwner} -R {$REMOTE_DIR}", $identifyfile, $passphrase, null, $PORT); //执行同步后每次都执行的本地命令 $this->processCommands($webScript['after']['local']); //执行同步后每次都执行的远端命令 $this->processCommands($webScript['after']['remote'], $HOST_NAME, $host['hostip'], $remoteUser, $identifyfile, $passphrase, $PORT); $rsyLock->release(); } catch (Exception $e) { $rsyLock->release(); throw $e; } } else { $webHosts->push($host); } } $worker->report(''); //执行同步后本地命令 $this->processCommands($webScript['after']['handle']); $errMsg = ''; foreach ($this->warnings as $w) { $errMsg .= "{$w}\n"; } $errMsg = empty($errMsg) ? null : $errMsg; $this->updateStatus('Deploy Success', $errMsg); Log::info($worker->getJobId() . " finish"); $pc = new \PrevCommit($siteId, $hostType); $prevCommit = $pc->get(); try { preg_match('/github\\.com:(.+?)\\.git$/i', $gitOrigin, $matchs); $repoName = $matchs[1]; $token = $dc->get(DC::HIPCHAT_TOKEN); $room = $dc->get(DC::HIPCHAT_ROOM); if (!empty($token) && !empty($room)) { $client = new HipChat($token, $room); $diffUrl = ''; if (!empty($prevCommit) && $prevCommit != $commit) { $diffUrl = "Diff: https://github.com/{$repoName}/compare/{$prevCommit}...{$commit}"; } $notify = <<<EOT Message: Deploy {$siteId} to {$hostType} Success Deploy Id: {$id} Operater: {$operateUser} Status: Success Host Type: {$hostType} Commit: {$commit} {$diffUrl} EOT; $client->notify($notify); Log::info('Hipchat Notify Send Sucess'); } $logins = Watch::allUserWatching($siteId); $emails = array(); foreach ($logins as $login) { $user = GithubUser::loadFromRedis($login); $emails[] = $user->email; } if (count($emails) > 0) { $mailer = Mail::getSwiftMailer(); $transport = $mailer->getTransport(); $transport->stop(); $transport->start(); Mail::send('emails.deploy', array('siteId' => $siteId, 'status' => 'Success', 'hostType' => $hostType, 'commit' => $commit, 'repoName' => $matchs[1], 'user' => $operateUser, 'id' => $id, 'prevCommit' => $prevCommit), function ($message) use($emails) { $email = array_pop($emails); $message->to($email)->subject('Deploy Success!'); foreach ($emails as $email) { $message->cc($email); } }); Log::info('Email Notify Send Success'); } } catch (Exception $e) { Log::error("Notify Error:\n" . $e); } $rmpath = app_path() . '/storage/views/*'; $this->process('sudo rm -rf ' . $rmpath, null, false); $rmpath = app_path() . '/storage/cache/*'; $this->process('sudo rm -rf ' . $rmpath, null, false); $rmpath = app_path() . '/storage/meta/*'; $this->process('sudo rm -rf ' . $rmpath, null, false); $pc->set($commit); } catch (Exception $e) { //if ($rsyLock != null) $rsyLock->release(); $errMsg = $worker->getJobId() . " error : " . $e->getMessage() . "\n"; $this->updateStatus('Error', $errMsg, null, $errMsg); Log::error($e); Log::info($worker->getJobId() . " Error Finish\n---------------------------"); } $commitLock->release(); //if (!empty($identifyfile)) $this->process('rm -f ' . $identifyfile, false); }
public function fire(Worker $worker, $message) { Log::info("--- Pull Request Build Start ---"); $commit = $message['commit']; $pullNumber = $message['pullNumber']; $siteId = $message['siteId']; $pr = new PullRequest($siteId); $commitInfo = $pr->get($commit); $repoName = $commitInfo->repo; $gitOrigin = "git@github.com:{$repoName}.git"; $dc = new DC($siteId); $branch = $commitInfo->branch; $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId; $ifContent = $dc->get(DC::IDENTIFYFILE); if (!empty($ifContent)) { $passphrase = $dc->get(DC::PASSPHRASE); $identifyfile = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId . '/identify.key'; if (!File::exists($identifyfile)) { file_put_contents($identifyfile, $ifContent); chmod($identifyfile, 0600); } } else { $passphrase = null; $identifyfile = null; } $defaultBranch = "{$root}/branch/default"; $prDefaultBranch = "{$root}/branch/pruse"; $branchRoot = "{$root}/pull_requests/repo/{$repoName}"; $commitPath = "{$root}/pull_requests/commit/{$commit}"; $progress = 0; $cmd = ''; $lock1 = null; $lock2 = null; try { $lock2 = new \Eleme\Rlock\Lock(app('redis')->connection(), JobLock::pullRequestBuildLock($prDefaultBranch), array('timeout' => 600000, 'blocking' => false)); if (!$lock2->acquire()) { Log::info("Job locked, now {$worker->getJobId()} Release"); $worker->release(30); return; } if (!File::exists($prDefaultBranch)) { // 可能跟build branch冲突 $lock1 = new \Eleme\Rlock\Lock(app('redis')->connection(), JobLock::buildLock($defaultBranch), array('timeout' => 600000, 'blocking' => false)); if (!$lock1->acquire()) { Log::info("Job locked, now {$worker->getJobId()} Release"); $worker->release(30); return; } Log::info('init pull request branch'); $mcd = 'mkdir -p ' . $prDefaultBranch; (new Process($cmd))->mustRun(); $cmd = "mkdir -p {$root}/pull_requests/commit/"; (new Process($cmd))->mustRun(); $progress = 1; $cmd = "cp -r {$defaultBranch} {$prDefaultBranch}"; (new Process($cmd))->mustRun(); $progress = 2; $lock1->release(); $lock1 = null; } if (!File::exists($commitPath)) { $cmd = "git fetch -f origin +refs/pull/{$pullNumber}/head"; Log::info($cmd . " " . $prDefaultBranch); (new GitProcess($cmd, $prDefaultBranch, $identifyfile, $passphrase, 600))->setTimeout(600)->mustRun(); $progress = 3; $cmd = "cp -r {$prDefaultBranch} {$commitPath}"; Log::info($cmd); (new Process($cmd))->mustRun(); } $lock2->release(); $lock2 = null; $cmd = "git checkout -qf FETCH_HEAD"; Log::info($cmd); (new Process($cmd, $commitPath))->mustRun(); $commitInfo->buildStatus = 'Building'; $pr->save($commitInfo); $progress = 4; $cmd = $dc->get(DC::BUILD_COMMAND) ?: 'make deploy'; Log::info($cmd); (new Process($cmd, $commitPath))->setTimeout(600)->mustRun(); $commitInfo->buildStatus = 'Success'; $pr->save($commitInfo); try { $progress = 5; $commitInfo->testStatus = 'Testing'; $pr->save($commitInfo); $cmd = $dc->get(DC::TEST_COMMAND); if (!empty($cmd)) { Log::info($cmd); (new Process($cmd, $commitPath))->setTimeout(600)->mustRun(); } } catch (Exception $e) { $this->sendStatus($siteId, $dc->get(DC::GITHUB_TOKEN), $dc->get(DC::GIT_ORIGIN), $commit, 'failure', 'Test Failure'); throw new Exception($e->getMessage(), 1379); } $commitInfo->testStatus = 'Success'; $pr->save($commitInfo); $this->sendStatus($siteId, $dc->get(DC::GITHUB_TOKEN), $dc->get(DC::GIT_ORIGIN), $commit, 'success', 'Build and Test Success'); } catch (Exception $e) { if ($e->getCode() != 1379) { $this->sendStatus($siteId, $dc->get(DC::GITHUB_TOKEN), $dc->get(DC::GIT_ORIGIN), $commit, 'error', 'Job Error'); } if ($lock1 !== null) { $lock1->release(); } if ($lock2 !== null) { $lock2->release(); } Log::info("ERROR!!! : " . $e->getMessage()); $commitInfo->buildStatus = 'Error'; $commitInfo->testStatus = 'Error'; $commitInfo->errorMsg = "Command : {$cmd}\nError Message : {$e->getMessage()}"; switch ($progress) { case 5: $commitInfo->buildStatus = 'Success'; break; case 4: (new Process("rm -rf {$commitPath}"))->run(); case 3: case 2: $commitInfo->testStatus = 'Abort'; break; case 1: $cmd = "rm -rf {$root}/pull_requests/commit/"; (new Process($cmd))->run(); (new Process("rm -rf {$prDefaultBranch}"))->run(); $commitInfo->testStatus = 'Abort'; break; } $pr->save($commitInfo); } Log::info("progress : {$progress}"); Log::info("worker id : {$worker->getJobId()} finish"); //if (!empty($identifyfile)) (new Process('rm -f ' . $identifyfile))->run(); }
public function fire(Worker $worker, $message) { Log::info("--- BuildBranchJob Start ---"); $siteId = $message['siteId']; $buildId = $message['id']; $branch = $message['branch']; $dc = new DC($siteId); $this->infoManage = new DeployInfo($siteId); $root = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId; $commitRoot = "{$root}/commit/"; $branchPath = "{$commitRoot}/{$branch}"; $gitOrigin = $dc->get(DC::GIT_ORIGIN); $buildCommand = $dc->get(DC::BUILD_COMMAND) ?: 'make deploy'; $defaultBranch = 'default'; $developRoot = "{$root}/branch/{$defaultBranch}"; $progress = 0; $redis = app('redis')->connection(); $lock = new \Eleme\Rlock\Lock($redis, JobLock::buildLock($developRoot), array('timeout' => 600000, 'blocking' => false)); if (!$lock->acquire()) { Log::info("Job locked, now {$worker->getJobId()} Release"); $worker->release(30); return; } try { $this->deployInfo = $this->infoManage->get($buildId); $ifContent = $dc->get(DC::IDENTIFYFILE); if (!empty($ifContent)) { $passphrase = $dc->get(DC::PASSPHRASE); $sitePath = (new SystemConfig())->get(SystemConfig::WORK_ROOT_FIELD) . '/' . $siteId; if (!File::exists($sitePath)) { $this->process('mkdir -p ' . $sitePath); } $identifyfile = $sitePath . '/identify.key'; file_put_contents($identifyfile, $ifContent); chmod($identifyfile, 0600); } else { $passphrase = null; $identifyfile = null; } if (!File::exists($developRoot)) { $this->refreshStatus('Clone Repo'); $worker->report(''); $createWait = 1; $this->process('mkdir -p ' . $commitRoot); $this->process('mkdir -p ' . $developRoot); $this->gitProcess('git clone ' . $gitOrigin . ' ' . $developRoot, $developRoot, $identifyfile, $passphrase); unset($createWait); } $this->refreshStatus('Fetch Origin'); $worker->report(''); $this->gitProcess("git fetch origin", $developRoot, $identifyfile, $passphrase); $progress = 1; $this->process("cp -r {$developRoot} {$branchPath}", $commitRoot); $revParseProcess = $this->process("git rev-parse origin/{$branch}", $branchPath); $commit = trim($revParseProcess->getOutput()); $commitPath = "{$commitRoot}/{$commit}"; $needBuild = true; if ($commit !== $branch) { if (File::exists($commitPath)) { File::deleteDirectory($branchPath); $needBuild = false; } else { $progress = 2; File::move($branchPath, $commitPath); } } if ($needBuild) { $this->refreshStatus('Building', false); Log::info("Build {$siteId} branch: {$branch}"); $this->process("git checkout {$commit}", $commitPath); $worker->report(''); $this->process($buildCommand, $commitPath); } (new CommitVersion($siteId))->add($commit); $this->deployInfo['commit'] = $commit; $this->refreshStatus('Build Success'); Log::info('--- ' . $worker->getJobId() . " finish ---"); } catch (Exception $e) { Log::error($e); Log::info('--- ' . $worker->getJobId() . " ERROR ---"); //$this->deployInfo['errMsg'] = $e->getFile() . ' '. $e->getLine() . ' : ' . $e->getMessage(); $this->deployInfo['errOut'] = $worker->getJobId() . " error : " . $e->getMessage() . "\n"; $this->refreshStatus('Error', false); switch ($progress) { case 2: $this->process('rm -rf ' . $commitPath); case 1: $this->process('rm -rf ' . $branchPath); } if (isset($createWait) && $createWait == 1) { $this->process('rm -rf ' . $developRoot); $this->process('rm -rf ' . $commitRoot); } } $lock->release(); Log::info("--- BuildBranchJob End ---"); //if (!empty($identifyfile)) $this->process('rm -f ' . $identifyfile, false); }