protected function cloneRepo() { if (file_exists($this->project->getLocalCVSPath())) { $this->runCommand(sprintf('rm -rf %s', escapeshellarg($this->project->getLocalCVSPath()))); } $this->runCommand(sprintf('/usr/bin/git clone --bare -q %s %s', escapeshellarg($this->project->CVSPath), escapeshellarg($this->project->getLocalCVSPath()))); }
/** * Deploy the given build to the given environment. * * @param DNEnvironment $environment * @param DeploynautLogFile $log * @param DNProject $project * @param array $options */ public function deploy(DNEnvironment $environment, DeploynautLogFile $log, DNProject $project, $options) { $name = $environment->getFullName(); $repository = $project->getLocalCVSPath(); $sha = $options['sha']; $args = array('branch' => $sha, 'repository' => $repository); $this->extend('deployStart', $environment, $sha, $log, $project); $log->write(sprintf('Deploying "%s" to "%s"', $sha, $name)); $this->enableMaintenance($environment, $log, $project); // Use a package generator if specified, otherwise run a direct deploy, which is the default behaviour // if build_filename isn't specified if ($this->packageGenerator) { $log->write(sprintf('Using package generator "%s"', get_class($this->packageGenerator))); try { $args['build_filename'] = $this->packageGenerator->getPackageFilename($project->Name, $sha, $repository, $log); } catch (Exception $e) { $log->write($e->getMessage()); throw $e; } if (empty($args['build_filename'])) { throw new RuntimeException('Failed to generate package.'); } } $command = $this->getCommand('deploy', 'web', $environment, $args, $log); $command->run(function ($type, $buffer) use($log) { $log->write($buffer); }); // Deployment cleanup. We assume it is always safe to run this at the end, regardless of the outcome. $self = $this; $cleanupFn = function () use($self, $environment, $args, $log) { $command = $self->getCommand('deploy:cleanup', 'web', $environment, $args, $log); $command->run(function ($type, $buffer) use($log) { $log->write($buffer); }); if (!$command->isSuccessful()) { $this->extend('cleanupFailure', $environment, $sha, $log, $project); $log->write('Warning: Cleanup failed, but fine to continue. Needs manual cleanup sometime.'); } }; // Once the deployment has run it's necessary to update the maintenance page status if (!empty($options['leaveMaintenancePage'])) { $this->enableMaintenance($environment, $log, $project); } if (!$command->isSuccessful()) { $cleanupFn(); $this->extend('deployFailure', $environment, $sha, $log, $project); throw new RuntimeException($command->getErrorOutput()); } // Check if maintenance page should be removed if (empty($options['leaveMaintenancePage'])) { $this->disableMaintenance($environment, $log, $project); } $cleanupFn(); $log->write(sprintf('Deploy of "%s" to "%s" finished', $sha, $name)); $this->extend('deployEnd', $environment, $sha, $log, $project); }
/** * Output the raw content of the .alerts.yml file from HEAD of a bare repository. * @param DNProject $project * @param string $sha * @return null|string */ public function getAlertsConfigContent($project, $sha) { $command = sprintf('git show --format=raw %s:.alerts.yml', $sha); $process = new Process($command, $project->getLocalCVSPath()); $process->run(); // we don't care if the command wasn't successful, which would be caused by a missing .alerts.yml // sync() will take care of outputting the "No .alerts.yml found" error message to the user. if (!$process->isSuccessful()) { return false; } return $process->getOutput(); }
/** * @return array */ protected function getReferences() { $branches = array(); // Placeholder to put master branch first $firstBranch = null; try { $repository = new Gitonomy\Git\Repository($this->project->getLocalCVSPath()); } catch (Exception $e) { return $branches; } foreach ($repository->getReferences()->getBranches() as $branch) { /** @var DNBranch $obj */ $obj = DNBranch::create($branch, $this->project, $this->data); if ($branch->getName() == 'master') { $firstBranch = array($branch->getName() => $obj); } else { $branches[$branch->getName()] = $obj; } } if ($firstBranch) { $branches = $firstBranch + $branches; } return $branches; }
/** * Find a build in this set by hash. * * @param string $hash * @return DNCommit */ public function byName($hash) { if ($this->loaded === false) { $this->items = $this->getReferences(); $this->loaded = true; } // The item might not be in the list because of the limit, try to find // in an older version and add it to the list. $found = null; foreach ($this->items as $item) { if ($item->SHA() == $hash) { $found = $item; break; } } if ($found === null) { $repository = new Gitonomy\Git\Repository($this->project->getLocalCVSPath()); $commit = new Gitonomy\Git\Commit($repository, $hash); $found = DNCommit::create($commit, $this->project, $this->data); } return $found; }
/** * Deploy the given build to the given environment. * * @param \DNEnvironment $environment * @param \DeploynautLogFile $log * @param \DNProject $project * @param array $options */ public function deploy(\DNEnvironment $environment, \DeploynautLogFile $log, \DNProject $project, $options) { $name = $environment->getFullName(); $repository = $project->getLocalCVSPath(); $sha = $options['sha']; $args = array('branch' => $sha, 'repository' => $repository); $this->extend('deployStart', $environment, $sha, $log, $project); $log->write(sprintf('Deploying "%s" to "%s"', $sha, $name)); $this->enableMaintenance($environment, $log, $project); // Use a package generator if specified, otherwise run a direct deploy, which is the default behaviour // if build_filename isn't specified if ($this->packageGenerator) { $log->write(sprintf('Using package generator "%s"', get_class($this->packageGenerator))); try { $args['build_filename'] = $this->packageGenerator->getPackageFilename($project->Name, $sha, $repository, $log); } catch (Exception $e) { $log->write($e->getMessage()); throw $e; } if (empty($args['build_filename'])) { throw new RuntimeException('Failed to generate package.'); } } $command = $this->getCommand('deploy', 'web', $environment, $args, $log); $command->run(function ($type, $buffer) use($log) { $log->write($buffer); }); $error = null; $deploySuccessful = $command->isSuccessful(); if ($deploySuccessful) { // Deployment automatically removes .htaccess, i.e. disables maintenance. Fine to smoketest. $deploySuccessful = $this->smokeTest($environment, $log); } if (!$deploySuccessful) { $this->enableMaintenance($environment, $log, $project); $rollbackSuccessful = $this->deployRollback($environment, $log, $project, $options, $args); if ($rollbackSuccessful) { // Again, .htaccess removed, maintenance off. $rollbackSuccessful = $this->smokeTest($environment, $log); } if (!$rollbackSuccessful) { $this->enableMaintenance($environment, $log, $project); $currentBuild = $environment->CurrentBuild(); $this->extend('deployRollbackFailure', $environment, $currentBuild, $log, $project); $log->write('Rollback failed'); $error = $command->getErrorOutput(); } else { $error = 'Rollback successful'; } } // Regardless of outcome, try to clean up. $cleanup = $this->getCommand('deploy:cleanup', 'web', $environment, $args, $log); $cleanup->run(function ($type, $buffer) use($log) { $log->write($buffer); }); if (!$cleanup->isSuccessful()) { $this->extend('cleanupFailure', $environment, $sha, $log, $project); $log->write('Warning: Cleanup failed, but fine to continue. Needs manual cleanup sometime.'); } $this->extend('deployEnd', $environment, $sha, $log, $project); if ($error !== null) { throw new RuntimeException($error); } $log->write(sprintf('Deploy of "%s" to "%s" finished', $sha, $name)); }