[object Object]

← back to Designer Wallcoverings

Add dev-theme push script for variant-button UX (targets dev theme, backup+verify, never live)

7cf36ba5eadbab4f59b684f5a88702dcbff41836 · 2026-06-21 18:23:58 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 7cf36ba5eadbab4f59b684f5a88702dcbff41836
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sun Jun 21 18:23:58 2026 -0700

    Add dev-theme push script for variant-button UX (targets dev theme, backup+verify, never live)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 shopify/push-variant-ux-to-dev-theme.sh | 70 +++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/shopify/push-variant-ux-to-dev-theme.sh b/shopify/push-variant-ux-to-dev-theme.sh
new file mode 100755
index 00000000..b9b94706
--- /dev/null
+++ b/shopify/push-variant-ux-to-dev-theme.sh
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+# Push the latest UX (variant buttons + price-restore hardening) from
+# _cwVERIFY/layout/theme.liquid to the Shopify DEV theme (never the live/main theme).
+# Backs up the dev theme's current theme.liquid first, then verifies the push.
+#
+# Run:  bash ~/Projects/Designer-Wallcoverings/shopify/push-variant-ux-to-dev-theme.sh
+set -euo pipefail
+cd "$(dirname "$0")"
+
+STORE="designer-laboratory-sandbox.myshopify.com"
+API="2024-10"
+SRC="_cwVERIFY/layout/theme.liquid"
+SECRETS="$HOME/Projects/secrets-manager/.env"
+
+# Theme-scoped token. CONTENT token is the candidate (themes = content scope);
+# override by exporting THEME_TOKEN=... before running if you have a Theme Access pw.
+TOK="${THEME_TOKEN:-$(grep -hE '^SHOPIFY_DW_ADMIN_TOKEN_CONTENT=' "$SECRETS" | head -1 | cut -d= -f2- | tr -d '"'"'"' ')}"
+[ -z "$TOK" ] && { echo "No theme token (SHOPIFY_DW_ADMIN_TOKEN_CONTENT) found; export THEME_TOKEN=… and retry"; exit 1; }
+[ -f "$SRC" ] || { echo "missing $SRC"; exit 1; }
+echo "token …${TOK: -4}  | source $SRC ($(wc -c <"$SRC") bytes)"
+
+echo "=== themes (id role name) ==="
+THEMES_JSON=$(curl -s "https://$STORE/admin/api/$API/themes.json" -H "X-Shopify-Access-Token: $TOK")
+echo "$THEMES_JSON" | python3 -c 'import sys,json
+d=json.load(sys.stdin)
+if "themes" not in d: print("API ERROR:",d); sys.exit(1)
+for t in d["themes"]: print(" ",t["id"],t["role"],"|",t["name"])'
+
+# Pick DEV theme: role=development, else newest non-main (unpublished). NEVER main.
+DEV_ID=$(echo "$THEMES_JSON" | python3 -c 'import sys,json
+ts=json.load(sys.stdin)["themes"]
+dev=[t for t in ts if t["role"]=="development"]
+if not dev: dev=sorted([t for t in ts if t["role"]!="main"], key=lambda t:t.get("updated_at",""), reverse=True)
+print(dev[0]["id"] if dev else "")')
+[ -z "$DEV_ID" ] && { echo "No dev/unpublished theme found. Create one in Online Store → Themes → Add theme, or push to a named theme."; exit 1; }
+echo "=== target DEV theme: $DEV_ID (NOT live) ==="
+
+mkdir -p theme-backups
+BK="theme-backups/theme.liquid.dev-$DEV_ID.$(date +%Y%m%d-%H%M%S).bak"
+curl -s "https://$STORE/admin/api/$API/themes/$DEV_ID/assets.json?asset[key]=layout/theme.liquid" \
+  -H "X-Shopify-Access-Token: $TOK" \
+  | python3 -c 'import sys,json;a=json.load(sys.stdin).get("asset");open(sys.argv[1],"w").write(a["value"]) if a else print("no existing asset (new theme)")' "$BK" || true
+[ -s "$BK" ] && echo "backup: $BK ($(wc -c <"$BK") bytes)" || echo "no prior theme.liquid backed up (theme may be empty)"
+
+echo "=== PUT layout/theme.liquid → dev theme $DEV_ID ==="
+python3 - "$STORE" "$API" "$DEV_ID" "$TOK" "$SRC" <<'PY'
+import sys,json,urllib.request
+store,api,tid,tok,src=sys.argv[1:6]
+val=open(src).read()
+body=json.dumps({"asset":{"key":"layout/theme.liquid","value":val}}).encode()
+req=urllib.request.Request(f"https://{store}/admin/api/{api}/themes/{tid}/assets.json",
+    data=body, method="PUT",
+    headers={"X-Shopify-Access-Token":tok,"Content-Type":"application/json"})
+try:
+    r=urllib.request.urlopen(req)
+    print("PUT HTTP",r.status,"OK")
+except urllib.error.HTTPError as e:
+    print("PUT FAILED HTTP",e.code,e.read().decode()[:300]); sys.exit(1)
+PY
+
+echo "=== verify (re-GET asset, check for new UX markers) ==="
+curl -s "https://$STORE/admin/api/$API/themes/$DEV_ID/assets.json?asset[key]=layout/theme.liquid" \
+  -H "X-Shopify-Access-Token: $TOK" \
+  | python3 -c 'import sys,json;v=json.load(sys.stdin)["asset"]["value"];print("dw-variant-btns:", v.count("dw-variant-btns"), "| theme-agnostic restore:", v.count("shopify-section-template")>0)'
+
+echo
+echo "PREVIEW the dev theme:"
+echo "  https://$STORE/?preview_theme_id=$DEV_ID"
+echo "  (or a product: https://www.designerwallcoverings.com/products/cirrus-jade-dwdx-220230?preview_theme_id=$DEV_ID )"
+echo "Revert if needed: PUT the backup file $BK back to layout/theme.liquid on theme $DEV_ID."

← 43eef3c8 rename inventory sweep to .mjs to silence MODULE_TYPELESS_PA  ·  back to Designer Wallcoverings  ·  Dev-theme push: pull→surgical-edit→push (drift-safe), target 8c327f87 →