Changeset View
Changeset View
Standalone View
Standalone View
src/applications/harbormaster/storage/build/HarbormasterBuild.php
Show First 20 Lines • Show All 309 Lines • ▼ Show 20 Lines | /* -( Build Messages )----------------------------------------------------- */ | ||||
} | } | ||||
public function attachUnprocessedMessages(array $messages) { | public function attachUnprocessedMessages(array $messages) { | ||||
assert_instances_of($messages, 'HarbormasterBuildMessage'); | assert_instances_of($messages, 'HarbormasterBuildMessage'); | ||||
$this->unprocessedMessages = $messages; | $this->unprocessedMessages = $messages; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function canRestartBuild() { | |||||
try { | |||||
$this->assertCanRestartBuild(); | |||||
return true; | |||||
} catch (HarbormasterRestartException $ex) { | |||||
return false; | |||||
} | |||||
} | |||||
public function assertCanRestartBuild() { | |||||
if ($this->isAutobuild()) { | |||||
throw new HarbormasterRestartException( | |||||
pht('Can Not Restart Autobuild'), | |||||
pht( | |||||
'This build can not be restarted because it is an automatic '. | |||||
'build.')); | |||||
} | |||||
$restartable = HarbormasterBuildPlanBehavior::BEHAVIOR_RESTARTABLE; | |||||
$plan = $this->getBuildPlan(); | |||||
// See T13526. Users who can't see the "BuildPlan" can end up here with | |||||
// no object. This is highly questionable. | |||||
if (!$plan) { | |||||
throw new HarbormasterRestartException( | |||||
pht('No Build Plan Permission'), | |||||
pht( | |||||
'You can not restart this build because you do not have '. | |||||
'permission to access the build plan.')); | |||||
} | |||||
$option = HarbormasterBuildPlanBehavior::getBehavior($restartable) | |||||
->getPlanOption($plan); | |||||
$option_key = $option->getKey(); | |||||
$never_restartable = HarbormasterBuildPlanBehavior::RESTARTABLE_NEVER; | |||||
$is_never = ($option_key === $never_restartable); | |||||
if ($is_never) { | |||||
throw new HarbormasterRestartException( | |||||
pht('Build Plan Prevents Restart'), | |||||
pht( | |||||
'This build can not be restarted because the build plan is '. | |||||
'configured to prevent the build from restarting.')); | |||||
} | |||||
$failed_restartable = HarbormasterBuildPlanBehavior::RESTARTABLE_IF_FAILED; | |||||
$is_failed = ($option_key === $failed_restartable); | |||||
if ($is_failed) { | |||||
if (!$this->isFailed()) { | |||||
throw new HarbormasterRestartException( | |||||
pht('Only Restartable if Failed'), | |||||
pht( | |||||
'This build can not be restarted because the build plan is '. | |||||
'configured to prevent the build from restarting unless it '. | |||||
'has failed, and it has not failed.')); | |||||
} | |||||
} | |||||
if ($this->isRestarting()) { | |||||
throw new HarbormasterRestartException( | |||||
pht('Already Restarting'), | |||||
pht( | |||||
'This build is already restarting. You can not reissue a restart '. | |||||
'command to a restarting build.')); | |||||
} | |||||
} | |||||
public function canPauseBuild() { | |||||
if ($this->isAutobuild()) { | |||||
return false; | |||||
} | |||||
return !$this->isComplete() && | |||||
!$this->isPaused() && | |||||
!$this->isPausing() && | |||||
!$this->isRestarting() && | |||||
!$this->isAborting(); | |||||
} | |||||
public function canAbortBuild() { | |||||
if ($this->isAutobuild()) { | |||||
return false; | |||||
} | |||||
return | |||||
!$this->isComplete() && | |||||
!$this->isAborting(); | |||||
} | |||||
public function canResumeBuild() { | |||||
if ($this->isAutobuild()) { | |||||
return false; | |||||
} | |||||
return | |||||
$this->isPaused() && | |||||
!$this->isResuming() && | |||||
!$this->isRestarting() && | |||||
!$this->isAborting(); | |||||
} | |||||
public function isPausing() { | public function isPausing() { | ||||
return $this->getBuildPendingStatusObject()->isPausing(); | return $this->getBuildPendingStatusObject()->isPausing(); | ||||
} | } | ||||
public function isResuming() { | public function isResuming() { | ||||
return $this->getBuildPendingStatusObject()->isResuming(); | return $this->getBuildPendingStatusObject()->isResuming(); | ||||
} | } | ||||
Show All 19 Lines | public function deleteUnprocessedMessages() { | ||||
foreach ($this->getUnprocessedMessages() as $key => $message_object) { | foreach ($this->getUnprocessedMessages() as $key => $message_object) { | ||||
$message_object->delete(); | $message_object->delete(); | ||||
unset($this->unprocessedMessages[$key]); | unset($this->unprocessedMessages[$key]); | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
public function canIssueCommand(PhabricatorUser $viewer, $command) { | |||||
try { | |||||
$this->assertCanIssueCommand($viewer, $command); | |||||
return true; | |||||
} catch (Exception $ex) { | |||||
return false; | |||||
} | |||||
} | |||||
public function assertCanIssueCommand(PhabricatorUser $viewer, $command) { | |||||
$plan = $this->getBuildPlan(); | |||||
// See T13526. Users without permission to access the build plan can | |||||
// currently end up here with no "BuildPlan" object. | |||||
if (!$plan) { | |||||
return false; | |||||
} | |||||
$need_edit = true; | |||||
switch ($command) { | |||||
case HarbormasterBuildCommand::COMMAND_RESTART: | |||||
case HarbormasterBuildCommand::COMMAND_PAUSE: | |||||
case HarbormasterBuildCommand::COMMAND_RESUME: | |||||
case HarbormasterBuildCommand::COMMAND_ABORT: | |||||
if ($plan->canRunWithoutEditCapability()) { | |||||
$need_edit = false; | |||||
} | |||||
break; | |||||
default: | |||||
throw new Exception( | |||||
pht( | |||||
'Invalid Harbormaster build command "%s".', | |||||
$command)); | |||||
} | |||||
// Issuing these commands requires that you be able to edit the build, to | |||||
// prevent enemy engineers from sabotaging your builds. See T9614. | |||||
if ($need_edit) { | |||||
PhabricatorPolicyFilter::requireCapability( | |||||
$viewer, | |||||
$plan, | |||||
PhabricatorPolicyCapability::CAN_EDIT); | |||||
} | |||||
} | |||||
public function sendMessage(PhabricatorUser $viewer, $message_type) { | public function sendMessage(PhabricatorUser $viewer, $message_type) { | ||||
HarbormasterBuildMessage::initializeNewMessage($viewer) | HarbormasterBuildMessage::initializeNewMessage($viewer) | ||||
->setReceiverPHID($this->getPHID()) | ->setReceiverPHID($this->getPHID()) | ||||
->setType($message_type) | ->setType($message_type) | ||||
->save(); | ->save(); | ||||
PhabricatorWorker::scheduleTask( | PhabricatorWorker::scheduleTask( | ||||
'HarbormasterBuildWorker', | 'HarbormasterBuildWorker', | ||||
▲ Show 20 Lines • Show All 169 Lines • Show Last 20 Lines |