climaybe 3.1.4 โ†’ 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/version.txt CHANGED
@@ -1 +1 @@
1
- 3.1.4
1
+ 3.2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "climaybe",
3
- "version": "3.1.4",
3
+ "version": "3.2.0",
4
4
  "description": "Shopify CLI by Electric Maybe for theme CI/CD workflows, branch orchestration, app setup, and dev tooling",
5
5
  "type": "module",
6
6
  "bin": {
@@ -232,8 +232,14 @@ export function serveAssets({ cwd = process.cwd(), includeThemeCheck = false } =
232
232
  writeTaggedLine('tailwind', pc.blue, 'watching _styles/main.css -> assets/style.css');
233
233
  }
234
234
 
235
- // Optional dev MCP (non-blocking if missing)
236
- const devMcp = spawnLogged('npx', ['-y', '@shopify/dev-mcp@latest'], { name: 'dev-mcp', cwd });
235
+ // Optional dev MCP (non-blocking if missing). @shopify/dev-mcp pulls hydrogen (peers react-router 7.12)
236
+ // alongside react-router 7.13 โ€” npm warns with ERESOLVE unless legacy peer resolution is enabled.
237
+ const devMcpEnv = { ...process.env, npm_config_legacy_peer_deps: 'true' };
238
+ const devMcp = spawnLogged('npx', ['-y', '@shopify/dev-mcp@latest'], {
239
+ name: 'dev-mcp',
240
+ cwd,
241
+ env: devMcpEnv,
242
+ });
237
243
 
238
244
  const scriptsDir = join(cwd, '_scripts');
239
245
  if (existsSync(scriptsDir)) {
@@ -15,6 +15,7 @@ jobs:
15
15
  resolve-store:
16
16
  runs-on: ubuntu-latest
17
17
  outputs:
18
+ store_alias: ${{ steps.resolve.outputs.alias }}
18
19
  store_alias_secret: ${{ steps.resolve.outputs.alias_secret }}
19
20
  steps:
20
21
  - name: Checkout code
@@ -80,7 +81,7 @@ jobs:
80
81
  secrets: inherit
81
82
 
82
83
  comment-on-pr:
83
- needs: cleanup-theme
84
+ needs: [cleanup-theme, resolve-store]
84
85
  runs-on: ubuntu-latest
85
86
  steps:
86
87
  - name: Comment on PR about cleanup
@@ -88,6 +89,7 @@ jobs:
88
89
  with:
89
90
  script: |
90
91
  const prNumber = context.payload.pull_request.number;
92
+ const storeAlias = '${{ needs.resolve-store.outputs.store_alias }}' || '';
91
93
  const deletedCount = parseInt('${{ needs.cleanup-theme.outputs.deleted_count }}') || 0;
92
94
  const deletedThemesRaw = `${{ needs.cleanup-theme.outputs.deleted_themes }}`.trim();
93
95
 
@@ -98,8 +100,9 @@ jobs:
98
100
  '',
99
101
  `**Branch:** ${context.payload.pull_request.head.ref}`,
100
102
  `**PR Status:** ${context.payload.pull_request.state}`,
103
+ storeAlias ? `**Store:** ${storeAlias}` : null,
101
104
  `**Deleted Themes:** ${deletedCount}`
102
- ];
105
+ ].filter(Boolean);
103
106
 
