climaybe 1.6.0 → 1.6.2

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
@@ -185,7 +185,7 @@ Direct pushes to `staging-<store>` or `live-<store>` are automatically synced ba
185
185
 
186
186
  | Workflow | Trigger | What it does |
187
187
  |----------|---------|-------------|
188
- | `main-to-staging-stores.yml` (main-to-staging-&lt;store&gt;) | Push to `main` | Merges main into each `staging-<alias>`; root JSONs ignored (restored from stores/). Skips on hotfix/version/sync commits |
188
+ | `main-to-staging-stores.yml` (main-to-staging-&lt;store&gt;) | Push to `main` | Merges main into each `staging-<alias>`; root JSONs ignored. For hotfix-backport, skips the store that sent the hotfix; other stores get the merge. Skips only on pure store-sync. |
189
189
  | `stores-to-root.yml` | Push to `staging-*` | From main merge: stores→root. From elsewhere (e.g. Shopify): root→stores |
190
190
  | `pr-to-live.yml` | After stores-to-root | Opens PR from `staging-<alias>` to `live-<alias>` |
191
191
  | `root-to-stores.yml` | Push to `live-*` | From main merge: stores→root. From elsewhere: root→stores (same as stores-to-root on staging-*) |
@@ -221,7 +221,8 @@ Enabled via `climaybe init` prompt (`Enable build + Lighthouse workflows?`).
221
221
  - **No tags yet?** The system uses `theme_version` from `config/settings_schema.json` (`theme_info`), creates that tag on main (e.g. `v1.0.0`), and continues from there.
222
222
  - **Staging → main**: On PR, a pre-release patch tag (e.g. v3.1.13) locks the current minor line; on merge, **minor** bump (e.g. v3.1.13 → v3.2.0).
223
223
  - **Non-staging to main** (hotfix backports, direct commits): **Patch** bump only, via **nightly workflow** at 02:00 US Eastern (not at commit time).
224
- - All version bumps update `config/settings_schema.json` automatically.
224
+ - **Version bump runs only on main** (post-merge-tag and nightly-hotfix). Main-to-staging-stores merges main into each `staging-<alias>` on every push (version bumps and hotfixes). When the push is a hotfix from one store (e.g. live-norway), that store’s staging branch is skipped; other stores’ staging branches still get the merge.
225
+ - Version bumps update `config/settings_schema.json` and, when present, `package.json` `version`.
225
226
 
226
227
  **Full specification:** For detailed versioning rules, local dev flow, hotfix behavior, and alignment with the external CI/CD doc, see **[CI/CD Reference](docs/CI_CD_REFERENCE.md)**.
227
228
 
package/bin/version.txt CHANGED
@@ -1 +1 @@
1
- 1.6.0
1
+ 1.6.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "climaybe",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
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": {
@@ -39,7 +39,22 @@
39
39
  "main"
40
40
  ],
41
41
  "plugins": [
42
- "@semantic-release/commit-analyzer",
42
+ [
43
+ "@semantic-release/commit-analyzer",
44
+ {
45
+ "preset": "conventionalcommits",
46
+ "releaseRules": [
47
+ {
48
+ "type": "ci",
49
+ "release": "patch"
50
+ },
51
+ {
52
+ "type": "chore",
53
+ "release": "patch"
54
+ }
55
+ ]
56
+ }
57
+ ],
43
58
  "@semantic-release/release-notes-generator",
44
59
  [
45
60
  "@semantic-release/npm",
@@ -54,7 +69,7 @@
54
69
  "package.json",
55
70
  "package-lock.json"
56
71
  ],
57
- "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
72
+ "message": "chore(release): ${nextRelease.version}\n\n${nextRelease.notes}"
58
73
  }
59
74
  ]
60
75
  ]
@@ -2,13 +2,22 @@
2
2
  # When main is pushed (e.g. after staging→main merge), syncs main to each staging-<alias>.
3
3
  # Root JSON files (config/settings_data.json, templates/*.json, sections/*.json) are ignored:
4
4
  # merge brings main in but we immediately restore root from stores/<alias>/ so store-specific data is kept.
