← back to Designer Wallcoverings
pending-approval/toolbar-consolidation-assets/push-to-live.sh
85 lines
#!/usr/bin/env bash
# ============================================================================
# DW Collection-Page Toolbar Consolidation — LIVE PUSH
# Pushes 3 surgically-edited theme assets to the LIVE (role==main) theme.
# Race-safe: resolves role==main dynamically, backs up each asset before PUT,
# verifies byte-size after. Never hardcodes a theme id.
#
# Authored 2026-06-23 by vp-dw-commerce. Approved by Steve: ____________
# ============================================================================
set -euo pipefail
TOKEN="$(grep -E '^SHOPIFY_THEME_TOKEN=' "$HOME/Projects/secrets-manager/.env" | cut -d= -f2-)"
DOMAIN="designer-laboratory-sandbox.myshopify.com"
VER="2024-10"
SRC_DIR="$HOME/Projects/Designer-Wallcoverings/pending-approval/toolbar-consolidation-assets"
BK_DIR="$HOME/Projects/Designer-Wallcoverings/shopify/theme-backups/toolbar-consolidation-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BK_DIR"
if [ -z "$TOKEN" ]; then echo "FATAL: SHOPIFY_THEME_TOKEN not found"; exit 1; fi
# --- 1. Resolve the LIVE theme (role==main) dynamically ---
LIVE="$(curl -s "https://$DOMAIN/admin/api/$VER/themes.json" \
-H "X-Shopify-Access-Token: $TOKEN" \
| python3 -c "import sys,json;print(next(t['id'] for t in json.load(sys.stdin)['themes'] if t['role']=='main'))")"
if ! [[ "$LIVE" =~ ^[0-9]+$ ]]; then echo "FATAL: could not resolve role==main theme (got '$LIVE')"; exit 1; fi
echo "LIVE theme (role==main) = $LIVE"
echo "Backups -> $BK_DIR"
echo
enc() { python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$1"; }
push_asset() {
local KEY="$1" SRCFILE="$2"
local ENC; ENC="$(enc "$KEY")"
local SAFE="${KEY//\//__}"
echo "==== $KEY ===="
# 1a. backup current live value
curl -s "https://$DOMAIN/admin/api/$VER/themes/$LIVE/assets.json?asset%5Bkey%5D=$ENC" \
-H "X-Shopify-Access-Token: $TOKEN" \
| python3 -c "
import sys,json
a=json.load(sys.stdin).get('asset')
if not a or a.get('value') is None:
print(' WARN: no current value to back up (new asset?)'); sys.exit(0)
open('$BK_DIR/$SAFE','w').write(a['value'])
print(' backed up', len(a['value']), 'bytes ->', '$BK_DIR/$SAFE')
"
# 1b. PUT the edited value
local PAYLOAD; PAYLOAD="$(python3 -c "
import json,sys
print(json.dumps({'asset':{'key':sys.argv[1],'value':open(sys.argv[2]).read()}}))
" "$KEY" "$SRCFILE")"
local HTTP; HTTP="$(curl -s -o /tmp/_dw_put_resp.json -w '%{http_code}' -X PUT \
"https://$DOMAIN/admin/api/$VER/themes/$LIVE/assets.json" \
-H "X-Shopify-Access-Token: $TOKEN" -H "Content-Type: application/json" \
-d "$PAYLOAD")"
if [ "$HTTP" != "200" ] && [ "$HTTP" != "201" ]; then
echo " PUT FAILED http=$HTTP"; cat /tmp/_dw_put_resp.json; echo; return 1
fi
# 1c. verify size after
local EXPECT; EXPECT="$(wc -c < "$SRCFILE" | tr -d ' ')"
sleep 1
local ACTUAL; ACTUAL="$(curl -s "https://$DOMAIN/admin/api/$VER/themes/$LIVE/assets.json?asset%5Bkey%5D=$ENC" \
-H "X-Shopify-Access-Token: $TOKEN" \
| python3 -c "import sys,json;a=json.load(sys.stdin).get('asset');print(len(a.get('value') or '') if a else 0)")"
echo " PUT ok (http=$HTTP). expected ~${EXPECT}b, live now ${ACTUAL}b"
echo
}
# --- 2. Push the 3 consolidated assets ---
push_asset "snippets/collection-toolbar.liquid" "$SRC_DIR/snippets__collection-toolbar.liquid"
push_asset "sections/collection.liquid" "$SRC_DIR/sections__collection.liquid"
push_asset "layout/theme.liquid" "$SRC_DIR/layout__theme.liquid"
echo "============================================================"
echo "DONE. Live theme $LIVE updated with the consolidated toolbar."
echo "Verify in a real browser (hard-refresh / incognito):"
echo " https://www.designerwallcoverings.com/collections/1838-wallcoverings"
echo "Expect: 1 sort dropdown + 1 density slider + filter chips,"
echo " density slider changes grid columns, and the"
echo " 'addEventListener of null' pageerror is gone."
echo "Rollback: restore any file from $BK_DIR via the same PUT."
echo "============================================================"