104
107
  if (deletedCount > 0 && deletedThemesRaw) {
105
108
  const deletedThemeLines = deletedThemesRaw
@@ -18,6 +18,18 @@ on:
18
18
  deleted_themes:
19
19
  description: "Deleted theme names, one per line"
20
20
  value: ${{ jobs.cleanup.outputs.deleted_themes }}
21
+ matched_count:
22
+ description: "Number of themes matching this PR (before delete)"
23
+ value: ${{ jobs.cleanup.outputs.matched_count }}
24
+ matched_themes:
25
+ description: "Matched theme names, one per line (before delete)"
26
+ value: ${{ jobs.cleanup.outputs.matched_themes }}
27
+ skipped_reason:
28
+ description: "Why cleanup was skipped (empty if not skipped)"
29
+ value: ${{ jobs.cleanup.outputs.skipped_reason }}
30
+ store_hint:
31
+ description: "Redacted store host (best-effort; may be masked)"
32
+ value: ${{ jobs.cleanup.outputs.store_hint }}
21
33
 
22
34
  jobs:
23
35
  cleanup:
@@ -25,6 +37,10 @@ jobs:
25
37
  outputs:
26
38
  deleted_count: ${{ steps.cleanup.outputs.deleted_count }}
27
39
  deleted_themes: ${{ steps.cleanup.outputs.deleted_themes }}
40
+ matched_count: ${{ steps.cleanup.outputs.matched_count }}
41
+ matched_themes: ${{ steps.cleanup.outputs.matched_themes }}
42
+ skipped_reason: ${{ steps.cleanup.outputs.skipped_reason }}
43
+ store_hint: ${{ steps.cleanup.outputs.store_hint }}
28
44
  steps:
29
45
  - name: Install Shopify CLI
30
46
  run: npm install -g @shopify/cli @shopify/theme
@@ -35,20 +51,86 @@ jobs:
35
51
  SHOPIFY_STORE_URL: ${{ inputs.store_alias_secret && secrets[format('SHOPIFY_STORE_URL_{0}', inputs.store_alias_secret)] || secrets.SHOPIFY_STORE_URL }}
36
52
  SHOPIFY_THEME_ACCESS_TOKEN: ${{ inputs.store_alias_secret && secrets[format('SHOPIFY_THEME_ACCESS_TOKEN_{0}', inputs.store_alias_secret)] || secrets.SHOPIFY_THEME_ACCESS_TOKEN }}
37
53
  PR_NUMBER: ${{ inputs.pr_number }}
54
+ STORE_ALIAS_SECRET: ${{ inputs.store_alias_secret }}
38
55
  run: |
39
- if [ -z "$SHOPIFY_STORE_URL" ] || [ -z "$SHOPIFY_THEME_ACCESS_TOKEN" ]; then
56
+ set -euo pipefail
57
+
58
+ STORE_HOST="${SHOPIFY_STORE_URL#https://}"
59
+ STORE_HOST="${STORE_HOST#http://}"
60
+ STORE_HOST="${STORE_HOST%%/*}"
61
+
62
+ {
63
+ echo "### ๐Ÿงน Cleanup preview themes"
64
+ echo ""
65
+ echo "- **PR**: \`${PR_NUMBER}\`"
66
+ echo "- **Store alias secret**: \`${STORE_ALIAS_SECRET:-<default>}\`"
67
+ echo "- **Store (host)**: \`${STORE_HOST:-<missing>}\`"
68
+ } >> "$GITHUB_STEP_SUMMARY"
69
+
70
+ echo "PR=${PR_NUMBER}"
71
+ echo "Store alias secret=${STORE_ALIAS_SECRET:-<default>}"
72
+ echo "Store host=${STORE_HOST:-<missing>}"
73
+
74
+ if [ -z "${SHOPIFY_STORE_URL:-}" ] || [ -z "${SHOPIFY_THEME_ACCESS_TOKEN:-}" ]; then
40
75
  echo "Missing Shopify secrets; skipping theme cleanup (no themes deleted)."
41
- echo "deleted_count=0" >> $GITHUB_OUTPUT
42
- echo "deleted_themes<<DELETED_EOF" >> $GITHUB_OUTPUT
43
- echo "DELETED_EOF" >> $GITHUB_OUTPUT
76
+
77
+ {
78
+ echo ""
79
+ echo "#### Result"
80
+ echo "- **Skipped**: yes (missing Shopify secrets)"
81
+ echo "- **Matched themes**: 0"
82
+ echo "- **Deleted themes**: 0"
83
+ } >> "$GITHUB_STEP_SUMMARY"
84
+
85
+ echo "skipped_reason=missing_secrets" >> "$GITHUB_OUTPUT"
86
+ echo "store_hint=${STORE_HOST:-}" >> "$GITHUB_OUTPUT"
87
+ echo "matched_count=0" >> "$GITHUB_OUTPUT"
88
+ echo "matched_themes<<MATCHED_EOF" >> "$GITHUB_OUTPUT"
89
+ echo "MATCHED_EOF" >> "$GITHUB_OUTPUT"
90
+ echo "deleted_count=0" >> "$GITHUB_OUTPUT"
91
+ echo "deleted_themes<<DELETED_EOF" >> "$GITHUB_OUTPUT"
92
+ echo "DELETED_EOF" >> "$GITHUB_OUTPUT"
44
93
  exit 0
45
94
  fi
46
95
 
47
- THEME_LIST=$(shopify theme list \
96
+ echo "store_hint=${STORE_HOST:-}" >> "$GITHUB_OUTPUT"
97
+ echo "skipped_reason=" >> "$GITHUB_OUTPUT"
98
+
99
+ THEME_LIST_ERR="$(mktemp)"
100
+ THEME_LIST_JSON="$(mktemp)"
101
+
102
+ if ! shopify theme list \
48
103
  --store "$SHOPIFY_STORE_URL" \
49
104
  --password "$SHOPIFY_THEME_ACCESS_TOKEN" \
50
- --json 2>/dev/null || echo "[]")
105
+ --json > "$THEME_LIST_JSON" 2> "$THEME_LIST_ERR"; then
106
+ echo "shopify theme list failed."
107
+ echo "Error output (first 120 lines):"
108
+ sed -n '1,120p' "$THEME_LIST_ERR" || true
109
+ {
110
+ echo ""
111
+ echo "#### Result"
112
+ echo "- **Error**: \`shopify theme list\` failed"
113
+ echo ""
114
+ echo "<details><summary>CLI error output</summary>"
115
+ echo ""
116
+ echo "\`\`\`"
117
+ sed -n '1,240p' "$THEME_LIST_ERR" || true
118
+ echo "\`\`\`"
119
+ echo "</details>"
120
+ } >> "$GITHUB_STEP_SUMMARY"
121
+ exit 1
122
+ fi
123
+
124
+ # Defensive: if CLI returned empty, treat as an empty list (instead of jq failure).
125
+ if [ ! -s "$THEME_LIST_JSON" ]; then
126
+ echo "[]" > "$THEME_LIST_JSON"
127
+ fi
128
+
129
+ ALL_COUNT="$(jq -r 'length' "$THEME_LIST_JSON" 2>/dev/null || echo "0")"
130
+ echo "Found ${ALL_COUNT} total theme(s) on store."
51
131
 
132
+ MATCHED_COUNT=0
133
+ MATCHED_THEMES=""
52
134
  DELETED_COUNT=0
53
135
  DELETED_THEMES=""
54
136
 
@@ -57,22 +139,61 @@ jobs:
57
139
  [ -z "$THEME_NAME" ] && continue
58
140
 
59
141
  if printf "%s" "$THEME_NAME" | grep -q "PR${PR_NUMBER}"; then
142
+ MATCHED_COUNT=$((MATCHED_COUNT + 1))
143
+ MATCHED_THEMES="${MATCHED_THEMES}${THEME_NAME}\n"
144
+ echo "Matched: $THEME_NAME ($THEME_ID)"
145
+
146
+ DELETE_ERR="$(mktemp)"
60
147
  if shopify theme delete \
61
148
  --store "$SHOPIFY_STORE_URL" \
62
149
  --password "$SHOPIFY_THEME_ACCESS_TOKEN" \
63
150
  --force \
64
- --theme "$THEME_ID" 2>/dev/null; then
151
+ --theme "$THEME_ID" 1>/dev/null 2>"$DELETE_ERR"; then
65
152
  DELETED_COUNT=$((DELETED_COUNT + 1))
66
153
  DELETED_THEMES="${DELETED_THEMES}${THEME_NAME}\n"
154
+ echo "Deleted: $THEME_NAME ($THEME_ID)"
67
155
  else
68
- echo "Failed to delete theme: $THEME_NAME ($THEME_ID)"
156
+ echo "Failed to delete: $THEME_NAME ($THEME_ID)"
157
+ echo "Delete error output (first 80 lines):"
158
+ sed -n '1,80p' "$DELETE_ERR" || true
69
159
  fi
70
160
  fi
71
- done < <(echo "$THEME_LIST" | jq -r '.[] | [.id, .name] | @tsv')
161
+ done < <(jq -r '.[] | [.id, .name] | @tsv' "$THEME_LIST_JSON")
162
+
163
+ {
164
+ echo ""
165
+ echo "#### Result"
166
+ echo "- **Total themes on store**: ${ALL_COUNT}"
167
+ echo "- **Matched (PR${PR_NUMBER})**: ${MATCHED_COUNT}"
168
+ echo "- **Deleted**: ${DELETED_COUNT}"
169
+ } >> "$GITHUB_STEP_SUMMARY"
170
+
171
+ if [ "$MATCHED_COUNT" -gt 0 ]; then
172
+ {
173
+ echo ""
174
+ echo "#### Matched theme names"
175
+ printf "%b" "$MATCHED_THEMES" | sed -e 's/^/- /'
176
+ } >> "$GITHUB_STEP_SUMMARY"
177
+ fi
178
+
179
+ if [ "$DELETED_COUNT" -gt 0 ]; then
180
+ {
181
+ echo ""
182
+ echo "#### Deleted theme names"
183
+ printf "%b" "$DELETED_THEMES" | sed -e 's/^/- /'
184
+ } >> "$GITHUB_STEP_SUMMARY"
185
+ fi
186
+
187
+ echo "matched_count=$MATCHED_COUNT" >> "$GITHUB_OUTPUT"
188
+ {
189
+ echo "matched_themes<<MATCHED_EOF"
190
+ printf "%b" "$MATCHED_THEMES"
191
+ echo "MATCHED_EOF"
192
+ } >> "$GITHUB_OUTPUT"
72
193
 
73
- echo "deleted_count=$DELETED_COUNT" >> $GITHUB_OUTPUT
194
+ echo "deleted_count=$DELETED_COUNT" >> "$GITHUB_OUTPUT"
74
195
  {
75
196
  echo "deleted_themes<<DELETED_EOF"
76
197
  printf "%b" "$DELETED_THEMES"
77
198
  echo "DELETED_EOF"
78
- } >> $GITHUB_OUTPUT
199
+ } >> "$GITHUB_OUTPUT"