From ac8f6aa75b3a518cae980fda1ff03a41d9ba0e65 Mon Sep 17 00:00:00 2001 From: Aron Novak Date: Fri, 28 Nov 2025 09:08:24 +0100 Subject: [PATCH] Fix: Robust deployment regression protection using ancestry check --- robo-components/DeploymentTrait.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/robo-components/DeploymentTrait.php b/robo-components/DeploymentTrait.php index 159e866ea..7116a2693 100644 --- a/robo-components/DeploymentTrait.php +++ b/robo-components/DeploymentTrait.php @@ -284,15 +284,18 @@ public function deployPantheon(string $branch_name = 'master', ?string $commit_m $current_version = trim($result->getMessage()); if (!empty($currently_deployed_version)) { - $result = $this - ->taskExec('git cat-file -t ' . $currently_deployed_version) + // Check if the currently deployed version is an ancestor of the current version. + // This returns exit code 0 if it is an ancestor, 1 if not, and 128 if the object is missing. + // In any case other than 0, we must not deploy to prevent regression. + $is_ancestor = $this->taskExec("git merge-base --is-ancestor $currently_deployed_version $current_version") ->printOutput(FALSE) - ->run(); + ->run() + ->getExitCode() === 0; - if ($result->getMessage() !== 'commit') { - $this->yell(strtr('This current commit @current-commit cannot be deployed, as new commits have been created since, so we don\'t want to deploy an older version. Result was: @result', [ - '@current-commit' => $current_version, - '@result' => $result->getMessage(), + if (!$is_ancestor) { + $this->yell(strtr('The currently deployed version (@deployed) is not an ancestor of the current version (@current). Aborting the process to avoid going back in time.', [ + '@deployed' => $currently_deployed_version, + '@current' => $current_version, ])); throw new \Exception('Aborting the process to avoid going back in time.'); }