protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $build_target_phid = $request->getValue('buildTargetPHID'); $message_type = $request->getValue('type'); $build_target = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->withPHIDs(array($build_target_phid))->executeOne(); if (!$build_target) { throw new Exception(pht('No such build target!')); } $save = array(); $lint_messages = $request->getValue('lint', array()); foreach ($lint_messages as $lint) { $save[] = HarbormasterBuildLintMessage::newFromDictionary($build_target, $lint); } $unit_messages = $request->getValue('unit', array()); foreach ($unit_messages as $unit) { $save[] = HarbormasterBuildUnitMessage::newFromDictionary($build_target, $unit); } $save[] = HarbormasterBuildMessage::initializeNewMessage($viewer)->setBuildTargetPHID($build_target->getPHID())->setType($message_type); $build_target->openTransaction(); foreach ($save as $object) { $object->save(); } $build_target->saveTransaction(); // If the build has completely paused because all steps are blocked on // waiting targets, this will resume it. PhabricatorWorker::scheduleTask('HarbormasterBuildWorker', array('buildID' => $build_target->getBuild()->getID())); return null; }
private function buildPropertyListView(HarbormasterBuildUnitMessage $message) { $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView())->setUser($viewer); $view->addProperty(pht('Run At'), phabricator_datetime($message->getDateCreated(), $viewer)); $details = $message->getUnitMessageDetails(); if (strlen($details)) { // TODO: Use the log view here, once it gets cleaned up. // Shenanigans below. $details = phutil_tag('div', array('class' => 'PhabricatorMonospaced', 'style' => 'white-space: pre-wrap; ' . 'color: #666666; ' . 'overflow-x: auto;'), $details); } else { $details = phutil_tag('em', array(), pht('No details provided.')); } $view->addSectionHeader(pht('Details'), PHUIPropertyListView::ICON_TESTPLAN); $view->addTextContent($details); return $view; }
protected function newModernMessage(array $message) { return HarbormasterBuildUnitMessage::newFromDictionary(new HarbormasterBuildTarget(), $this->getModernUnitMessageDictionary($message)); }
protected function loadHarbormasterData(array $diffs) { $viewer = $this->getViewer(); $diffs = mpull($diffs, null, 'getPHID'); $buildables = id(new HarbormasterBuildableQuery())->setViewer($viewer)->withBuildablePHIDs(array_keys($diffs))->withManualBuildables(false)->needBuilds(true)->needTargets(true)->execute(); $buildables = mpull($buildables, null, 'getBuildablePHID'); foreach ($diffs as $phid => $diff) { $diff->attachBuildable(idx($buildables, $phid)); } $target_map = array(); foreach ($diffs as $phid => $diff) { $target_map[$phid] = $diff->getBuildTargetPHIDs(); } $all_target_phids = array_mergev($target_map); if ($all_target_phids) { $unit_messages = id(new HarbormasterBuildUnitMessage())->loadAllWhere('buildTargetPHID IN (%Ls)', $all_target_phids); $unit_messages = mgroup($unit_messages, 'getBuildTargetPHID'); } else { $unit_messages = array(); } foreach ($diffs as $phid => $diff) { $target_phids = idx($target_map, $phid, array()); $messages = array_select_keys($unit_messages, $target_phids); $messages = array_mergev($messages); $diff->attachUnitMessages($messages); } // For diffs with no messages, look for legacy unit messages stored on the // diff itself. foreach ($diffs as $phid => $diff) { if ($diff->getUnitMessages()) { continue; } if (!$diff->hasDiffProperty('arc:unit')) { continue; } $legacy_messages = $diff->getProperty('arc:unit'); if (!$legacy_messages) { continue; } // Show the top 100 legacy lint messages. Previously, we showed some // by default and let the user toggle the rest. With modern messages, // we can send the user to the Harbormaster detail page. Just show // "a lot" of messages in legacy cases to try to strike a balance // between implementation simplicitly and compatibility. $legacy_messages = array_slice($legacy_messages, 0, 100); $messages = array(); foreach ($legacy_messages as $message) { $messages[] = HarbormasterBuildUnitMessage::newFromDictionary(new HarbormasterBuildTarget(), $this->getModernUnitMessageDictionary($message)); } $diff->attachUnitMessages($messages); } }
private function loadHistoryDiffStatus(array $diffs) { assert_instances_of($diffs, 'DifferentialDiff'); $diff_phids = mpull($diffs, 'getPHID'); $bad_unit_status = array(ArcanistUnitTestResult::RESULT_FAIL, ArcanistUnitTestResult::RESULT_BROKEN); $message = new HarbormasterBuildUnitMessage(); $target = new HarbormasterBuildTarget(); $build = new HarbormasterBuild(); $buildable = new HarbormasterBuildable(); $broken_diffs = queryfx_all($message->establishConnection('r'), 'SELECT distinct a.buildablePHID FROM %T m JOIN %T t ON m.buildTargetPHID = t.phid JOIN %T b ON t.buildPHID = b.phid JOIN %T a ON b.buildablePHID = a.phid WHERE a.buildablePHID IN (%Ls) AND m.result in (%Ls)', $message->getTableName(), $target->getTableName(), $build->getTableName(), $buildable->getTableName(), $diff_phids, $bad_unit_status); $unit_status = array(); foreach ($broken_diffs as $broken) { $phid = $broken['buildablePHID']; $unit_status[$phid] = DifferentialUnitStatus::UNIT_FAIL; } return $unit_status; }