/** * Get latest builds and render as a table. */ protected function getLatestBuildsHtml() { $builds = $this->buildStore->getWhere(array(), 5, 0, array(), array('id' => 'DESC')); $view = new b8\View('BuildsTable'); foreach ($builds['items'] as &$build) { $build = BuildFactory::getBuild($build); } $view->builds = $builds['items']; return $view->render(); }
protected function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; // For verbose mode we want to output all informational and above // messages to the symphony output interface. if ($input->hasOption('verbose') && $input->getOption('verbose')) { $this->logger->pushHandler(new OutputLogHandler($this->output, Logger::INFO)); } $store = Factory::getStore('Build'); $result = $store->getByStatus(0); $this->logger->addInfo(Lang::get('found_n_builds', count($result['items']))); $buildService = new BuildService($store); while (count($result['items'])) { $build = array_shift($result['items']); $build = BuildFactory::getBuild($build); $this->logger->addInfo('Added build #' . $build->getId() . ' to queue.'); $buildService->addBuildToQueue($build); } }
/** * Pulls all pending builds from the database and runs them. */ protected function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; // For verbose mode we want to output all informational and above // messages to the symphony output interface. if ($input->hasOption('verbose')) { $this->logger->pushHandler(new OutputLogHandler($this->output, Logger::INFO)); } $this->logger->pushProcessor(new LoggedBuildContextTidier()); $this->logger->addInfo("Finding builds to process"); $store = Factory::getStore('Build'); $result = $store->getByStatus(0, $this->maxBuilds); $this->logger->addInfo(sprintf("Found %d builds", count($result['items']))); $builds = 0; foreach ($result['items'] as $build) { $builds++; $build = BuildFactory::getBuild($build); try { // Logging relevant to this build should be stored // against the build itself. $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); $this->logger->pushHandler($buildDbLog); $builder = new Builder($build, $this->logger); $builder->execute(); // After execution we no longer want to record the information // back to this specific build so the handler should be removed. $this->logger->popHandler($buildDbLog); } catch (\Exception $ex) { $build->setStatus(Build::STATUS_FAILED); $build->setLog($build->getLog() . PHP_EOL . PHP_EOL . $ex->getMessage()); $store->save($build); } } $this->logger->addInfo("Finished processing builds"); return $builds; }
/** * Wrapper for creating a new build. * * @param Project $project * @param string $commitId * @param string $branch * @param string $committer * @param string $commitMessage * @param array $extra * * @return array * * @throws Exception */ protected function createBuild(Project $project, $commitId, $branch, $committer, $commitMessage, array $extra = null) { // Check if a build already exists for this commit ID: $builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId); if ($builds['count']) { return array('status' => 'ignored', 'message' => sprintf('Duplicate of build #%d', $builds['items'][0]->getId())); } // If not, create a new build job for it: $build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra); $build = BuildFactory::getBuild($build); // Send a status postback if the build type provides one: $build->sendStatusPostback(); return array('status' => 'ok', 'buildID' => $build->getID()); }
protected function validateRunningBuilds() { /** @var \PHPCI\Store\BuildStore $store */ $store = Factory::getStore('Build'); $running = $store->getByStatus(1); $rtn = array(); $timeout = Config::getInstance()->get('phpci.build.failed_after', 1800); foreach ($running['items'] as $build) { /** @var \PHPCI\Model\Build $build */ $build = BuildFactory::getBuild($build); $now = time(); $start = $build->getStarted()->getTimestamp(); if ($now - $start > $timeout) { $this->logger->addInfo(Lang::get('marked_as_failed', $build->getId())); $build->setStatus(Build::STATUS_FAILED); $build->setFinished(new \DateTime()); $store->save($build); $this->removeBuildDirectory($build); continue; } $rtn[$build->getProjectId()] = true; } return $rtn; }
/** * Render latest builds for project as HTML table. * * @param $projectId * @param string $branch A urldecoded branch name. * @param int $start * @return array */ protected function getLatestBuildsHtml($projectId, $branch = '', $start = 0) { $criteria = array('project_id' => $projectId); if (!empty($branch)) { $criteria['branch'] = $branch; } $order = array('id' => 'DESC'); $builds = $this->buildStore->getWhere($criteria, 10, $start, array(), $order); $view = new b8\View('BuildsTable'); foreach ($builds['items'] as &$build) { $build = BuildFactory::getBuild($build); } $view->builds = $builds['items']; return array($view->render(), $builds['count']); }
protected function createBuild($projectId, $commitId, $branch, $committer, $commitMessage, $extra = null) { // Check if a build already exists for this commit ID: $builds = $this->buildStore->getByProjectAndCommit($projectId, $commitId); if ($builds['count']) { return true; } $project = $this->projectStore->getById($projectId); if (empty($project)) { throw new \Exception('Project does not exist:' . $projectId); } // If not, create a new build job for it: $build = $this->buildService->createBuild($project, $commitId, $branch, $committer, $commitMessage, $extra); $build = BuildFactory::getBuild($build); // Send a status postback if the build type provides one: $build->sendStatusPostback(); return true; }
/** * Render latest builds for project as HTML table. */ protected function getLatestBuilds($projectId) { $criteria = array('project_id' => $projectId); $order = array('id' => 'DESC'); $builds = $this->buildStore->getWhere($criteria, 10, 0, array(), $order); foreach ($builds['items'] as &$build) { $build = BuildFactory::getBuild($build); } return $builds['items']; }
/** * Delete a build. */ public function delete($buildId) { $this->requireAdmin(); $build = BuildFactory::getBuildById($buildId); if (empty($build)) { throw new NotFoundException(Lang::get('build_x_not_found', $buildId)); } $this->buildService->deleteBuild($build); $response = new b8\Http\Response\RedirectResponse(); $response->setHeader('Location', PHPCI_URL . 'project/view/' . $build->getProjectId()); return $response; }
/** * Start the worker. */ public function startWorker() { $this->pheanstalk->watch($this->queue); $this->pheanstalk->ignore('default'); $buildStore = Factory::getStore('Build'); while ($this->run) { // Get a job from the queue: $job = $this->pheanstalk->reserve(); $this->checkJobLimit(); // Get the job data and run the job: $jobData = json_decode($job->getData(), true); if (!$this->verifyJob($job, $jobData)) { continue; } $this->logger->addInfo('Received build #' . $jobData['build_id'] . ' from Beanstalkd'); // If the job comes with config data, reset our config and database connections // and then make sure we kill the worker afterwards: if (!empty($jobData['config'])) { $this->logger->addDebug('Using job-specific config.'); $currentConfig = Config::getInstance()->getArray(); $config = new Config($jobData['config']); Database::reset($config); } try { $build = BuildFactory::getBuildById($jobData['build_id']); } catch (\Exception $ex) { $this->logger->addWarning('Build #' . $jobData['build_id'] . ' does not exist in the database.'); $this->pheanstalk->delete($job); } try { // Logging relevant to this build should be stored // against the build itself. $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); $this->logger->pushHandler($buildDbLog); $builder = new Builder($build, $this->logger); $builder->execute(); // After execution we no longer want to record the information // back to this specific build so the handler should be removed. $this->logger->popHandler($buildDbLog); } catch (\PDOException $ex) { // If we've caught a PDO Exception, it is probably not the fault of the build, but of a failed // connection or similar. Release the job and kill the worker. $this->run = false; $this->pheanstalk->release($job); } catch (\Exception $ex) { $build->setStatus(Build::STATUS_FAILED); $build->setFinished(new \DateTime()); $build->setLog($build->getLog() . PHP_EOL . PHP_EOL . $ex->getMessage()); $buildStore->save($build); $build->sendStatusPostback(); } // Reset the config back to how it was prior to running this job: if (!empty($currentConfig)) { $config = new Config($currentConfig); Database::reset($config); } // Delete the job when we're done: $this->pheanstalk->delete($job); } }
/** * Delete a build. */ public function delete($buildId) { if (empty($_SESSION['user']) || !$_SESSION['user']->getIsAdmin()) { throw new \Exception('You do not have permission to do that.'); } $build = BuildFactory::getBuildById($buildId); if (empty($build)) { throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); } $this->buildService->deleteBuild($build); header('Location: ' . PHPCI_URL . 'project/view/' . $build->getProjectId()); exit; }
/** * @param Build $copyFrom * @return \PHPCI\Model\Build */ public function createDuplicateBuild(Build $copyFrom) { $data = $copyFrom->getDataArray(); // Clean up unwanted properties from the original build: unset($data['id']); unset($data['status']); unset($data['log']); unset($data['started']); unset($data['finished']); $build = new Build(); $build->setValues($data); $build->setCreated(new \DateTime()); $build->setStatus(0); $build = $this->buildStore->save($build); $buildId = $build->getId(); if (!empty($buildId)) { $build = BuildFactory::getBuild($build); $build->sendStatusPostback(); $this->addBuildToQueue($build); } return $build; }
/** * Delete a build. */ public function delete($buildId) { $this->requireAdmin(); $build = BuildFactory::getBuildById($buildId); if (empty($build)) { throw new NotFoundException(Lang::get('build_x_not_found', $buildId)); } $this->buildService->deleteBuild($build); header('Location: ' . PHPCI_URL . 'project/view/' . $build->getProjectId()); exit; }
protected function createBuild($projectId, $commitId, $branch, $committer, $commitMessage, $extra = null) { // Check if a build already exists for this commit ID: $builds = $this->buildStore->getByProjectAndCommit($projectId, $commitId); if ($builds['count']) { return true; } // If not, create a new build job for it: $build = new Build(); $build->setProjectId($projectId); $build->setCommitId($commitId); $build->setStatus(Build::STATUS_NEW); $build->setLog(''); $build->setCreated(new \DateTime()); $build->setBranch($branch); $build->setCommitterEmail($committer); $build->setCommitMessage($commitMessage); if (!is_null($extra)) { $build->setExtra(json_encode($extra)); } $build = BuildFactory::getBuild($this->buildStore->save($build)); // Send a status postback if the build type provides one: $build->sendStatusPostback(); return true; }