From a358b58675067e7a2701f373b446538e31cb839d Mon Sep 17 00:00:00 2001 From: Tu Van Date: Thu, 27 Aug 2026 12:23:24 +0700 Subject: [PATCH] Remove the live release's crontab block in magento:cron:stop cron:remove only removes the crontab block of the installation it is run from, because CrontabManager keys the block on hash('sha256', BP). previous_release is releases_list[1], which stops being the live release once a failed deploy leaves a release directory behind, so the live block survives and magento:cron:install then adds a second one. Two cron:run entries then execute every minute, one of them against the previous release's code. current_path is still the live release at this point, since the task runs before deploy:symlink. --- recipe/magento2.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/recipe/magento2.php b/recipe/magento2.php index 12d612657..af8c66187 100644 --- a/recipe/magento2.php +++ b/recipe/magento2.php @@ -593,8 +593,18 @@ function magentoDeployAssetsSplit(string $area): void */ desc('Remove cron from crontab and kill running cron jobs'); task('magento:cron:stop', function () { - if (has('previous_release') && test("[ -f {{previous_release}}/{{magento_dir}}/bin/magento ]")) { - run('{{bin/php}} {{previous_release}}/{{magento_dir}}/bin/magento cron:remove'); + // Magento keys each crontab block to the base path `cron:install` was run from + // (CrontabManager::getTasksBlockStart() appends hash('sha256', BP)), so `cron:remove` only + // removes the block of the installation it is run from. The block to remove therefore belongs to + // the release that is currently live, which is not necessarily {{previous_release}}: that is + // releases_list[1], so a release directory left behind by a failed deploy takes its place. + // Removing the wrong block leaves the live one in the crontab, and magento:cron:install then adds + // a second, leaving two cron:run entries running every minute. + // + // This task runs before deploy:symlink, so {{current_path}} is still the live release. __DIR__ + // resolves the symlink, so BP is the real release path and the hash matches. + if (test("[ -f {{current_path}}/{{magento_dir}}/bin/magento ]")) { + run('{{bin/php}} {{current_path}}/{{magento_dir}}/bin/magento cron:remove'); } run('pgrep -U "$(id -u)" -f "bin/magento +(cron:run|queue:consumers:start)" | xargs -r kill');