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;
 }