climaybe 1.5.0 → 1.5.1

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/README.md CHANGED
@@ -232,7 +232,7 @@ Add the following secrets to your GitHub repository (or use **GitLab CI/CD varia
232
232
 
233
233
  **Store URL:** During `climaybe init` (or `add-store`), store URL secret(s) are set from your configured store domain(s); you are only prompted for the theme token.
234
234
 
235
- **Multi-store:** Per-store secrets `SHOPIFY_STORE_URL_<ALIAS>` and `SHOPIFY_THEME_ACCESS_TOKEN_<ALIAS>` — the URL is set from config; you must provide the theme token per store. `<ALIAS>` is uppercase with hyphens as underscores (e.g. `voldt-norway` → `SHOPIFY_STORE_URL_VOLDT_NORWAY`).
235
+ **Multi-store:** Per-store secrets `SHOPIFY_STORE_URL_<ALIAS>` and `SHOPIFY_THEME_ACCESS_TOKEN_<ALIAS>` — the URL is set from config; you must provide the theme token per store. `<ALIAS>` is uppercase with hyphens as underscores (e.g. `voldt-norway` → `SHOPIFY_STORE_URL_VOLDT_NORWAY`). Preview and cleanup workflows use the **default store** (from `config.default_store` or first store in `config.stores`), so set either the plain `SHOPIFY_*` secrets or the `_<ALIAS>` pair for that default store.
236
236
 
237
237
  ## Directory Structure (Multi-store)
238
238
 
package/bin/version.txt CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 1.5.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "climaybe",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Shopify CI/CD CLI — scaffolds workflows, branch strategy, and store config for single-store and multi-store theme repos",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,6 +24,7 @@ jobs:
24
24
  - uses: actions/checkout@v4
25
25
  with:
26
26
  token: ${{ secrets.GITHUB_TOKEN }}
27
+ fetch-depth: 2
27
28
 
28
29
  - name: Skip if this is a sync commit
29
30
  id: gate
@@ -41,6 +42,29 @@ jobs:
41
42
  echo "skip=false" >> $GITHUB_OUTPUT
42
43
  fi
43
44
 
45
+ - name: Keep store-specific paths (e.g. locales) after main sync
46
+ if: steps.gate.outputs.skip != 'true'
47
+ run: |
48
+ # After a main→staging merge, restore store-specific paths from the pre-merge commit
49
+ # so they are not overwritten by main. Only run when paths exist (no pathspec error).
50
+ if [ ! -d "locales" ]; then
51
+ echo "No locales/ directory, skipping."
52
+ exit 0
53
+ fi
54
+ PARENT=$(git rev-parse HEAD^1 2>/dev/null || echo "")
55
+ if [ -z "$PARENT" ]; then
56
+ echo "Not a merge commit or shallow clone, skipping."
57
+ exit 0
58
+ fi
59
+ find locales -name "*.json" 2>/dev/null | while read -r f; do
60
+ git checkout "$PARENT" -- "$f" 2>/dev/null || true
61
+ done
62
+ if git diff --quiet; then
63
+ echo "No store-specific locale changes to restore."
64
+ else
65
+ echo "Restored store-specific locale files from pre-merge commit."
66
+ fi
67
+
44
68
  - name: Extract store alias from branch name
45
69
  if: steps.gate.outputs.skip != 'true'
46
70
  id: alias
@@ -12,12 +12,66 @@ jobs:
12
12
  extract-pr-number:
13
13
  uses: ./.github/workflows/reusable-extract-pr-number.yml
14
14
 
15
+ resolve-store:
16
+ runs-on: ubuntu-latest
17
+ outputs:
18
+ store_alias_secret: ${{ steps.resolve.outputs.alias_secret }}
19
+ steps:
20
+ - name: Checkout code
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Resolve default store alias
24
+ id: resolve
25
+ run: |
26
+ ALIAS=$(node -e "
27
+ const fs = require('fs');
28
+ const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
29
+ const stores = pkg?.config?.stores || {};
30
+ const defaultStoreRaw = pkg?.config?.default_store;
31
+ const normalize = (v) => String(v || '')
32
+ .toLowerCase()
33
+ .replace(/^https?:\\/\\//, '')
34
+ .replace(/\\/.*$/, '');
35
+ const defaultStore = normalize(defaultStoreRaw);
36
+ let alias = '';
37
+ if (defaultStore) {
38
+ for (const [k, d] of Object.entries(stores)) {
39
+ if (normalize(d) === defaultStore) {
40
+ alias = k;
41
+ break;
42
+ }
43
+ }
44
+ }
45
+ if (!alias) {
46
+ alias = Object.keys(stores)[0] || '';
47
+ }
48
+ if (!alias && defaultStore) {
49
+ const subdomain = defaultStore.split('.')[0] || 'default';
50
+ alias = subdomain.replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-') || 'default';
51
+ }
52
+ if (!alias) {
53
+ alias = 'default';
54
+ }
55
+ process.stdout.write(alias);
56
+ ")
57
+
58
+ if [ -z "$ALIAS" ]; then
59
+ echo "Could not resolve default store alias from package.json config."
60
+ exit 1
61
+ fi
62
+
63
+ ALIAS_SECRET=$(echo "$ALIAS" | tr '[:lower:]-' '[:upper:]_')
64
+ echo "alias=$ALIAS" >> $GITHUB_OUTPUT
65
+ echo "alias_secret=$ALIAS_SECRET" >> $GITHUB_OUTPUT
66
+
15
67
  cleanup-theme:
16
- needs: extract-pr-number
68
+ needs: [extract-pr-number, resolve-store]
17
69
  uses: ./.github/workflows/reusable-cleanup-themes.yml
18
70
  with:
19
71
  pr_number: ${{ needs.extract-pr-number.outputs.pr_number }}
20
- secrets: inherit
72
+ secrets:
73
+ SHOPIFY_STORE_URL: ${{ secrets[format('SHOPIFY_STORE_URL_{0}', needs.resolve-store.outputs.store_alias_secret)] || secrets.SHOPIFY_STORE_URL }}
74
+ SHOPIFY_THEME_ACCESS_TOKEN: ${{ secrets[format('SHOPIFY_THEME_ACCESS_TOKEN_{0}', needs.resolve-store.outputs.store_alias_secret)] || secrets.SHOPIFY_THEME_ACCESS_TOKEN }}
21
75
 
22
76
  comment-on-pr:
23
77
  needs: cleanup-theme
@@ -87,11 +87,13 @@ jobs:
87
87
  echo "Shopify credentials are configured for alias: ${{ steps.resolve.outputs.alias }}"
88
88
 
89
89
  cleanup-themes:
90
- needs: extract-pr-number
90
+ needs: [extract-pr-number, validate-environment]
91
91
  uses: ./.github/workflows/reusable-cleanup-themes.yml
92
92
  with:
93
93
  pr_number: ${{ needs.extract-pr-number.outputs.pr_number }}
94
- secrets: inherit
94
+ secrets:
95
+ SHOPIFY_STORE_URL: ${{ secrets[format('SHOPIFY_STORE_URL_{0}', needs.validate-environment.outputs.store_alias_secret)] || secrets.SHOPIFY_STORE_URL }}
96
+ SHOPIFY_THEME_ACCESS_TOKEN: ${{ secrets[format('SHOPIFY_THEME_ACCESS_TOKEN_{0}', needs.validate-environment.outputs.store_alias_secret)] || secrets.SHOPIFY_THEME_ACCESS_TOKEN }}
95
97
 
96
98
  share-theme:
97
99
  needs: [validate-environment, extract-pr-number, cleanup-themes]
@@ -33,8 +33,11 @@ jobs:
33
33
  PR_NUMBER: ${{ inputs.pr_number }}
34
34
  run: |
35
35
  if [ -z "$SHOPIFY_STORE_URL" ] || [ -z "$SHOPIFY_THEME_ACCESS_TOKEN" ]; then
36
- echo "Missing Shopify secrets."
37
- exit 1
36
+ echo "Missing Shopify secrets; skipping theme cleanup (no themes deleted)."
37
+ echo "deleted_count=0" >> $GITHUB_OUTPUT
38
+ echo "deleted_themes<<DELETED_EOF" >> $GITHUB_OUTPUT
39
+ echo "DELETED_EOF" >> $GITHUB_OUTPUT
40
+ exit 0
38
41
  fi
39
42
 
40
43
  THEME_LIST=$(shopify theme list \