From 76f5dc09abedbc50c598a9bc692179adbc3a8930 Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 7 Jul 2026 13:57:47 -0400 Subject: [PATCH] Trigger Portainer stack webhooks after image push Adds a main-only Redeploy stage that POSTs to two Portainer stack webhooks (re-pull + redeploy) after a successful push. URLs are read from Secret-text credentials so they stay out of the repo and logs. Gated by the REDEPLOY_PORTAINER parameter. Co-Authored-By: Claude Opus 4.8 --- Jenkinsfile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index d2b4be2..aa4cbb3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -34,6 +34,8 @@ pipeline { description: 'Also tag and push :latest in addition to the commit-SHA tag.') booleanParam(name: 'REGISTRY_AUTH', defaultValue: false, description: 'Enable docker login using the thinkserver-registry credential.') + booleanParam(name: 'REDEPLOY_PORTAINER', defaultValue: true, + description: 'After pushing, POST to the Portainer stack webhooks to re-pull and redeploy.') } environment { @@ -133,6 +135,28 @@ pipeline { } } } + + stage('Redeploy (Portainer webhooks)') { + when { allOf { expression { env.IS_MAIN == 'true' }; expression { return params.REDEPLOY_PORTAINER } } } + steps { + // Webhook URLs are Secret-text credentials, so they never appear in the + // repo and Jenkins masks them in the console. They are bound to shell + // env vars and referenced inside a single-quoted sh block, so Groovy + // never interpolates the value into the pipeline log. + withCredentials([ + string(credentialsId: 'portainer-webhook-firebase', variable: 'WEBHOOK_FIREBASE'), + string(credentialsId: 'portainer-webhook-sqlite', variable: 'WEBHOOK_SQLITE'), + ]) { + sh ''' + set +x + echo "Triggering Portainer redeploy (firebase stack)" + curl -fsS -X POST --retry 3 --retry-delay 5 "$WEBHOOK_FIREBASE" + echo "Triggering Portainer redeploy (sqlite stack)" + curl -fsS -X POST --retry 3 --retry-delay 5 "$WEBHOOK_SQLITE" + ''' + } + } + } } post {