protected function loadPage() { $table = new HarbormasterBuildPlan(); $conn_r = $table->establishConnection('r'); $data = queryfx_all($conn_r, 'SELECT * FROM %T %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); return $table->loadAllFromArray($data); }
private function getBlockers(PhabricatorRepositoryCommit $commit, HarbormasterBuildPlan $plan, HarbormasterBuild $source) { $call = new ConduitCall('diffusion.commitparentsquery', array('commit' => $commit->getCommitIdentifier(), 'repository' => $commit->getRepository()->getPHID())); $call->setUser(PhabricatorUser::getOmnipotentUser()); $parents = $call->execute(); $parents = id(new DiffusionCommitQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withRepository($commit->getRepository())->withIdentifiers($parents)->execute(); $blockers = array(); $build_objects = array(); foreach ($parents as $parent) { if (!$parent->isImported()) { $blockers[] = pht('Commit %s', $parent->getCommitIdentifier()); } else { $build_objects[] = $parent->getPHID(); } } if ($build_objects) { $buildables = id(new HarbormasterBuildableQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildablePHIDs($build_objects)->withManualBuildables(false)->execute(); $buildable_phids = mpull($buildables, 'getPHID'); if ($buildable_phids) { $builds = id(new HarbormasterBuildQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildablePHIDs($buildable_phids)->withBuildPlanPHIDs(array($plan->getPHID()))->execute(); foreach ($builds as $build) { if (!$build->isComplete()) { $blockers[] = pht('Build %d', $build->getID()); } } } } return $blockers; }
public static function determineDependencyExecution(HarbormasterBuildPlan $plan) { $steps = id(new HarbormasterBuildStepQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildPlanPHIDs(array($plan->getPHID()))->execute(); $steps_by_phid = mpull($steps, null, 'getPHID'); $step_phids = mpull($steps, 'getPHID'); if (count($steps) === 0) { return array(); } $graph = id(new HarbormasterBuildGraph($steps_by_phid))->addNodes($step_phids); $raw_results = $graph->getBestEffortTopographicallySortedNodes(); $results = array(); foreach ($raw_results as $node) { $results[] = array('node' => $steps_by_phid[$node['node']], 'depth' => $node['depth'], 'cycle' => $node['cycle']); } return $results; }
public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $this->requireApplicationCapability(HarbormasterManagePlansCapability::CAPABILITY); $id = $request->getURIData('id'); if ($id) { $plan = id(new HarbormasterBuildPlanQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$plan) { return new Aphront404Response(); } } else { $plan = HarbormasterBuildPlan::initializeNewBuildPlan($viewer); } $e_name = true; $v_name = $plan->getName(); $validation_exception = null; if ($request->isFormPost()) { $xactions = array(); $v_name = $request->getStr('name'); $e_name = null; $type_name = HarbormasterBuildPlanTransaction::TYPE_NAME; $xactions[] = id(new HarbormasterBuildPlanTransaction())->setTransactionType($type_name)->setNewValue($v_name); $editor = id(new HarbormasterBuildPlanEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request); try { $editor->applyTransactions($plan, $xactions); return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('plan/' . $plan->getID() . '/')); } catch (PhabricatorApplicationTransactionValidationException $ex) { $validation_exception = $ex; $e_name = $validation_exception->getShortMessage(HarbormasterBuildPlanTransaction::TYPE_NAME); } } $is_new = !$plan->getID(); if ($is_new) { $title = pht('New Build Plan'); $cancel_uri = $this->getApplicationURI(); $save_button = pht('Create Build Plan'); } else { $id = $plan->getID(); $title = pht('Edit Build Plan'); $cancel_uri = $this->getApplicationURI('plan/' . $plan->getID() . '/'); $save_button = pht('Save Build Plan'); } $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Plan Name'))->setName('name')->setError($e_name)->setValue($v_name)); $form->appendChild(id(new AphrontFormSubmitControl())->setValue($save_button)->addCancelButton($cancel_uri)); $box = id(new PHUIObjectBoxView())->setHeaderText($title)->setValidationException($validation_exception)->setForm($form); $crumbs = $this->buildApplicationCrumbs(); if ($is_new) { $crumbs->addTextCrumb(pht('New Build Plan')); } else { $id = $plan->getID(); $crumbs->addTextCrumb(pht('Plan %d', $id), $this->getApplicationURI("plan/{$id}/")); $crumbs->addTextCrumb(pht('Edit')); } return $this->buildApplicationPage(array($crumbs, $box), array('title' => $title)); }
/** * Get a map of the @{class:HarbormasterBuildStep} objects for a list of * autotarget keys. * * This method creates the steps if they do not yet exist. * * @param list<string> Autotarget keys, like `"core.arc.lint"`. * @return map<string, object> Map of keys to step objects. */ private function generateBuildStepMap(array $autotargets) { $viewer = $this->getViewer(); $autosteps = $this->getAutosteps($autotargets); $autosteps = mgroup($autosteps, 'getBuildStepAutotargetPlanKey'); $plans = id(new HarbormasterBuildPlanQuery())->setViewer($viewer)->withPlanAutoKeys(array_keys($autosteps))->needBuildSteps(true)->execute(); $plans = mpull($plans, null, 'getPlanAutoKey'); // NOTE: When creating the plan and steps, we save the autokeys as the // names. These won't actually be shown in the UI, but make the data more // consistent for secondary consumers like typeaheads. $step_map = array(); foreach ($autosteps as $plan_key => $steps) { $plan = idx($plans, $plan_key); if (!$plan) { $plan = HarbormasterBuildPlan::initializeNewBuildPlan($viewer)->setName($plan_key)->setPlanAutoKey($plan_key); } $current = $plan->getBuildSteps(); $current = mpull($current, null, 'getStepAutoKey'); $new_steps = array(); foreach ($steps as $step_key => $step) { if (isset($current[$step_key])) { $step_map[$step_key] = $current[$step_key]; continue; } $new_step = HarbormasterBuildStep::initializeNewStep($viewer)->setName($step_key)->setClassName(get_class($step))->setStepAutoKey($step_key); $new_steps[$step_key] = $new_step; } if ($new_steps) { $plan->openTransaction(); if (!$plan->getPHID()) { $plan->save(); } foreach ($new_steps as $step_key => $step) { $step->setBuildPlanPHID($plan->getPHID()); $step->save(); $step->attachBuildPlan($plan); $step_map[$step_key] = $step; } $plan->saveTransaction(); } } return $step_map; }
public function applyPlan(HarbormasterBuildPlan $plan, array $parameters, $initiator_phid) { $viewer = PhabricatorUser::getOmnipotentUser(); $build = HarbormasterBuild::initializeNewBuild($viewer)->setBuildablePHID($this->getPHID())->setBuildPlanPHID($plan->getPHID())->setBuildParameters($parameters)->setBuildStatus(HarbormasterBuildStatus::STATUS_PENDING); if ($initiator_phid) { $build->setInitiatorPHID($initiator_phid); } $auto_key = $plan->getPlanAutoKey(); if ($auto_key) { $build->setPlanAutoKey($auto_key); } $build->save(); PhabricatorWorker::scheduleTask('HarbormasterBuildWorker', array('buildID' => $build->getID()), array('objectPHID' => $build->getPHID())); return $build; }
/** * Returns a list of all artifacts made available in the build plan. */ public static function getAvailableArtifacts(HarbormasterBuildPlan $build_plan, $current_build_step, $artifact_type) { $steps = id(new HarbormasterBuildStepQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildPlanPHIDs(array($build_plan->getPHID()))->execute(); $artifacts = array(); $artifact_arrays = array(); foreach ($steps as $step) { if ($current_build_step !== null && $step->getPHID() === $current_build_step->getPHID()) { continue; } $implementation = $step->getStepImplementation(); $array = $implementation->getArtifactOutputs(); $array = ipull($array, 'type', 'key'); foreach ($array as $name => $type) { if ($type !== $artifact_type && $artifact_type !== null) { continue; } $artifacts[$name] = array('type' => $type, 'step' => $step); } } return $artifacts; }
<?php $table = new HarbormasterBuildPlan(); $conn_w = $table->establishConnection('w'); $view_policy = PhabricatorPolicies::getMostOpenPolicy(); queryfx($conn_w, 'UPDATE %T SET viewPolicy = %s WHERE viewPolicy = %s', $table->getTableName(), $view_policy, ''); $edit_policy = id(new PhabricatorHarbormasterApplication())->getPolicy(HarbormasterCreatePlansCapability::CAPABILITY); queryfx($conn_w, 'UPDATE %T SET editPolicy = %s WHERE editPolicy = %s', $table->getTableName(), $edit_policy, '');
private function buildActionList(HarbormasterBuildPlan $plan) { $viewer = $this->getViewer(); $id = $plan->getID(); $list = id(new PhabricatorActionListView())->setUser($viewer)->setObject($plan)->setObjectURI($this->getApplicationURI("plan/{$id}/")); $has_manage = $this->hasApplicationCapability(HarbormasterManagePlansCapability::CAPABILITY); $has_edit = PhabricatorPolicyFilter::hasCapability($viewer, $plan, PhabricatorPolicyCapability::CAN_EDIT); $can_edit = $has_manage && $has_edit; $list->addAction(id(new PhabricatorActionView())->setName(pht('Edit Plan'))->setHref($this->getApplicationURI("plan/edit/{$id}/"))->setWorkflow(!$can_edit)->setDisabled(!$can_edit)->setIcon('fa-pencil')); if ($plan->isDisabled()) { $list->addAction(id(new PhabricatorActionView())->setName(pht('Enable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-check')); } else { $list->addAction(id(new PhabricatorActionView())->setName(pht('Disable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-ban')); } $can_run = $has_manage && $plan->canRunManually(); $list->addAction(id(new PhabricatorActionView())->setName(pht('Run Plan Manually'))->setHref($this->getApplicationURI("plan/run/{$id}/"))->setWorkflow(true)->setDisabled(!$can_run)->setIcon('fa-play-circle')); return $list; }
private function buildActionList(HarbormasterBuildPlan $plan) { $request = $this->getRequest(); $viewer = $request->getUser(); $id = $plan->getID(); $list = id(new PhabricatorActionListView())->setUser($viewer)->setObject($plan)->setObjectURI($this->getApplicationURI("plan/{$id}/")); $can_edit = $this->hasApplicationCapability(HarbormasterManagePlansCapability::CAPABILITY); $list->addAction(id(new PhabricatorActionView())->setName(pht('Edit Plan'))->setHref($this->getApplicationURI("plan/edit/{$id}/"))->setWorkflow(!$can_edit)->setDisabled(!$can_edit)->setIcon('fa-pencil')); if ($plan->isDisabled()) { $list->addAction(id(new PhabricatorActionView())->setName(pht('Enable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-check')); } else { $list->addAction(id(new PhabricatorActionView())->setName(pht('Disable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-ban')); } $list->addAction(id(new PhabricatorActionView())->setName(pht('Add Build Step'))->setHref($this->getApplicationURI("step/add/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-plus')); $list->addAction(id(new PhabricatorActionView())->setName(pht('Run Plan Manually'))->setHref($this->getApplicationURI("plan/run/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-play-circle')); return $list; }
<?php $table = new HarbormasterBuildPlan(); $conn_w = $table->establishConnection('w'); $viewer = PhabricatorUser::getOmnipotentUser(); // Since HarbormasterBuildStepQuery has been updated to handle the // correct order, we can't use the built in database access. foreach (new LiskMigrationIterator($table) as $plan) { $planname = $plan->getName(); echo "Migrating steps in {$planname}...\n"; $rows = queryfx_all($conn_w, 'SELECT id, sequence FROM harbormaster_buildstep ' . 'WHERE buildPlanPHID = %s ' . 'ORDER BY id ASC', $plan->getPHID()); $sequence = 1; foreach ($rows as $row) { $id = $row['id']; $existing = $row['sequence']; if ($existing != 0) { echo " - {$id} (already migrated)...\n"; continue; } echo " - {$id} to position {$sequence}...\n"; queryfx($conn_w, 'UPDATE harbormaster_buildstep ' . 'SET sequence = %d ' . 'WHERE id = %d', $sequence, $id); $sequence++; } } echo "Done.\n";
<?php $plan_table = new HarbormasterBuildPlan(); $step_table = new HarbormasterBuildStep(); $conn_w = $plan_table->establishConnection('w'); foreach (new LiskMigrationIterator($plan_table) as $plan) { echo pht("Migrating build plan %d: %s...\n", $plan->getID(), $plan->getName()); // Load all build steps in order using the step sequence. $steps = queryfx_all($conn_w, 'SELECT id FROM %T WHERE buildPlanPHID = %s ORDER BY sequence ASC;', $step_table->getTableName(), $plan->getPHID()); $previous_step = null; foreach ($steps as $step) { $id = $step['id']; $loaded_step = id(new HarbormasterBuildStep())->load($id); $depends_on = $loaded_step->getDetail('dependsOn'); if ($depends_on !== null) { // This plan already contains steps with depends_on set, so // we skip since there's nothing to migrate. break; } if ($previous_step === null) { $depends_on = array(); } else { $depends_on = array($previous_step->getPHID()); } $loaded_step->setDetail('dependsOn', $depends_on); queryfx($conn_w, 'UPDATE %T SET details = %s WHERE id = %d', $step_table->getTableName(), json_encode($loaded_step->getDetails()), $loaded_step->getID()); $previous_step = $loaded_step; echo pht(" Migrated build step %d.\n", $loaded_step->getID()); } }
public function applyPlan(HarbormasterBuildPlan $plan) { $viewer = PhabricatorUser::getOmnipotentUser(); $build = HarbormasterBuild::initializeNewBuild($viewer)->setBuildablePHID($this->getPHID())->setBuildPlanPHID($plan->getPHID())->setBuildStatus(HarbormasterBuild::STATUS_PENDING)->save(); PhabricatorWorker::scheduleTask('HarbormasterBuildWorker', array('buildID' => $build->getID())); return $build; }
protected function newEditableObject() { $viewer = $this->getViewer(); return HarbormasterBuildPlan::initializeNewBuildPlan($viewer); }
private function buildCurtainView(HarbormasterBuildPlan $plan) { $viewer = $this->getViewer(); $id = $plan->getID(); $curtain = $this->newCurtainView($plan); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $plan, PhabricatorPolicyCapability::CAN_EDIT); $curtain->addAction(id(new PhabricatorActionView())->setName(pht('Edit Plan'))->setHref($this->getApplicationURI("plan/edit/{$id}/"))->setWorkflow(!$can_edit)->setDisabled(!$can_edit)->setIcon('fa-pencil')); if ($plan->isDisabled()) { $curtain->addAction(id(new PhabricatorActionView())->setName(pht('Enable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-check')); } else { $curtain->addAction(id(new PhabricatorActionView())->setName(pht('Disable Plan'))->setHref($this->getApplicationURI("plan/disable/{$id}/"))->setWorkflow(true)->setDisabled(!$can_edit)->setIcon('fa-ban')); } $can_run = $can_edit && $plan->canRunManually(); $curtain->addAction(id(new PhabricatorActionView())->setName(pht('Run Plan Manually'))->setHref($this->getApplicationURI("plan/run/{$id}/"))->setWorkflow(true)->setDisabled(!$can_run)->setIcon('fa-play-circle')); $curtain->addPanel(id(new PHUICurtainPanelView())->setHeaderText(pht('Created'))->appendChild(phabricator_datetime($plan->getDateCreated(), $viewer))); return $curtain; }