From b4d4eb6f5b31b4a664d095b0478c08634ef88859 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Thu, 25 Dec 2025 12:14:28 +0300 Subject: [PATCH 1/5] Improve prod-deploy error handling --- Makefile | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 49d1505..2596522 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,18 @@ endif ifeq ($(PRIMARY_GOAL),prod-deploy) prod-deploy: ## PROD | Deploy to production - docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} + set -euo pipefail + docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log + if grep -qiE 'rollback:|update rolled back' deploy.log; then + FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')" + if [ -n "${FAILED_TASK_ID}" ]; then + echo "Docker Swarm update rolled back; failing job. Failed task ID: ${FAILED_TASK_ID}" + echo "--- docker service logs (${FAILED_TASK_ID}) ---" + docker -H ${PROD_SSH} service logs --timestamps --tail 500 "${FAILED_TASK_ID}" || true + else + echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.' + fi + fi endif # From 2630e0a8fbe025e53c2d7f88711300ff0cfc5ac9 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 26 Dec 2025 20:59:53 +0300 Subject: [PATCH 2/5] Update Makefile Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 2596522..b4d0bb3 100644 --- a/Makefile +++ b/Makefile @@ -133,6 +133,7 @@ prod-deploy: ## PROD | Deploy to production else echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.' fi + exit 1 fi endif From 8832bc155f2dbd51a47f2d882efb000b0b59bdf2 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 26 Dec 2025 21:00:45 +0300 Subject: [PATCH 3/5] Update Makefile Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b4d0bb3..cb96f79 100644 --- a/Makefile +++ b/Makefile @@ -123,6 +123,7 @@ endif ifeq ($(PRIMARY_GOAL),prod-deploy) prod-deploy: ## PROD | Deploy to production set -euo pipefail + rm -f deploy.log docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log if grep -qiE 'rollback:|update rolled back' deploy.log; then FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')" From c91b32749b7bc5c27c3b6201dd73d8b5597976c8 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 26 Dec 2025 21:01:02 +0300 Subject: [PATCH 4/5] Update Makefile Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index cb96f79..0c72e32 100644 --- a/Makefile +++ b/Makefile @@ -123,17 +123,17 @@ endif ifeq ($(PRIMARY_GOAL),prod-deploy) prod-deploy: ## PROD | Deploy to production set -euo pipefail - rm -f deploy.log - docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log - if grep -qiE 'rollback:|update rolled back' deploy.log; then - FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')" - if [ -n "${FAILED_TASK_ID}" ]; then - echo "Docker Swarm update rolled back; failing job. Failed task ID: ${FAILED_TASK_ID}" - echo "--- docker service logs (${FAILED_TASK_ID}) ---" - docker -H ${PROD_SSH} service logs --timestamps --tail 500 "${FAILED_TASK_ID}" || true - else - echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.' - fi + set -euo pipefail; \ + docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log; \ + if grep -qiE 'rollback:|update rolled back' deploy.log; then \ + FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')"; \ + if [ -n "${FAILED_TASK_ID}" ]; then \ + echo "Docker Swarm update rolled back; failing job. Failed task ID: ${FAILED_TASK_ID}"; \ + echo "--- docker service logs (${FAILED_TASK_ID}) ---"; \ + docker -H ${PROD_SSH} service logs --timestamps --tail 500 "${FAILED_TASK_ID}" || true; \ + else \ + echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.'; \ + fi; \ exit 1 fi endif From b3e22335378253fa331df883d607085868e2fcdd Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 26 Dec 2025 21:11:22 +0300 Subject: [PATCH 5/5] Add changelog, adjust script --- CHANGELOG.md | 2 +- Makefile | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0e5c2..2610d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.1.1 under development -- no changes in this release. +- New #421: Improve `prod-deploy` error handling so exact error is printed in case of rollback (@samdark) ## 1.1.0 December 20, 2025 diff --git a/Makefile b/Makefile index 0c72e32..60b2470 100644 --- a/Makefile +++ b/Makefile @@ -122,19 +122,18 @@ endif ifeq ($(PRIMARY_GOAL),prod-deploy) prod-deploy: ## PROD | Deploy to production - set -euo pipefail - set -euo pipefail; \ - docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log; \ - if grep -qiE 'rollback:|update rolled back' deploy.log; then \ - FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')"; \ + set -euo pipefail \ + docker -H ${PROD_SSH} stack deploy --prune --detach=false --with-registry-auth -c docker/compose.yml -c docker/prod/compose.yml ${STACK_NAME} 2>&1 | tee deploy.log \ + if grep -qiE 'rollback:|update rolled back' deploy.log then \ + FAILED_TASK_ID="$(grep -oiE 'task[[:space:]]+[a-z0-9]+' deploy.log | head -n 1 | awk '{print $2}')" \ if [ -n "${FAILED_TASK_ID}" ]; then \ - echo "Docker Swarm update rolled back; failing job. Failed task ID: ${FAILED_TASK_ID}"; \ - echo "--- docker service logs (${FAILED_TASK_ID}) ---"; \ - docker -H ${PROD_SSH} service logs --timestamps --tail 500 "${FAILED_TASK_ID}" || true; \ + echo "Docker Swarm update rolled back; failing job. Failed task ID: ${FAILED_TASK_ID}" \ + echo "--- docker service logs (${FAILED_TASK_ID}) ---" \ + docker -H ${PROD_SSH} service logs --timestamps --tail 500 "${FAILED_TASK_ID}" || true \ else \ - echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.'; \ - fi; \ - exit 1 + echo 'Docker Swarm update rolled back; failing job. Failed task ID: not found in deploy output.' \ + fi \ + exit 1 \ fi endif