5
- # Skips [hotfix-backport], version-bump, and store-sync commits so hotfix syncs do not re-trigger release to stores.
5
+ # Runs on every push to main except pure store-sync commits ([stores-to-root], [root-to-stores]), so that:
6
+ # - Version-bump commits: staging-<alias> get the new version.
7
+ # - Hotfix backports (live or staging-<alias> → main): other staging-<alias> get those changes; the store that sent the hotfix is skipped (no need to merge back to the same branch).
8
+ #
9
+ # Also runs when Post-Merge Tag or Nightly Hotfix Tag complete: version-bump pushes with GITHUB_TOKEN,
10
+ # which does not trigger push-based workflows, so we explicitly run sync after those workflows finish.
6
11
 
7
12
  name: Main to Staging Stores
8
13
 
9
14
  on:
10
15
  push:
11
16
  branches: [main]
17
+ workflow_run:
18
+ workflows: ['Post-Merge Tag', 'Nightly Hotfix Tag']
19
+ types: [completed]
20
+ branches: [main]
12
21
 
13
22
  # Prevent concurrent store pushes
14
23
  concurrency:
@@ -16,30 +25,48 @@ concurrency:
16
25
  cancel-in-progress: false
17
26
 
18
27
  jobs:
19
- # Gate: skip hotfix backports and version bump commits
28
+ # Gate: skip only pure store-sync commits. When hotfix-backport, extract source branch alias so we skip merging back into that same store.
29
+ # When triggered by workflow_run (version-bump finished), run sync if the workflow succeeded.
20
30
  gate:
21
31
  runs-on: ubuntu-latest
32
+ # workflow_run: only sync when Post-Merge or Nightly Hotfix completed successfully (version-bump pushed)
33
+ if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
22
34
  outputs:
23
35
  should_run: ${{ steps.check.outputs.should_run }}
36
+ hotfix_source_alias: ${{ steps.check.outputs.hotfix_source_alias }}
24
37
  steps:
25
- - name: Check commit message
38
+ - name: Check commit message and hotfix source
26
39
  id: check
27
40
  run: |
41
+ if [ "${{ github.event_name }}" = "workflow_run" ]; then
42
+ echo "Triggered by workflow_run (version-bump finished); syncing main to staging."
43
+ echo "should_run=true" >> $GITHUB_OUTPUT
44
+ echo "hotfix_source_alias=" >> $GITHUB_OUTPUT
45
+ exit 0
46
+ fi
47
+
28
48
  COMMIT_MSG="${{ github.event.head_commit.message }}"
29
49
 
30
- if echo "$COMMIT_MSG" | grep -q "\[hotfix-backport\]"; then
31
- echo "Skipping — hotfix backport commit (do not re-release to stores)"
32
- echo "should_run=false" >> $GITHUB_OUTPUT
33
- elif echo "$COMMIT_MSG" | grep -q "chore(release): bump version"; then
34
- echo "Skipping — version bump commit"
50
+ if echo "$COMMIT_MSG" | grep -qE "\[skip-store-sync\]|\[stores-to-root\]|\[root-to-stores\]"; then
51
+ echo "Skipping — store sync commit (avoid loop)"
35
52
  echo "should_run=false" >> $GITHUB_OUTPUT
36
- elif echo "$COMMIT_MSG" | grep -qE "\[skip-store-sync\]|\[stores-to-root\]|\[root-to-stores\]"; then
37
- echo "Skipping — store sync commit"
38
- echo "should_run=false" >> $GITHUB_OUTPUT
39
- else
40
- echo "should_run=true" >> $GITHUB_OUTPUT
53
+ echo "hotfix_source_alias=" >> $GITHUB_OUTPUT
54
+ exit 0
41
55
  fi
42
56
 
57
+ echo "should_run=true" >> $GITHUB_OUTPUT
58
+
59
+ # If hotfix-backport, extract source branch alias (e.g. staging-norway or live-norway → norway) so we skip that store in sync
60
+ HOTFIX_SOURCE_ALIAS=""
61
+ if echo "$COMMIT_MSG" | grep -q "\[hotfix-backport\]"; then
62
+ SOURCE_BRANCH=$(echo "$COMMIT_MSG" | sed -n 's/.*Merge \([^ ]*\) into main.*/\1/p' | head -1)
63
+ if [ -n "$SOURCE_BRANCH" ]; then
64
+ HOTFIX_SOURCE_ALIAS="${SOURCE_BRANCH#staging-}"
65
+ HOTFIX_SOURCE_ALIAS="${HOTFIX_SOURCE_ALIAS#live-}"
66
+ fi
67
+ fi
68
+ echo "hotfix_source_alias=$HOTFIX_SOURCE_ALIAS" >> $GITHUB_OUTPUT
69
+
43
70
  # Read store list from package.json
