public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $this->id; $generation = $request->getInt('g'); $build = id(new HarbormasterBuildQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$build) { return new Aphront404Response(); } require_celerity_resource('harbormaster-css'); $title = pht('Build %d', $id); $header = id(new PHUIHeaderView())->setHeader($title)->setUser($viewer)->setPolicyObject($build); if ($build->isRestarting()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Restarting')); } else { if ($build->isStopping()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Pausing')); } else { if ($build->isResuming()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Resuming')); } } } $box = id(new PHUIObjectBoxView())->setHeader($header); $actions = $this->buildActionList($build); $this->buildPropertyLists($box, $build, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($build->getBuildable()->getMonogram(), '/' . $build->getBuildable()->getMonogram()); $crumbs->addTextCrumb($title); if ($generation === null || $generation > $build->getBuildGeneration() || $generation < 0) { $generation = $build->getBuildGeneration(); } $build_targets = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->needBuildSteps(true)->withBuildPHIDs(array($build->getPHID()))->withBuildGenerations(array($generation))->execute(); if ($build_targets) { $messages = id(new HarbormasterBuildMessageQuery())->setViewer($viewer)->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))->execute(); $messages = mgroup($messages, 'getBuildTargetPHID'); } else { $messages = array(); } $targets = array(); foreach ($build_targets as $build_target) { $header = id(new PHUIHeaderView())->setHeader($build_target->getName())->setUser($viewer); $target_box = id(new PHUIObjectBoxView())->setHeader($header); $properties = new PHUIPropertyListView(); $status_view = new PHUIStatusListView(); $item = new PHUIStatusItemView(); $status = $build_target->getTargetStatus(); $status_name = HarbormasterBuildTarget::getBuildTargetStatusName($status); $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status); $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status); $item->setTarget($status_name); $item->setIcon($icon, $color); $status_view->addItem($item); $properties->addProperty(pht('Name'), $build_target->getName()); if ($build_target->getDateStarted() !== null) { $properties->addProperty(pht('Started'), phabricator_datetime($build_target->getDateStarted(), $viewer)); if ($build_target->isComplete()) { $properties->addProperty(pht('Completed'), phabricator_datetime($build_target->getDateCompleted(), $viewer)); $properties->addProperty(pht('Duration'), phutil_format_relative_time_detailed($build_target->getDateCompleted() - $build_target->getDateStarted())); } else { $properties->addProperty(pht('Elapsed'), phutil_format_relative_time_detailed(time() - $build_target->getDateStarted())); } } $properties->addProperty(pht('Status'), $status_view); $target_box->addPropertyList($properties, pht('Overview')); $step = $build_target->getBuildStep(); if ($step) { $description = $step->getDescription(); if ($description) { $rendered = PhabricatorMarkupEngine::renderOneObject(id(new PhabricatorMarkupOneOff())->setContent($description)->setPreserveLinebreaks(true), 'default', $viewer); $properties->addSectionHeader(pht('Description')); $properties->addTextContent($rendered); } } else { $target_box->setFormErrors(array(pht('This build step has since been deleted on the build plan. ' . 'Some information may be omitted.'))); } $details = $build_target->getDetails(); if ($details) { $properties = new PHUIPropertyListView(); foreach ($details as $key => $value) { $properties->addProperty($key, $value); } $target_box->addPropertyList($properties, pht('Configuration')); } $variables = $build_target->getVariables(); if ($variables) { $properties = new PHUIPropertyListView(); foreach ($variables as $key => $value) { $properties->addProperty($key, $value); } $target_box->addPropertyList($properties, pht('Variables')); } $artifacts = $this->buildArtifacts($build_target); if ($artifacts) { $properties = new PHUIPropertyListView(); $properties->addRawContent($artifacts); $target_box->addPropertyList($properties, pht('Artifacts')); } $build_messages = idx($messages, $build_target->getPHID(), array()); if ($build_messages) { $properties = new PHUIPropertyListView(); $properties->addRawContent($this->buildMessages($build_messages)); $target_box->addPropertyList($properties, pht('Messages')); } $properties = new PHUIPropertyListView(); $properties->addProperty('Build Target ID', $build_target->getID()); $target_box->addPropertyList($properties, pht('Metadata')); $targets[] = $target_box; $targets[] = $this->buildLog($build, $build_target); } $xactions = id(new HarbormasterBuildTransactionQuery())->setViewer($viewer)->withObjectPHIDs(array($build->getPHID()))->execute(); $timeline = id(new PhabricatorApplicationTransactionView())->setUser($viewer)->setObjectPHID($build->getPHID())->setTransactions($xactions); return $this->buildApplicationPage(array($crumbs, $box, $targets, $timeline), array('title' => $title)); }
private function buildBuildList(HarbormasterBuildable $buildable) { $viewer = $this->getRequest()->getUser(); $build_list = id(new PHUIObjectItemListView())->setUser($viewer); foreach ($buildable->getBuilds() as $build) { $view_uri = $this->getApplicationURI('/build/' . $build->getID() . '/'); $item = id(new PHUIObjectItemView())->setObjectName(pht('Build %d', $build->getID()))->setHeader($build->getName())->setHref($view_uri); $status = $build->getBuildStatus(); $item->setStatusIcon('fa-dot-circle-o ' . HarbormasterBuild::getBuildStatusColor($status), HarbormasterBuild::getBuildStatusName($status)); $item->addAttribute(HarbormasterBuild::getBuildStatusName($status)); if ($build->isRestarting()) { $item->addIcon('fa-repeat', pht('Restarting')); } else { if ($build->isPausing()) { $item->addIcon('fa-pause', pht('Pausing')); } else { if ($build->isResuming()) { $item->addIcon('fa-play', pht('Resuming')); } } } $build_id = $build->getID(); $restart_uri = "build/restart/{$build_id}/buildable/"; $resume_uri = "build/resume/{$build_id}/buildable/"; $pause_uri = "build/pause/{$build_id}/buildable/"; $abort_uri = "build/abort/{$build_id}/buildable/"; $item->addAction(id(new PHUIListItemView())->setIcon('fa-repeat')->setName(pht('Restart'))->setHref($this->getApplicationURI($restart_uri))->setWorkflow(true)->setDisabled(!$build->canRestartBuild())); if ($build->canResumeBuild()) { $item->addAction(id(new PHUIListItemView())->setIcon('fa-play')->setName(pht('Resume'))->setHref($this->getApplicationURI($resume_uri))->setWorkflow(true)); } else { $item->addAction(id(new PHUIListItemView())->setIcon('fa-pause')->setName(pht('Pause'))->setHref($this->getApplicationURI($pause_uri))->setWorkflow(true)->setDisabled(!$build->canPauseBuild())); } $targets = $build->getBuildTargets(); if ($targets) { $target_list = id(new PHUIStatusListView()); foreach ($targets as $target) { $status = $target->getTargetStatus(); $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status); $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status); $status_name = HarbormasterBuildTarget::getBuildTargetStatusName($status); $name = $target->getName(); $target_list->addItem(id(new PHUIStatusItemView())->setIcon($icon, $color, $status_name)->setTarget(pht('Target %d', $target->getID()))->setNote($name)); } $target_box = id(new PHUIBoxView())->addPadding(PHUI::PADDING_SMALL)->appendChild($target_list); $item->appendChild($target_box); } $build_list->addItem($item); } $build_list->setFlush(true); $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Builds'))->appendChild($build_list); return $box; }
public function handleRequest(AphrontRequest $request) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $request->getURIData('id'); $generation = $request->getInt('g'); $build = id(new HarbormasterBuildQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$build) { return new Aphront404Response(); } require_celerity_resource('harbormaster-css'); $title = pht('Build %d', $id); $header = id(new PHUIHeaderView())->setHeader($title)->setUser($viewer)->setPolicyObject($build); if ($build->isRestarting()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Restarting')); } else { if ($build->isPausing()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Pausing')); } else { if ($build->isResuming()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Resuming')); } else { if ($build->isAborting()) { $header->setStatus('fa-exclamation-triangle', 'red', pht('Aborting')); } } } } $box = id(new PHUIObjectBoxView())->setHeader($header); $actions = $this->buildActionList($build); $this->buildPropertyLists($box, $build, $actions); $crumbs = $this->buildApplicationCrumbs(); $this->addBuildableCrumb($crumbs, $build->getBuildable()); $crumbs->addTextCrumb($title); if ($generation === null || $generation > $build->getBuildGeneration() || $generation < 0) { $generation = $build->getBuildGeneration(); } $build_targets = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->needBuildSteps(true)->withBuildPHIDs(array($build->getPHID()))->withBuildGenerations(array($generation))->execute(); if ($build_targets) { $messages = id(new HarbormasterBuildMessageQuery())->setViewer($viewer)->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))->execute(); $messages = mgroup($messages, 'getBuildTargetPHID'); } else { $messages = array(); } if ($build_targets) { $artifacts = id(new HarbormasterBuildArtifactQuery())->setViewer($viewer)->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))->execute(); $artifacts = msort($artifacts, 'getArtifactKey'); $artifacts = mgroup($artifacts, 'getBuildTargetPHID'); } else { $artifacts = array(); } $targets = array(); foreach ($build_targets as $build_target) { $header = id(new PHUIHeaderView())->setHeader($build_target->getName())->setUser($viewer); $target_box = id(new PHUIObjectBoxView())->setHeader($header); $properties = new PHUIPropertyListView(); $target_artifacts = idx($artifacts, $build_target->getPHID(), array()); $links = array(); $type_uri = HarbormasterURIArtifact::ARTIFACTCONST; foreach ($target_artifacts as $artifact) { if ($artifact->getArtifactType() == $type_uri) { $impl = $artifact->getArtifactImplementation(); if ($impl->isExternalLink()) { $links[] = $impl->renderLink(); } } } if ($links) { $links = phutil_implode_html(phutil_tag('br'), $links); $properties->addProperty(pht('External Link'), $links); } $status_view = new PHUIStatusListView(); $item = new PHUIStatusItemView(); $status = $build_target->getTargetStatus(); $status_name = HarbormasterBuildTarget::getBuildTargetStatusName($status); $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status); $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status); $item->setTarget($status_name); $item->setIcon($icon, $color); $status_view->addItem($item); $when = array(); $started = $build_target->getDateStarted(); $now = PhabricatorTime::getNow(); if ($started) { $ended = $build_target->getDateCompleted(); if ($ended) { $when[] = pht('Completed at %s', phabricator_datetime($started, $viewer)); $duration = $ended - $started; if ($duration) { $when[] = pht('Built for %s', phutil_format_relative_time_detailed($duration)); } else { $when[] = pht('Built instantly'); } } else { $when[] = pht('Started at %s', phabricator_datetime($started, $viewer)); $duration = $now - $started; if ($duration) { $when[] = pht('Running for %s', phutil_format_relative_time_detailed($duration)); } } } else { $created = $build_target->getDateCreated(); $when[] = pht('Queued at %s', phabricator_datetime($started, $viewer)); $duration = $now - $created; if ($duration) { $when[] = pht('Waiting for %s', phutil_format_relative_time_detailed($duration)); } } $properties->addProperty(pht('When'), phutil_implode_html(" · ", $when)); $properties->addProperty(pht('Status'), $status_view); $target_box->addPropertyList($properties, pht('Overview')); $step = $build_target->getBuildStep(); if ($step) { $description = $step->getDescription(); if ($description) { $description = new PHUIRemarkupView($viewer, $description); $properties->addSectionHeader(pht('Description'), PHUIPropertyListView::ICON_SUMMARY); $properties->addTextContent($description); } } else { $target_box->setFormErrors(array(pht('This build step has since been deleted on the build plan. ' . 'Some information may be omitted.'))); } $details = $build_target->getDetails(); $properties = new PHUIPropertyListView(); foreach ($details as $key => $value) { $properties->addProperty($key, $value); } $target_box->addPropertyList($properties, pht('Configuration')); $variables = $build_target->getVariables(); $properties = new PHUIPropertyListView(); $properties->addRawContent($this->buildProperties($variables)); $target_box->addPropertyList($properties, pht('Variables')); $artifacts_tab = $this->buildArtifacts($build_target, $target_artifacts); $properties = new PHUIPropertyListView(); $properties->addRawContent($artifacts_tab); $target_box->addPropertyList($properties, pht('Artifacts')); $build_messages = idx($messages, $build_target->getPHID(), array()); $properties = new PHUIPropertyListView(); $properties->addRawContent($this->buildMessages($build_messages)); $target_box->addPropertyList($properties, pht('Messages')); $properties = new PHUIPropertyListView(); $properties->addProperty(pht('Build Target ID'), $build_target->getID()); $properties->addProperty(pht('Build Target PHID'), $build_target->getPHID()); $target_box->addPropertyList($properties, pht('Metadata')); $targets[] = $target_box; $targets[] = $this->buildLog($build, $build_target); } $timeline = $this->buildTransactionTimeline($build, new HarbormasterBuildTransactionQuery()); $timeline->setShouldTerminate(true); return $this->buildApplicationPage(array($crumbs, $box, $targets, $timeline), array('title' => $title)); }