/** * Builds a project. * * @param Project $project A Project instance * @param string $revision The revision to build (or null for the latest revision) * @param integer $flags Flags (a combinaison of FORCE_BUILD, LOCAL_BUILD, and SILENT_BUILD) * @param mixed $callback A PHP callback */ public function build(Project $project, $revision = null, $flags = 0, $callback = null) { // project already has a running build if ($project->isBuilding() && Sismo::FORCE_BUILD !== ($flags & Sismo::FORCE_BUILD)) { return; } $this->builder->init($project, $callback); list($sha, $author, $date, $message) = $this->builder->prepare($revision, Sismo::LOCAL_BUILD !== ($flags & Sismo::LOCAL_BUILD)); $commit = $this->storage->getCommit($project, $sha); // commit has already been built if ($commit && $commit->isBuilt() && Sismo::FORCE_BUILD !== ($flags & Sismo::FORCE_BUILD)) { return; } $commit = $this->storage->initCommit($project, $sha, $author, \DateTime::createFromFormat('Y-m-d H:i:s O', $date), $message); $process = $this->builder->build(); if (!$process->isSuccessful()) { $commit->setStatusCode('failed'); $commit->setOutput(sprintf("[31mBuild failed[0m\n\n[33mOutput[0m\n%s\n\n[33m Error[0m%s", $process->getOutput(), $process->getErrorOutput())); } else { $commit->setStatusCode('success'); $commit->setOutput($process->getOutput()); } $this->storage->updateCommit($commit); if (Sismo::SILENT_BUILD !== ($flags & Sismo::SILENT_BUILD)) { foreach ($project->getNotifiers() as $notifier) { $notifier->notify($commit); } } }
public function testNotify() { $project = new Project('Twig'); $failedCommit = new Commit($project, '123456'); $failedCommit->setAuthor('Fabien'); $failedCommit->setMessage('Foo'); $successCommit = new Commit($project, '123455'); $successCommit->setAuthor('Fabien'); $successCommit->setMessage('Bar'); $successCommit->setStatusCode('success'); $baseNotifier = $this->getMock('Sismo\\Notifier\\Notifier'); $baseNotifier->expects($this->once())->method('notify')->will($this->returnValue('foo')); $notifier = new CrossFingerNotifier(array($baseNotifier)); //a failed commit should call notify on real notifier $this->assertTrue($notifier->notify($failedCommit)); $project->setCommits(array($successCommit)); //a success commit should not call notify on real notifier $this->assertFalse($notifier->notify($successCommit)); }
public function testNotify() { $project = new Project('Twig'); $successCommit = new Commit($project, '123455'); $successCommit->setAuthor('Fabien'); $successCommit->setMessage('Bar'); $successCommit->setStatusCode('success'); $failedCommit = new Commit($project, '123456'); $failedCommit->setAuthor('Fabien'); $failedCommit->setMessage('Foo'); $failedCommit->setStatusCode('failed'); $project->setCommits(array($failedCommit, $successCommit)); $logger = $this->getMock('Psr\\Log\\NullLogger'); $logger->expects($this->once())->method('info'); $logger->expects($this->once())->method('critical'); $notifier = new LoggerNotifier($logger); //notify success commit $notifier->notify($successCommit); //notify failed commit $notifier->notify($failedCommit); }
public function setRepository($url) { parent::setRepository($url); if (file_exists($this->getRepository())) { $process = new Process('git remote -v', $this->getRepository()); $process->run(); foreach (explode("\n", $process->getOutput()) as $line) { $parts = explode("\t", $line); if ('origin' == $parts[0] && preg_match('#(?:\\:|/|@)github.com(?:\\:|/)(.*?)/(.*?)\\.git#', $parts[1], $matches)) { $this->setUrlPattern(sprintf('https://github.com/%s/%s/commit/%%commit%%', $matches[1], $matches[2])); break; } } } elseif (preg_match('#^[a-z0-9_-]+/[a-z0-9_-]+$#i', $this->getRepository())) { $this->setUrlPattern(sprintf('https://github.com/%s/commit/%%commit%%', $this->getRepository())); parent::setRepository(sprintf('https://github.com/%s.git', $this->getRepository())); } else { throw new \InvalidArgumentException(sprintf('URL "%s" does not look like a Github repository.', $this->getRepository())); } }
public function updateProject(Project $project) { $stmt = $this->db->prepare('INSERT OR REPLACE INTO project (slug, name, repository, branch, command, url_pattern) VALUES (:slug, :name, :repository, :branch, :command, :url_pattern)'); $stmt->bindValue(':slug', $project->getSlug(), SQLITE3_TEXT); $stmt->bindValue(':name', $project->getName(), SQLITE3_TEXT); $stmt->bindValue(':repository', $project->getRepository(), SQLITE3_TEXT); $stmt->bindValue(':branch', $project->getBranch(), SQLITE3_TEXT); $stmt->bindValue(':command', $project->getCommand(), SQLITE3_TEXT); $stmt->bindValue(':url_pattern', $project->getUrlPattern(), SQLITE3_TEXT); if (false === $stmt->execute()) { throw new \RuntimeException(sprintf('Unable to save project "%s".', $project->getName())); } $stmt = $this->db->prepare('SELECT sha, author, date, build_date, message, status, output FROM `commit` WHERE slug = :slug ORDER BY build_date DESC LIMIT 100'); $stmt->bindValue(':slug', $project->getSlug(), SQLITE3_TEXT); if (false === ($results = $stmt->execute())) { throw new \RuntimeException(sprintf('Unable to get latest commit for project "%s".', $project->getName())); } $commits = array(); while ($result = $results->fetchArray(\SQLITE3_ASSOC)) { $commits[] = $this->createCommit($project, $result); } $project->setCommits($commits); $stmt = $this->db->prepare('SELECT COUNT(*) AS count FROM `commit` WHERE slug = :slug AND status = "building"'); $stmt->bindValue(':slug', $project->getSlug(), SQLITE3_TEXT); $building = false; if (false !== ($result = $stmt->execute())) { if (false !== ($result = $result->fetchArray(\SQLITE3_ASSOC))) { if ($result['count'] > 0) { $building = true; } } } $project->setBuilding($building); }
public function testUrlPattern() { $project = new Project('Twig Local'); $project->setUrlPattern('https://github.com/fabpot/Twig/commit/%commit%'); $this->assertEquals('https://github.com/fabpot/Twig/commit/%commit%', $project->getUrlPattern()); }
public function getBuildDir(Project $project) { return substr(md5($project->getRepository() . $project->getBranch()), 0, 6); }
/** * Create or update the information of a project. * * If the project is already available, the information of the existing project will be updated. * * @param Project $project The project to create or update. * * @return StorageInterface $this */ public function updateProject(Project $project) { $stmt = $this->db->prepare('SELECT COUNT(*) FROM project WHERE slug = :slug'); $stmt->bindValue(':slug', $project->getSlug(), \PDO::PARAM_STR); if (false === $stmt->execute()) { // @codeCoverageIgnoreStart throw new \RuntimeException(sprintf('Unable to verify existence of project "%s".', $project->getName())); // @codeCoverageIgnoreEnd } if ($stmt->fetchColumn(0)) { $stmt = $this->db->prepare('UPDATE project SET slug = :slug, name = :name, repository = :repository, branch = :branch, command = :command, url_pattern = :url_pattern WHERE slug = :slug'); } else { $stmt = $this->db->prepare('INSERT INTO project (slug, name, repository, branch, command, url_pattern) VALUES (:slug, :name, :repository, :branch, :command, :url_pattern)'); } $stmt->bindValue(':slug', $project->getSlug(), \PDO::PARAM_STR); $stmt->bindValue(':name', $project->getName(), \PDO::PARAM_STR); $stmt->bindValue(':repository', $project->getRepository(), \PDO::PARAM_STR); $stmt->bindValue(':branch', $project->getBranch(), \PDO::PARAM_STR); $stmt->bindValue(':command', $project->getCommand(), \PDO::PARAM_STR); $stmt->bindValue(':url_pattern', $project->getUrlPattern(), \PDO::PARAM_STR); if (false === $stmt->execute()) { // @codeCoverageIgnoreStart throw new \RuntimeException(sprintf('Unable to save project "%s".', $project->getName())); // @codeCoverageIgnoreEnd } // related commits $stmt = $this->db->prepare('SELECT sha, author, date, build_date, message, status, output FROM `commit` WHERE slug = :slug ORDER BY `status` = "building" DESC, build_date DESC LIMIT 100'); $stmt->bindValue(':slug', $project->getSlug(), \PDO::PARAM_STR); if (false === $stmt->execute()) { // @codeCoverageIgnoreStart throw new \RuntimeException(sprintf('Unable to get latest commit for project "%s".', $project->getName())); // @codeCoverageIgnoreEnd } $commits = array(); while ($result = $stmt->fetch(\PDO::FETCH_ASSOC)) { $commits[] = $this->createCommit($project, $result); } $project->setCommits($commits); // project building? $stmt = $this->db->prepare('SELECT COUNT(*) AS count FROM `commit` WHERE slug = :slug AND status = "building"'); $stmt->bindValue(':slug', $project->getSlug(), \PDO::PARAM_STR); $building = false; if ($stmt->execute() and intval($stmt->fetchColumn(0))) { $building = true; } $project->setBuilding($building); }
public function init(Project $project, $callback = null) { $this->project = $project; $this->callback = $callback; $this->buildDir = $this->baseBuildDir . '/' . substr(md5($project->getRepository()), 0, 6); }