/** * Send an email to a single recipient * * @param PipelineStep $source Client step * @param string $from * @param string $to * @param string $subject * @param string $body */ protected function sendViaEmail($source, $from, $to, $subject, $body) { $email = new Email($from, $to, $subject, $body); if ($source->getDryRun()) { $source->log("[Skipped] Sent message to {$to} (subject: {$subject})"); } else { $email->sendPlain(); $source->log("Sent message to {$to} (subject: {$subject})"); } }
public function markFailed($notify = true) { if ($this->getDryRun()) { $this->log("[Skipped] Smoke testing failed: Putting up emergency maintenance page"); } else { // Put up maintenance page after this fails $this->log("Smoke testing failed: Putting up emergency maintenance page"); $this->Pipeline()->Environment()->enableMaintenace($this->Pipeline()->getLogger()); } // Mark pipeline and step failed parent::markFailed($notify); }
/** * This method should be called only by the {@link CheckPipelineStatus} controller. It iterates through all the * {@link PipelineStep} objects associated with this Pipeline, and finds a place where the pipeline has stalled * (where one step has completed, but the next one has yet to start). It will then start the next step if required. * * We check here whether the {@link PipelineStep} finished successfully, and will mark the Pipeline as Failed if * the step failed, but this is only a fallback, and should not be relied upon. The individual {@link PipelineStep} * should mark itself as failed and then call {@link Pipeline::markFailed()} directly. * * If the Pipeline has run out of steps, then it will mark the pipeline as completed. */ public function checkPipelineStatus() { $message = ""; if (!$this->isActive()) { $message = "Pipeline::checkPipelineStatus() should only be called on running or rolling back pipelines."; } if (!$this->ID || !$this->isInDB()) { $message = "Pipeline::checkPipelineStatus() can only be called on pipelines already saved."; } $currentStep = $this->CurrentStep() && $this->CurrentStep()->isInDB() ? $this->CurrentStep() : null; if ($currentStep && $currentStep->PipelineID != $this->ID) { $message = sprintf("The current step (#%d) has a pipeline ID (#%d) that doesn't match this pipeline's ID (#%d).", $currentStep->ID, $currentStep->PipelineID, $this->ID); } if ($message) { $this->log($message); throw new LogicException($message); } // Fallback check only: this shouldn't be called unless a {@link PipelineStep} has been implemented incorrectly if ($currentStep && $currentStep->isFailed() && !$this->isFailed() && !$this->isRollback()) { $this->log(sprintf("Marking pipeline step (#%d) as failed - this pipeline step needs to be amended to mark" . " the pipeline (as well as itself) as failed to ensure consistency.", $this->CurrentStep()->ID)); $this->markFailed(); return; } // If this is the first time the Pipeline is run, then we don't have a CurrentStep, so set it, // start it running, and return if (!$currentStep) { $step = $this->Steps()->first(); $this->CurrentStepID = $step->ID; $this->write(); $this->log("Starting first pipeline step..."); $step->start(); } else { if ($currentStep->isFinished()) { // Sort through the list of {@link PipelineStep} objects to find the next step we need to start. $this->log("Finding next step to execute..."); $nextStep = $this->findNextStep(); if (!$nextStep) { // Special handling, since the main pipeline has already failed at this stage. if ($this->isRollback()) { $this->finaliseRollback(); return false; } // Double check for any steps that failed, but didn't notify the pipeline via markFailed. $failedSteps = PipelineStep::get()->filter(array('PipelineID' => $this->ID, 'Status' => 'Failed'))->count(); if ($failedSteps) { $this->log('At least one of the steps has failed marking the pipeline as failed'); $this->markFailed(); return false; } // We've reached the end of this pipeline successfully! $this->markComplete(); return; } else { $this->CurrentStepID = $nextStep->ID; $this->write(); // Otherwise, kick off the next step $this->log(sprintf("Found the next step (#%s), starting it now...", $nextStep->Name)); $nextStep->start(); } // if the current step is failing run it again } else { if ($step = $this->CurrentStep()) { $step->start(); } } } }