44
71
  config:
45
72
  needs: gate
@@ -61,7 +88,7 @@ jobs:
61
88
  echo "stores=$STORES" >> $GITHUB_OUTPUT
62
89
  echo "Store aliases: $STORES"
63
90
 
64
- # Merge main into each staging-<alias>; root JSONs ignored (restored from stores/<alias>/)
91
+ # Merge main into each staging-<alias>; root JSONs ignored (restored from stores/<alias>/). Skip the store that sent the hotfix (no need to merge back).
65
92
  sync:
66
93
  needs: [gate, config]
67
94
  if: needs.gate.outputs.should_run == 'true'
@@ -76,6 +103,7 @@ jobs:
76
103
  actions: write
77
104
  env:
78
105
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106
+ HOTFIX_SOURCE_ALIAS: ${{ needs.gate.outputs.hotfix_source_alias }}
79
107
  steps:
80
108
  - uses: actions/checkout@v4
81
109
  with:
@@ -83,10 +111,16 @@ jobs:
83
111
 
84
112
  - name: Sync main to staging-${{ matrix.store }} (root JSONs ignored)
85
113
  run: |
114
+ git fetch origin main
86
115
  BRANCH="staging-${{ matrix.store }}"
87
116
  ALIAS="${{ matrix.store }}"
88
117
  STORE_DIR="stores/${ALIAS}"
89
118
 
119
+ if [ -n "$HOTFIX_SOURCE_ALIAS" ] && [ "$HOTFIX_SOURCE_ALIAS" = "$ALIAS" ]; then
120
+ echo "Hotfix came from staging-$ALIAS or live-$ALIAS, skipping (no need to merge back to same store)."
121
+ exit 0
122
+ fi
123
+
90
124
  if ! git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then
91
125
  echo "Branch $BRANCH does not exist on remote, skipping."
92
126
  exit 0
@@ -1,5 +1,6 @@
1
1
  # climaybe — Version Bump (Reusable Workflow)
2
- # Bumps version in settings_schema.json, creates a git tag, and pushes.
2
+ # Bumps version in settings_schema.json and package.json (if present), creates a git tag, and pushes.
3
+ # Only runs on main (called from post-merge-tag and nightly-hotfix). staging / staging-* / live-* do not run version bump.
3
4
 
4
5
  name: Version Bump
5
6
 
@@ -99,20 +100,20 @@ jobs:
99
100
  echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
100
101
  echo "New version: $NEW_VERSION"
101
102
 
102
- - name: Update settings_schema.json
103
+ - name: Update settings_schema.json and package.json
104
+ env:
105
+ NEW_VERSION: ${{ steps.bump.outputs.new_version }}
103
106
  run: |
104
- NEW_VERSION="${{ steps.bump.outputs.new_version }}"
107
+ export VERSION_PLAIN="${NEW_VERSION#v}"
105
108
  SCHEMA_FILE="config/settings_schema.json"
106
109
 
107
110
  if [ -f "$SCHEMA_FILE" ]; then
108
- # Update the theme_info version in settings_schema.json
109
111
  node -e "
110
112
  const fs = require('fs');
113
+ const v = process.env.VERSION_PLAIN;
111
114
  const schema = JSON.parse(fs.readFileSync('$SCHEMA_FILE', 'utf-8'));
112
115
  const themeInfo = schema.find(s => s.name === 'theme_info');
113
- if (themeInfo) {
114
- themeInfo.theme_version = '${NEW_VERSION#v}';
115
- }
116
+ if (themeInfo) themeInfo.theme_version = v;
116
117
  fs.writeFileSync('$SCHEMA_FILE', JSON.stringify(schema, null, 2) + '\n');
117
118
  "
118
119
  echo "Updated $SCHEMA_FILE to ${NEW_VERSION}"
@@ -120,6 +121,18 @@ jobs:
120
121
  echo "No $SCHEMA_FILE found, skipping schema update."
121
122
  fi
122
123
 
124
+ if [ -f "package.json" ]; then
125
+ node -e "
126
+ const fs = require('fs');
127
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
128
+ pkg.version = process.env.VERSION_PLAIN;
129
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
130
+ "
131
+ echo "Updated package.json version to ${VERSION_PLAIN}"
132
+ else
133
+ echo "No package.json found, skipping."
134
+ fi
135
+
123
136
  - name: Commit and tag
124
137
  run: |
125
138
  NEW_VERSION="${{ steps.bump.outputs.new_version }}"