Esempio n. 1
0
 /**
  * Schedules a build
  *
  * @see App\CoreBundle\EventListener\BuildBranchRelationSubscriber for automatic creation of non-existing branches
  */
 public function schedule(Project $project, $ref, $hash, PayloadInterface $payload = null, $options = [])
 {
     $logger = $this->logger;
     $logger->info('scheduling build', ['project' => $project->getId(), 'ref' => $ref, 'hash' => $hash]);
     $em = $this->doctrine->getManager();
     // @todo I guess this should be in a build.scheduled event listener
     $alreadyRunningBuilds = $em->getRepository('Model:Build')->findPendingByRef($project, $ref);
     foreach ($alreadyRunningBuilds as $build) {
         // @todo instead of retrieving then updating builds to be canceled, directly issue an UPDATE
         //       it should avoid most race conditions
         if ($build->isScheduled()) {
             $logger->info('canceling same ref build', ['ref' => $ref, 'canceled_build' => $build->getId()]);
             $build->setStatus(Build::STATUS_CANCELED);
             $em->persist($build);
             $em->flush();
         } else {
             $logger->info('killing same ref build', ['ref' => $ref, 'canceled_build' => $build->getId()]);
             $scheduler->kill($build);
         }
     }
     $build = new Build();
     $build->setProject($project);
     $build->setStatus(Build::STATUS_SCHEDULED);
     $build->setRef($ref);
     $build->setHash($hash);
     $build->setCommitUrl(sprintf('https://github.com/%s/commit/%s', $project->getFullName(), $hash));
     if (null !== $payload) {
         $build->setIsPullRequest($payload->isPullRequest());
         $build->setRawPayload($payload->getRawContent());
     } else {
         $build->setIsPullRequest(false);
     }
     if (isset($options['force_local_build_yml']) && $options['force_local_build_yml']) {
         $build->setForceLocalBuildYml(true);
     }
     $builderHost = null;
     $logger->info('electing builder', ['builder_host_allow' => $this->getOption('builder_host_allow')]);
     if (count($builderHostAllow = $this->getOption('builder_host_allow')) > 0) {
         $builderHost = $builderHostAllow[array_rand($builderHostAllow)];
     }
     $build->setBuilderHost($builderHost);
     /**
      * @todo move this outside, it belongs in a controller
      *       this will allow to remove the $options argument
      */
     $em->persist($build);
     $em->flush();
     $this->logger->info('sending build order', ['build' => $build->getId(), 'builder_host' => $builderHost]);
     $this->buildProducer->publish(json_encode(['build_id' => $build->getId()]), $build->getRoutingKey());
     $message = $this->messageFactory->createBuildScheduled($build);
     $this->websocketProducer->publish($message);
     return $build;
 }
Esempio n. 2
0
 /**
  * @todo the policy check and Payload->isBuildable() could be implemented
  *       as a voting system
  */
 private function scheduleBranchPush(PayloadInterface $payload, Project $project)
 {
     $logger = $this->get('logger');
     $em = $this->get('doctrine')->getManager();
     if (!$payload->hasRef()) {
         return new JsonResponse(json_encode(null), 400);
     }
     $ref = $payload->getRef();
     $hash = $payload->getHash();
     # then, check if ref is configured to be automatically built
     $doBuild = false;
     switch ($project->getSettings()->getPolicy()) {
         case ProjectSettings::POLICY_ALL:
             $doBuild = true;
             break;
         case ProjectSettings::POLICY_NONE:
         case ProjectSettings::POLICY_PR:
             $doBuild = false;
             break;
         case ProjectSettings::POLICY_PATTERNS:
             $patterns = explode(PHP_EOL, $project->getSettings()->getBranchPatterns());
             foreach ($patterns as $pattern) {
                 $regex = strtr($pattern, ['*' => '.*', '?' => '.']);
                 if (preg_match('/' . $regex . '/i', $ref)) {
                     $doBuild = true;
                 }
             }
             break;
         default:
             $logger->error('could not find a build policy', ['project' => $project->getId(), 'ref' => $ref]);
             return new JsonResponse(['class' => 'danger', 'message' => 'Could not find a build policy'], 400);
     }
     if (!$doBuild) {
         $logger->info('build declined by project policy', ['project' => $project->getId(), 'ref' => $ref]);
         return new JsonResponse(['class' => 'info', 'message' => 'Build declined by project policy (' . $project->getSettings()->getPolicy() . ')'], 200);
     }
     /** @todo this should be in the PayloadInterface as ->isDelete() or something */
     if ($hash === '0000000000000000000000000000000000000000') {
         $branch = $em->getRepository('Model:Branch')->findOneByProjectAndName($project, $ref);
         $branch->setDeleted(true);
         $em->persist($branch);
         $em->flush();
         return new JsonResponse(json_encode(null), 200);
     }
     $sameHashBuilds = $em->getRepository('Model:Build')->findByHash($hash);
     if (count($sameHashBuilds) > 0) {
         $logger->warn('found builds with same hash', ['count' => count($sameHashBuilds)]);
         $allowRebuild = array_reduce($sameHashBuilds, function ($result, $b) {
             return $result || $b->getAllowRebuild();
         }, false);
     }
     if (isset($allowRebuild) && !$allowRebuild) {
         $logger->warn('build already scheduled for hash', ['hash' => $hash]);
         return new JsonResponse(['class' => 'danger', 'message' => 'Build already scheduled for hash'], 400);
     } else {
         $logger->info('scheduling build for hash', ['hash' => $hash]);
     }
     return [$ref, $hash];
 }
Esempio n. 3
0
 public function findOneByPayload(PayloadInterface $payload)
 {
     return $this->createQueryBuilder('p')->where('p.providerName = :providerName and p.fullName = :fullName')->setParameters(['providerName' => $payload->getProviderName(), 'fullName' => $payload->getRepositoryFullName()])->getQuery()->getOneOrNullResult();
 }