protected function beginPipeline($data, $form, $isDryRun = false) {
		$buildName = $form->getSelectedBuild($data);

		// Performs canView permission check by limiting visible projects
		$project = $this->getCurrentProject();
		if(!$project) {
			return new SS_HTTPResponse("Project '" . Convert::raw2xml($this->getRequest()->latestParam('Project')) . "' not found.", 404);
		}

		// Performs canView permission check by limiting visible projects
		$environment = $this->getCurrentEnvironment($project);
		if(!$environment) {
			return new SS_HTTPResponse("Environment '" . Convert::raw2xml($this->getRequest()->latestParam('Environment')) . "' not found.", 404);
		}

		if(!$environment->DryRunEnabled && $isDryRun) {
			return new SS_HTTPResponse("Dry-run for pipelines is not enabled for this environment", 404);
		}

		// Initiate the pipeline
		$sha = $project->DNBuildList()->byName($buildName);
		$pipeline = Pipeline::create();
		$pipeline->DryRun = $isDryRun;
		$pipeline->SkipSnapshot = !empty($data['SkipSnapshot']) && $data['SkipSnapshot'];
		$pipeline->EnvironmentID = $environment->ID;
		$pipeline->AuthorID = Member::currentUserID();
		$pipeline->SHA = $sha->FullName();
		// Record build at time of execution
		if($currentBuild = $environment->CurrentBuild()) {
			$pipeline->PreviousDeploymentID = $currentBuild->ID;
		}
		$pipeline->start(); // start() will call write(), so no need to do it here as well.
		return $this->redirect($environment->Link());
	}