deploy.yml: fix pipeline compile error 'missing closing brace' -- the documentation comment itself contained a literal dollar-brace sequence with invalid contents (dollar-brace CI_...), which Woodpecker's substitution engine parses even inside comments. Rewrote header to describe the rules in words without any literal dollar-brace sequences. Also removed backtick-quoted dollar-brace remnants from the vaultwarden case comment.
ci/woodpecker/push/deploy Pipeline was successful

This commit is contained in:
2026-07-27 13:35:13 -07:00
parent 9b3bba636c
commit e0a6b7d233
+21 -16
View File
@@ -5,22 +5,27 @@ when:
# ───────────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────────
# IMPORTANT — Woodpecker variable substitution rules (learned the hard way): # IMPORTANT — Woodpecker variable substitution rules (learned the hard way):
# #
# Woodpecker pre-processes command strings BEFORE the shell runs them: # Woodpecker pre-processes the ENTIRE yaml text (comments included!) before
# - ${VAR} is substituted at pipeline-compile time from Woodpecker's own # the shell runs anything:
# metadata (CI_* vars). Secrets DO NOT exist in that map, so any braced # - A dollar sign followed by a braced variable name is substituted at
# reference to a secret-backed env var silently becomes an EMPTY STRING. # pipeline-compile time from Woodpecker's own metadata (the CI_* vars).
# - $$ is unescaped to a single $ and passed to the shell. # Secrets DO NOT exist in that map, so a braced reference to a
# secret-backed env var silently becomes an EMPTY STRING.
# - A double dollar sign is unescaped to a single dollar sign and passed
# through to the shell untouched.
# #
# Therefore: # Therefore:
# - Use ${CI_...} (braced, unescaped) ONLY for Woodpecker metadata vars. # - Braced, single-dollar form: ONLY for Woodpecker CI_* metadata vars.
# - Use $${VAR} for anything that must be resolved by the shell at runtime # - Double-dollar braced form: for everything that must be resolved by the
# (i.e., every from_secret-backed environment variable). # shell at runtime (i.e., every from_secret-backed environment variable).
# - Bare $VAR (no braces) also works for runtime resolution, but $${VAR} # - Bare single-dollar VAR (no braces) also passes through to the shell.
# is preferred for anything adjacent to other characters. # - NEVER write a literal dollar-brace sequence in comments either — the
# substitution engine parses comments too and will fail the pipeline
# with "missing closing brace" on anything it cannot parse.
# #
# This was the root cause of a long-running "SWARM_MANAGER_IP secret is # This was the root cause of a long-running "SWARM_MANAGER_IP secret is
# empty" failure: the braced references were being blanked at compile time # empty" failure: braced references were blanked at compile time before the
# before the shell ever saw them. # shell ever saw them.
# ───────────────────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────────────────
steps: steps:
@@ -200,10 +205,10 @@ steps:
create_or_update_secret 'productivity_oidc_providers' '$${PRODUCTIVITY_OIDC_PROVIDERS}'";; create_or_update_secret 'productivity_oidc_providers' '$${PRODUCTIVITY_OIDC_PROVIDERS}'";;
vaultwarden) vaultwarden)
# NOTE: vaultwarden_database_url cannot be rotated in-place — Swarm refuses # NOTE: vaultwarden_database_url cannot be rotated in-place — Swarm refuses
# to `docker secret rm` a secret referenced by a running service's spec. # to remove a secret referenced by a running service's spec. We provision
# We provision under a versioned name (_v2) instead; vaultwarden.yaml maps # under a versioned name instead; vaultwarden.yaml maps it back to the same
# it back to the same in-container filename via `target:`. The old secret # in-container filename via target. The old secret is removed manually once
# is removed manually once the compose file cutover is confirmed healthy. # the compose file cutover is confirmed healthy.
ssh -o StrictHostKeyChecking=no root@$${SWARM_MANAGER_IP} "source /tmp/cs.sh ssh -o StrictHostKeyChecking=no root@$${SWARM_MANAGER_IP} "source /tmp/cs.sh
create_or_update_secret 'vaultwarden_admin_token' '$${VAULTWARDEN_ADMIN_TOKEN}' create_or_update_secret 'vaultwarden_admin_token' '$${VAULTWARDEN_ADMIN_TOKEN}'
create_or_update_secret 'vaultwarden_database_url_v2' '$${VAULTWARDEN_DATABASE_URL}'";; create_or_update_secret 'vaultwarden_database_url_v2' '$${VAULTWARDEN_DATABASE_URL}'";;