private function buildActionList(HarbormasterBuildable $buildable)
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $id = $buildable->getID();
     $list = id(new PhabricatorActionListView())->setUser($viewer)->setObject($buildable)->setObjectURI($buildable->getMonogram());
     $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $buildable, PhabricatorPolicyCapability::CAN_EDIT);
     $can_restart = false;
     $can_resume = false;
     $can_stop = false;
     foreach ($buildable->getBuilds() as $build) {
         if ($build->canRestartBuild()) {
             $can_restart = true;
         }
         if ($build->canResumeBuild()) {
             $can_resume = true;
         }
         if ($build->canStopBuild()) {
             $can_stop = true;
         }
     }
     $restart_uri = "buildable/{$id}/restart/";
     $stop_uri = "buildable/{$id}/stop/";
     $resume_uri = "buildable/{$id}/resume/";
     $list->addAction(id(new PhabricatorActionView())->setIcon('fa-repeat')->setName(pht('Restart All Builds'))->setHref($this->getApplicationURI($restart_uri))->setWorkflow(true)->setDisabled(!$can_restart || !$can_edit));
     $list->addAction(id(new PhabricatorActionView())->setIcon('fa-pause')->setName(pht('Pause All Builds'))->setHref($this->getApplicationURI($stop_uri))->setWorkflow(true)->setDisabled(!$can_stop || !$can_edit));
     $list->addAction(id(new PhabricatorActionView())->setIcon('fa-play')->setName(pht('Resume All Builds'))->setHref($this->getApplicationURI($resume_uri))->setWorkflow(true)->setDisabled(!$can_resume || !$can_edit));
     return $list;
 }
 private function renderLintAndUnit(HarbormasterBuildable $buildable, array $builds)
 {
     $viewer = $this->getViewer();
     $targets = array();
     foreach ($builds as $build) {
         foreach ($build->getBuildTargets() as $target) {
             $targets[] = $target;
         }
     }
     if (!$targets) {
         return;
     }
     $target_phids = mpull($targets, 'getPHID');
     $lint_data = id(new HarbormasterBuildLintMessage())->loadAllWhere('buildTargetPHID IN (%Ls)', $target_phids);
     $unit_data = id(new HarbormasterBuildUnitMessage())->loadAllWhere('buildTargetPHID IN (%Ls)', $target_phids);
     if ($lint_data) {
         $lint_table = id(new HarbormasterLintPropertyView())->setUser($viewer)->setLimit(10)->setLintMessages($lint_data);
         $lint_href = $this->getApplicationURI('lint/' . $buildable->getID() . '/');
         $lint_header = id(new PHUIHeaderView())->setHeader(pht('Lint Messages'))->addActionLink(id(new PHUIButtonView())->setTag('a')->setHref($lint_href)->setIconFont('fa-list-ul')->setText('View All'));
         $lint = id(new PHUIObjectBoxView())->setHeader($lint_header)->setTable($lint_table);
     } else {
         $lint = null;
     }
     if ($unit_data) {
         $unit_table = id(new HarbormasterUnitPropertyView())->setUser($viewer)->setLimit(25)->setUnitMessages($unit_data);
         $unit_href = $this->getApplicationURI('unit/' . $buildable->getID() . '/');
         $unit_header = id(new PHUIHeaderView())->setHeader(pht('Unit Tests'))->addActionLink(id(new PHUIButtonView())->setTag('a')->setHref($unit_href)->setIconFont('fa-list-ul')->setText('View All'));
         $unit = id(new PHUIObjectBoxView())->setHeader($unit_header)->setTable($unit_table);
     } else {
         $unit = null;
     }
     return array($lint, $unit);
 }
Ejemplo n.º 3
0
 /**
  * Update the overall status of the buildable this build is attached to.
  *
  * After a build changes state (for example, passes or fails) it may affect
  * the overall state of the associated buildable. Compute the new aggregate
  * state and save it on the buildable.
  *
  * @param   HarbormasterBuild The buildable to update.
  * @return  void
  */
 private function updateBuildable(HarbormasterBuildable $buildable)
 {
     $viewer = $this->getViewer();
     $lock_key = 'harbormaster.buildable:' . $buildable->getID();
     $lock = PhabricatorGlobalLock::newLock($lock_key)->lock(15);
     $buildable = id(new HarbormasterBuildableQuery())->setViewer($viewer)->withIDs(array($buildable->getID()))->needBuilds(true)->executeOne();
     $all_pass = true;
     $any_fail = false;
     foreach ($buildable->getBuilds() as $build) {
         if ($build->getBuildStatus() != HarbormasterBuild::STATUS_PASSED) {
             $all_pass = false;
         }
         if ($build->getBuildStatus() == HarbormasterBuild::STATUS_FAILED || $build->getBuildStatus() == HarbormasterBuild::STATUS_ERROR || $build->getBuildStatus() == HarbormasterBuild::STATUS_DEADLOCKED) {
             $any_fail = true;
         }
     }
     if ($any_fail) {
         $new_status = HarbormasterBuildable::STATUS_FAILED;
     } else {
         if ($all_pass) {
             $new_status = HarbormasterBuildable::STATUS_PASSED;
         } else {
             $new_status = HarbormasterBuildable::STATUS_BUILDING;
         }
     }
     $old_status = $buildable->getBuildableStatus();
     $did_update = $old_status != $new_status;
     if ($did_update) {
         $buildable->setBuildableStatus($new_status);
         $buildable->save();
     }
     $lock->unlock();
     // If we changed the buildable status, try to post a transaction to the
     // object about it. We can safely do this outside of the locked region.
     // NOTE: We only post transactions for automatic buildables, not for
     // manual ones: manual builds are test builds, whoever is doing tests
     // can look at the results themselves, and other users generally don't
     // care about the outcome.
     $should_publish = $did_update && $new_status != HarbormasterBuildable::STATUS_BUILDING && !$buildable->getIsManualBuildable();
     if (!$should_publish) {
         return;
     }
     $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withPHIDs(array($buildable->getBuildablePHID()))->executeOne();
     if (!$object) {
         return;
     }
     if (!$object instanceof PhabricatorApplicationTransactionInterface) {
         return;
     }
     // TODO: Publishing these transactions is causing a race. See T8650.
     // We shouldn't be publishing to diffs anyway.
     if ($object instanceof DifferentialDiff) {
         return;
     }
     $template = $object->getApplicationTransactionTemplate();
     if (!$template) {
         return;
     }
     $template->setTransactionType(PhabricatorTransactions::TYPE_BUILDABLE)->setMetadataValue('harbormaster:buildablePHID', $buildable->getPHID())->setOldValue($old_status)->setNewValue($new_status);
     $harbormaster_phid = id(new PhabricatorHarbormasterApplication())->getPHID();
     $daemon_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_DAEMON, array());
     $editor = $object->getApplicationTransactionEditor()->setActor($viewer)->setActingAsPHID($harbormaster_phid)->setContentSource($daemon_source)->setContinueOnNoEffect(true)->setContinueOnMissingFields(true);
     $editor->applyTransactions($object->getApplicationTransactionObject(), array($template));
 }