Skip to content

Commit 3048ec2

Browse files
committed
Merge remote-tracking branch 'origin/canary' into sync-integrations-makeswift
# Conflicts: # core/CHANGELOG.md # pnpm-lock.yaml
2 parents 9dff9d8 + bfafc56 commit 3048ec2

17 files changed

Lines changed: 846 additions & 562 deletions

File tree

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
---
2+
name: release-catalyst-patch
3+
description: >
4+
Release a single Catalyst package patch in isolation, without bundling it with
5+
other queued changesets in the open Version Packages PR. Use when the user says
6+
"/release-catalyst-patch", "isolate a patch release", "publish only one package",
7+
or wants to ship a single package's changeset ahead of the normal release cadence.
8+
Performs the full flow locally (`changeset version`, build, `changeset publish`,
9+
push, GitHub release) so the remaining queued changesets stay untouched in the
10+
Version Packages PR.
11+
---
12+
13+
# Release Catalyst Patch (single-package isolation)
14+
15+
The Changesets GitHub Action picks one mode per push to `canary`: if any unconsumed
16+
changesets exist, it opens/refreshes the Version Packages PR and **does not** publish.
17+
That's why we publish locally — we keep the other changesets in `.changeset/` so the
18+
Version Packages PR still tracks them, but we ship just the one we want now.
19+
20+
Execute stages in order. Pause for user input where indicated. **Never execute the
21+
`changeset publish` command yourself** — provide it to the user to run.
22+
23+
## Stage 0: Confirm scope
24+
25+
Identify the changeset to release and the target package + version.
26+
27+
```bash
28+
ls .changeset/
29+
git log --oneline -10 # find the PR/commit that added the changeset
30+
cat .changeset/<changeset-file>.md # confirm the package + bump type
31+
npm view <package> version dist-tags # confirm current published state
32+
```
33+
34+
Confirm with the user:
35+
- Which `.changeset/*.md` file is being released
36+
- The target package and the resulting version (e.g., `1.0.2``1.0.3`)
37+
- That **all other** changesets in `.changeset/` should remain queued for the next regular release
38+
39+
If the package has notes in the [Package-specific notes](#package-specific-notes) section
40+
below, review them before continuing.
41+
42+
## Stage 1: Branch + quarantine
43+
44+
Work on a release branch so the workflow doesn't trigger mid-flow.
45+
46+
```bash
47+
git switch canary && git pull
48+
git switch -c release/<package>-<new-version>
49+
```
50+
51+
Move the **other** changesets **outside** the repo. A subdirectory inside `.changeset/`
52+
gets parsed as a malformed changeset by the CLI and crashes `changeset version`:
53+
54+
```bash
55+
mkdir -p /tmp/changeset-hold
56+
mv .changeset/<other-1>.md .changeset/<other-2>.md ... /tmp/changeset-hold/
57+
ls .changeset/ # should leave only config.json + the one changeset to release
58+
```
59+
60+
## Stage 2: Run `changeset version`
61+
62+
Requires `GITHUB_TOKEN` because the repo uses `@changesets/changelog-github`. The `gh`
63+
CLI token works.
64+
65+
```bash
66+
pnpm install --frozen-lockfile
67+
GITHUB_TOKEN=$(gh auth token) pnpm changeset version
68+
```
69+
70+
Restore the held changesets immediately:
71+
72+
```bash
73+
mv /tmp/changeset-hold/*.md .changeset/
74+
rmdir /tmp/changeset-hold
75+
```
76+
77+
Verify the diff:
78+
79+
```bash
80+
git status
81+
git diff packages/<package>/package.json packages/<package>/CHANGELOG.md
82+
```
83+
84+
Expect: bumped `package.json`, new CHANGELOG entry, deleted only the one changeset.
85+
The other changesets should be back in `.changeset/` and untouched.
86+
87+
## Stage 3: Build
88+
89+
Run the root build. Turborepo handles env passthrough from `.env.local` via the
90+
pipeline config, so package builds get the variables they need without manual sourcing.
91+
92+
```bash
93+
pnpm build
94+
```
95+
96+
If a package has build-time secrets that must be present, see the
97+
[Package-specific notes](#package-specific-notes) section for verification steps.
98+
99+
## Stage 4: Commit
100+
101+
```bash
102+
git add -A
103+
git commit -m "Version Packages (\`canary\`)"
104+
```
105+
106+
Match the message format the changesets bot uses, since this is a manual stand-in for it.
107+
108+
## Stage 5: Hand the publish command to the user
109+
110+
**Do not run `changeset publish` from the agent.** Publishing to npm is a destructive,
111+
externally-visible action that should be performed by the user.
112+
113+
Have the user confirm they're logged in, then run the publish themselves. The CLI will
114+
prompt them interactively for the npm OTP.
115+
116+
```bash
117+
npm whoami # expect their npm username
118+
pnpm exec changeset publish # prompts for OTP interactively
119+
```
120+
121+
`changeset publish` is per-package version-aware: it only publishes packages whose local
122+
`package.json` is ahead of npm. Since only one package was bumped, only it ships. It
123+
also creates a local git tag like `@bigcommerce/<package>@<version>`.
124+
125+
Wait for the user to confirm the publish completed before continuing.
126+
127+
## Stage 6: Verify npm state
128+
129+
```bash
130+
npm view <package> version
131+
npm view <package> dist-tags
132+
```
133+
134+
`latest` should point to the new version. If it doesn't (rare — only happens if
135+
`publishConfig.tag` is set), advise the user to fix with:
136+
137+
```bash
138+
npm dist-tag add <package>@<version> latest
139+
```
140+
141+
## Stage 7: Fast-forward canary and push
142+
143+
This requires a direct push to the protected default branch. **Pause and ask for explicit
144+
user authorization** before pushing — the user's "never push directly to main/master/production"
145+
rule guards against this even though the changesets bot does the same thing during normal
146+
releases.
147+
148+
```bash
149+
git switch canary
150+
git fetch origin canary
151+
git log --oneline origin/canary..canary # should be 1 ahead
152+
git log --oneline canary..origin/canary # should be 0 behind
153+
git merge --ff-only release/<package>-<new-version>
154+
```
155+
156+
If you're 1 ahead and 0 behind, default `git push` rejects non-fast-forward updates,
157+
which gives the same safety as `--ff-only` on the push side. Apple's git build (≤2.50.x)
158+
does not accept `--ff-only` as a push flag — `git push origin canary` is correct here.
159+
160+
If a hook blocks the agent push, hand these commands to the user:
161+
162+
```bash
163+
git push origin canary
164+
git push origin "@bigcommerce/<package>@<new-version>"
165+
```
166+
167+
## Stage 8: Create the GitHub release manually
168+
169+
CI runs `changeset publish` after the canary push, finds the version already on npm,
170+
and no-ops. Because the action only creates GitHub releases for packages it actually
171+
publishes, **no release is created automatically** in this flow. Make it manually.
172+
173+
Extract the new CHANGELOG section (everything after the `## <version>` heading up to
174+
the next `## ` heading) into a notes file. Then:
175+
176+
```bash
177+
gh release create "@bigcommerce/<package>@<new-version>" \
178+
--repo bigcommerce/catalyst \
179+
--title "@bigcommerce/<package>@<new-version>" \
180+
--notes-file /tmp/release-notes.md
181+
```
182+
183+
Match the body format of prior releases — just the `### Patch Changes` /
184+
`### Minor Changes` heading and the bullets, no version heading at the top. Compare
185+
against an existing release:
186+
187+
```bash
188+
gh release view "@bigcommerce/catalyst-core@<some-prior-version>" --repo bigcommerce/catalyst --json body
189+
```
190+
191+
## Stage 9: Final validation
192+
193+
```bash
194+
git fetch origin canary
195+
git log --oneline origin/canary -3 # version commit on canary
196+
git ls-remote --tags origin "@bigcommerce/<package>@<new-version>" # tag on origin
197+
gh release view "@bigcommerce/<package>@<new-version>" --repo bigcommerce/catalyst --json tagName,isDraft,isPrerelease
198+
gh run list --workflow=changesets-release.yml --limit 1 # CI run succeeded
199+
gh pr list --search "Version Packages (canary)" --state open --json number,headRefName,updatedAt # Version Packages PR refreshed
200+
git fetch origin changeset-release/canary
201+
git show --stat origin/changeset-release/canary | head -20 # confirm only the other changesets remain
202+
npm view <package> version dist-tags
203+
```
204+
205+
Report:
206+
- Published version + dist-tag
207+
- Canary commit SHA
208+
- Tag pushed
209+
- GitHub release URL
210+
- Confirmation that the Version Packages PR now contains **only** the other changesets — the released one has been dropped from its scope.
211+
212+
## Stage 10: Cleanup
213+
214+
```bash
215+
git branch -d release/<package>-<new-version>
216+
```
217+
218+
## Package-specific notes
219+
220+
### `@bigcommerce/create-catalyst`
221+
222+
The CLI build (`tsup` via the package's `tsup.config.ts`) inlines `CLI_SEGMENT_WRITE_KEY`
223+
at build time, falling back to the placeholder `'not-a-valid-segment-write-key'` if the
224+
env var is missing. After Stage 3, verify the real key was embedded:
225+
226+
```bash
227+
grep -c "not-a-valid-segment-write-key" packages/create-catalyst/dist/index.js
228+
# expect: 0
229+
```
230+
231+
If `1`, the env var wasn't loaded. Confirm `CLI_SEGMENT_WRITE_KEY` exists in `.env.local`,
232+
and that the turbo pipeline for `build` declares it under `env` or `passThroughEnv` in
233+
`turbo.json`. Re-run `pnpm build` after fixing.

.github/workflows/native-hosting.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
run: pnpm install --frozen-lockfile
2727

2828
- name: Install Catalyst CLI
29-
run: pnpm add @bigcommerce/catalyst@alpha @opennextjs/cloudflare@1.17.3
29+
run: pnpm add @bigcommerce/catalyst@alpha @opennextjs/cloudflare@latest
3030
working-directory: core
3131

3232
- name: Convert proxy.ts to middleware.ts

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
**Catalyst** is the composable, fully customizable headless commerce framework for
1919
[BigCommerce](https://www.bigcommerce.com/). Catalyst is built with [Next.js](https://nextjs.org/), uses
2020
our [React](https://react.dev/) storefront components, and is backed by the
21-
[GraphQL Storefront API](https://developer.bigcommerce.com/docs/storefront/graphql).
21+
[GraphQL Storefront API](https://docs.bigcommerce.com/developer/docs/storefront/guides/graphql-storefront-api/overview).
2222

2323
By choosing Catalyst, you'll have a fully-functional storefront within a few seconds, and spend zero time on wiring
2424
up APIs or building SEO, Accessibility, and Performance-optimized ecommerce components you've probably written many
@@ -32,9 +32,9 @@ times before. You can instead go straight to work building your brand and making
3232

3333
<p align="center">
3434
<a href="https://www.catalyst.dev">🚀 catalyst.dev</a> •
35-
<a href="https://developer.bigcommerce.com/community">🤗 BigCommerce Developer Community</a> •
35+
<a href="https://docs.bigcommerce.com/developer/community/connect">🤗 BigCommerce Developer Community</a> •
3636
<a href="https://github.com/bigcommerce/catalyst/discussions">💬 GitHub Discussions</a> •
37-
<a href="/docs">💡 Docs in this repo</a>
37+
<a href="https://docs.bigcommerce.com/developer/docs/storefront/catalyst/overview">💡 Documentation</a>
3838
</p>
3939

4040
![-----------------------------------------------------](https://storage.googleapis.com/bigcommerce-developers/images/catalyst_readme_hr.png)
@@ -43,7 +43,7 @@ times before. You can instead go straight to work building your brand and making
4343

4444
The easiest way to deploy your Catalyst Storefront is to use the [One-Click Catalyst App](https://login.bigcommerce.com/deep-links/app/53284) available in the BigCommerce App Marketplace.
4545

46-
Check out the [Catalyst.dev One-Click Catalyst Documentation](https://www.catalyst.dev/docs/getting-started) for more details.
46+
Check out the [Commerce One-Click Catalyst Documentation](https://docs.bigcommerce.com/developer/docs/storefront/catalyst/getting-started/workflows/one-click-catalyst) for more details.
4747

4848
## Getting Started
4949

@@ -73,7 +73,6 @@ Learn more about Catalyst at [catalyst.dev](https://catalyst.dev).
7373

7474
## Resources
7575

76-
- [Catalyst Documentation](https://catalyst.dev/docs/)
77-
- [GraphQL Storefront API Playground](https://developer.bigcommerce.com/graphql-storefront/playground)
78-
- [GraphQL Storefront API Explorer](https://developer.bigcommerce.com/graphql-storefront/explorer)
79-
- [BigCommerce DevDocs](https://developer.bigcommerce.com/docs/build)
76+
- [Catalyst Documentation](https://docs.bigcommerce.com/developer/docs/storefront/catalyst/overview)
77+
- [GraphQL Storefront API Playground](https://docs.bigcommerce.com/developer/docs/storefront/guides/graphql-storefront-api/overview#accessing-the-graphql-storefront-playground)
78+
- [BigCommerce DevDocs](https://docs.bigcommerce.com/developer/docs/overview/quick-start)

core/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- [#2952](https://github.com/bigcommerce/catalyst/pull/2952) [`66d2a7d`](https://github.com/bigcommerce/catalyst/commit/66d2a7dfab653762da4986b55a7c92fa4ab9b6c6) Thanks [@jorgemoya](https://github.com/jorgemoya)! - Upgrade `@makeswift/runtime` from `0.26.3` to `0.26.4`.
88

9+
- [#3007](https://github.com/bigcommerce/catalyst/pull/3007) [`13b3c2e`](https://github.com/bigcommerce/catalyst/commit/13b3c2e5c85bf47a07e999315a8f12988ab96d3f) Thanks [@chanceaclark](https://github.com/chanceaclark)! - Bump Next.js and React to address security vulnerabilities
10+
- `next`: ~16.1.6 → ~16.2.6 — fixes middleware bypass, SSRF, XSS, and cache poisoning CVEs
11+
- `react` / `react-dom`: 19.1.5 → 19.1.7 — fixes GHSA-rv78-f8rc-xrxh (DoS via OOM/CPU exhaustion on server function endpoints)
12+
913
## 1.6.2
1014

1115
### Patch Changes

core/app/[locale]/(default)/cart/page-data.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export const PhysicalItemFragment = graphql(`
2828
currencyCode
2929
value
3030
}
31+
discountedAmount {
32+
currencyCode
33+
value
34+
}
3135
selectedOptions {
3236
__typename
3337
entityId
@@ -87,6 +91,10 @@ export const DigitalItemFragment = graphql(`
8791
currencyCode
8892
value
8993
}
94+
discountedAmount {
95+
currencyCode
96+
value
97+
}
9098
selectedOptions {
9199
__typename
92100
entityId

core/app/[locale]/(default)/cart/page.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ export default async function Cart({ params }: Props) {
217217
const totalCouponDiscount =
218218
checkout?.coupons.reduce((sum, coupon) => sum + coupon.discountedAmount.value, 0) ?? 0;
219219

220+
const totalLineItemDiscount = [
221+
...cart.lineItems.physicalItems,
222+
...cart.lineItems.digitalItems,
223+
].reduce((sum, item) => sum + item.discountedAmount.value, 0);
224+
225+
const totalDiscount = cart.discountedAmount.value + totalLineItemDiscount;
226+
220227
const giftCertificatesSummary =
221228
checkout?.giftCertificates.reduce<Array<{ code: string; used: number }>>((acc, c) => {
222229
acc.push({
@@ -283,10 +290,10 @@ export default async function Cart({ params }: Props) {
283290
currency: cart.currencyCode,
284291
}),
285292
},
286-
cart.discountedAmount.value > 0
293+
totalDiscount > 0
287294
? {
288295
label: t('CheckoutSummary.discounts'),
289-
value: `-${format.number(cart.discountedAmount.value, {
296+
value: `-${format.number(totalDiscount, {
290297
style: 'currency',
291298
currency: cart.currencyCode,
292299
})}`,

core/app/[locale]/(default)/compare/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export default async function Compare(props: Props) {
129129
previousLabel={t('previous')}
130130
products={streamableProducts}
131131
ratingLabel={t('rating')}
132+
showLessLabel={t('showLess')}
133+
showMoreLabel={t('showMore')}
132134
title={t('title')}
133135
viewOptionsLabel={t('viewOptions')}
134136
/>

core/messages/da.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@
642642
},
643643
"Footer": {
644644
"home": "Hjem",
645-
"contactUs": "kontakte os",
645+
"contactUs": "Kontakt os",
646646
"socialMediaLinks": "Links til sociale medier",
647647
"categories": "Kategorier",
648648
"brands": "mærker",

core/messages/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@
500500
"otherDetails": "Other details",
501501
"noOtherDetails": "There are no other details.",
502502
"viewOptions": "View options",
503+
"showMore": "Show more",
504+
"showLess": "Show less",
503505
"successMessage": "{cartItems, plural, =1 {1 item} other {# items}} added to <cartLink> your cart</cartLink>",
504506
"missingCart": "Cart not found. Please try again later.",
505507
"unknownError": "Unknown error. Please try again later."

core/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@
6161
"lodash.debounce": "^4.0.8",
6262
"lru-cache": "^11.1.0",
6363
"lucide-react": "^0.474.0",
64-
"next": "~16.1.6",
64+
"next": "~16.2.6",
6565
"next-auth": "5.0.0-beta.30",
6666
"next-intl": "^4.6.1",
6767
"nuqs": "^2.4.3",
6868
"p-lazy": "^5.0.0",
69-
"react": "19.1.5",
69+
"react": "19.1.7",
7070
"react-day-picker": "^9.7.0",
71-
"react-dom": "19.1.5",
71+
"react-dom": "19.1.7",
7272
"react-google-recaptcha": "^3.1.0",
7373
"react-headroom": "^3.2.1",
7474
"schema-dts": "^1.1.5",

0 commit comments

Comments
 (0)