Skip to content

Commit b214224

Browse files
committed
Merge branch 'canary' into integrations/makeswift
1 parent 3fcf2c2 commit b214224

125 files changed

Lines changed: 5211 additions & 512 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,21 @@ Except for the additional code required to integrate with Makeswift, the `integr
2626

2727
In order to complete the following steps, you will need to have met the following prerequisites:
2828

29-
- You have a remote named `origin` pointing to the [`bigcommerce/catalyst` repository on GitHub](https://github.com/bigcommerce/catalyst). If you do not, you can add it with `git remote add origin ssh://git@github.com/bigcommerce/catalyst.git`, or if you are not using SSH, you can use `git remote add origin https://github.com/bigcommerce/catalyst.git`.
29+
- You have a remote named `origin` pointing to the [`bigcommerce/catalyst` repository on GitHub](https://github.com/bigcommerce/catalyst).
3030
- You have rights to push to the `integrations/makeswift` branch on GitHub.
3131

3232
#### Steps
3333

34-
To pull the latest code from `canary` into `integrations/makeswift`, follow the steps below:
35-
36-
1. Ensure your local `canary` branch is synchronized with the remote `canary` branch:
34+
1. Fetch latest from `origin`
3735

3836
```bash
3937
git fetch origin
40-
git checkout canary
41-
git reset --hard origin/canary
4238
```
4339

44-
2. Fetch the latest code from `integrations/makeswift`:
40+
2. Create a branch to perform a merge from `canary`
4541

4642
```bash
47-
git checkout -B integrations/makeswift origin/integrations/makeswift
43+
git checkout -B sync-integrations-makeswift origin/integrations/makeswift
4844
```
4945

5046
> [!TIP]
@@ -53,72 +49,70 @@ To pull the latest code from `canary` into `integrations/makeswift`, follow the
5349
> - If the local branch doesn't exist, it creates it from `origin/integrations/makeswift`
5450
> - If the local branch exists, it resets it to match `origin/integrations/makeswift`
5551
56-
3. Checkout a new branch from `integrations/makeswift`:
57-
58-
```bash
59-
git checkout -b {new-branch-name}
60-
```
61-
62-
4. Merge `canary` into `{new-branch-name}`, and resolve merge conflicts, if necessary:
52+
3. Merge `canary` and resolve merge conflicts, if necessary:
6353

6454
```bash
6555
git merge canary
6656
```
6757

6858
> [!WARNING]
69-
> There are a number of "gotchas" that you need to be aware of when merging `canary` into `integrations/makeswift`:
59+
> **Gotchas when merging canary into integrations/makeswift:**
7060
>
7161
> - The `name` field in `core/package.json` should remain `@bigcommerce/catalyst-makeswift`
7262
> - The `version` field in `core/package.json` should remain whatever the latest published `@bigcommerce/catalyst-makeswift` version was
73-
> - The `.changeset/` directory should not include any files that reference the `"@bigcommerce/catalyst-core"` package. If these files are merged into `integrations/makeswift`, they will cause the `Changesets Release` GitHub Action in `.github/workflows/changesets-release.yml` to fail with the error: `Error: Found changeset for package @bigcommerce/catalyst-core which is not in the workspace`
74-
>
75-
> _Note: A [GitHub Action is in place](.github/workflows/prevent-invalid-changesets.yml) to help prevent invalid changesets from being merged into `integrations/makeswift`. Do not merge your PR if this GitHub Action fails._
7663
77-
5. After resolving any merge conflicts, open a new PR in GitHub to merge your `{new-branch-name}` into `integrations/makeswift`. This PR should be code reviewed and approved before the next steps.
64+
4. After resolving any merge conflicts, open a new PR in GitHub to merge your `sync-integrations-makeswift` into `integrations/makeswift`. This PR should be code reviewed and approved before the next steps.
7865

79-
6. Once your PR is approved, the next step is to incorporate the merge commit from `{new-branch-name}` into `integrations/makeswift`. Do not use the merge button in the GitHub UI to merge your PR. Instead, you'll want to run the following command locally:
66+
5. Rebase `integrations/makeswift` to establish new merge base
8067

8168
```bash
82-
git checkout integrations/makeswift
83-
git rebase {new-branch-name}
69+
git checkout -B integrations/makeswift origin/integrations/makeswift
70+
git rebase sync-integrations-makeswift
8471
```
8572

86-
> [!IMPORTANT]
87-
> We have added a GitHub Ruleset to protect against this, but it's worth explicitly documenting here for posterity: It is very important that we do not "Squash and merge" or "Rebase and merge" our changes onto `integrations/makeswift`. Instead, we should either merge the PR with a traditional merge commit (the button in the GitHub PR UI should say "Merge pull request"), or locally rebase the `integrations/makeswift` branch onto the `{new-branch-name}` branch (as illustrated in the step above). Either of these options will correctly preserve the merge commit from step 4 in the history of the `integrations/makeswift` branch, which will then set the new merge base for future merges from `canary` into `integrations/makeswift`.
88-
>
89-
> If you are unsure whether or not you've done this correctly, you can run `git merge canary` from `integrations/makeswift` after rebasing in the step above; if you see "Already up to date.", you followed the steps correctly (with one caveat: in the case that new commits have been pushed to `canary` since the last time you merged, then you may see a new merge commit/potential conflicts for only those new commits).
90-
91-
7. Push the changes up to GitHub, which will automatically close the open PR from step 5.
73+
6. Push the changes up to GitHub:
9274

9375
```bash
9476
git push origin integrations/makeswift
9577
```
9678

97-
## Cutting new releases
79+
This should close the PR in GitHub automatically.
9880

99-
This repository uses [Changesets](https://github.com/changesets/changesets) to manage version bumps, changelogs, and publishing to the NPM registry. Whenever you create a pull request, you should think about whether the changes you are making warrant a version bump or a changelog entry.
81+
> [!IMPORTANT]
82+
> Do not squash or rebase-and-merge PRs into `integrations/makeswift`. Always use a true merge commit or rebase locally (as shown below). This is to preserve the merge commit and establish a new merge base between `canary` and `integrations/makeswift`.
10083
101-
If you are not sure, you can ask in the PR. Here are some examples:
84+
## Cutting New Releases
10285

103-
- If your pull request introduces changes to the root `README.md`: _Likely does not warrant a version bump or changelog entry, therefore your PR does not need to include a Changeset._
104-
- If your pull request introduces changes to `core/`, e.g., `core/app/`, or any of the packages in `packages/`: _Likely warrants a version bump and changelog entry, therefore your PR should include a Changeset._
86+
Catalyst uses [Changesets](https://github.com/changesets/changesets) to manage version bumps, changelogs, and publishing. Releases happen in **two stages**:
10587

106-
You can run the following command to create a new version bump and changelog entry:
88+
1. Cut a release from `canary`
89+
2. Sync that release into `integrations/makeswift` and cut again
10790

108-
```bash
109-
pnpm changeset
110-
```
91+
This ensures `integrations/makeswift` remains a faithful mirror of `canary` while including its additional integration code.
11192

112-
An interactive prompt will take you through the process of [adding your changeset](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).
93+
#### Stage 1: Cut a release from `canary`
11394

114-
Once you've completed the interactive prompt, you'll see a new file in the `.changeset/` directory. This file contains the version bump and changelog entry for your changes. You should commit this file to the branch associated with your PR.
95+
1. Begin the release process by merging the **Version Packages (`canary`)** PR. When `.changeset/` files exist on `canary`, a GitHub Action opens a **Version Packages (`canary`)** PR. This PR consolidates pending changesets, bumps versions, and updates changelogs. Merging this PR should publish new tags to GitHub, and optionally publish new package versions to NPM.
11596

116-
Once your PR is merged, our [GitHub Action](.github/workflows/changesets-release.yml) will handle the process of versioning and updating the changelog, (and in the case of `packages/`, publishing your changes to NPM). No further action is needed from you.
97+
#### Stage 2: Sync and Release `integrations/makeswift`
11798

118-
> [!WARNING]
119-
> It is very important that `.changeset/*.md` files targeting packages in `packages/` are not merged into the `integrations/makeswift` branch. While it is technically feasible to release packages from `integrations/makeswift`, we never want to do this. If we did this, we would need to sync the branches in the opposite direction, which was never intended to happen.
120-
>
121-
> _Note: A [GitHub Action is in place](.github/workflows/prevent-invalid-changesets.yml) to help prevent invalid changesets from being merged into `integrations/makeswift`. Do not merge your PR if this GitHub Action fails._
99+
2. Follow steps 1-6 under "[Keeping `integrations/makeswift` in sync with `canary`](#keeping-integrationsmakeswift-in-sync-with-canary)"
100+
101+
3. **IMPORTANT**: After step 6, you'll need to open another PR into `integrations/makeswift`
102+
- Ensure a local `integrations/makeswift` branch exists and is up to date (`git checkout -B integrations/makeswift origin/integrations/makeswift`)
103+
- Run `git fetch origin` and create a new branch from `integrations/makeswift` (`git checkout -B bump-version origin/integrations/makeswift`)
104+
- From this new `bump-version` branch, run `pnpm changeset`
105+
- Select `@bigcommerce/catalyst-makeswift`
106+
- For choosing between a `patch/minor/major` bump, you should copy the bump from Stage 1. (e.g., if `@bigcommerce/catalyst-core` went from `1.1.0` to `1.2.0`, choose `minor`)
107+
- Commit the generated changeset file and open a PR to merge this branch into `integrations/makeswift`
108+
- Once merged, you can proceed to the next step
109+
110+
4. Merge the **Version Packages (`integrations/makeswift`)** PR: Changesets will open another PR (similar to Stage 1) bumping `@bigcommerce/catalyst-makeswift`. Merge it following the same process. This cuts a new release of the Makeswift variant.
111+
112+
### Additional Notes
113+
114+
- **Tags and Releases:** Confirm tags exist for both `@bigcommerce/catalyst-core` and `@bigcommerce/catalyst-makeswift`. If needed, update `latest` tags in GitHub manually.
115+
- **Release cadence:** Teams typically review on Wednesdays whether to cut a release, but you may cut releases more frequently as needed.
122116

123117
## Other Ways to Contribute
124118

core/app/[locale]/(default)/account/orders/[id]/page-data.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { client } from '~/client';
66
import { graphql } from '~/client/graphql';
77
import { TAGS } from '~/client/tags';
88

9-
import { OrderItemFragment } from '../fragment';
9+
import { OrderGiftCertificateItemFragment, OrderItemFragment } from '../fragment';
1010

1111
const CustomerOrderDetails = graphql(
1212
`
@@ -109,12 +109,28 @@ const CustomerOrderDetails = graphql(
109109
}
110110
}
111111
}
112+
email {
113+
giftCertificates {
114+
edges {
115+
node {
116+
recipientEmail
117+
lineItems {
118+
edges {
119+
node {
120+
...OrderGiftCertificateItemFragment
121+
}
122+
}
123+
}
124+
}
125+
}
126+
}
127+
}
112128
}
113129
}
114130
}
115131
}
116132
`,
117-
[OrderItemFragment],
133+
[OrderItemFragment, OrderGiftCertificateItemFragment],
118134
);
119135

120136
export const getCustomerOrderDetails = cache(async (id: number) => {
@@ -150,6 +166,20 @@ export const getCustomerOrderDetails = cache(async (id: number) => {
150166
shipments: removeEdgesAndNodes(consignment.shipments),
151167
};
152168
}),
169+
email:
170+
order.consignments?.email &&
171+
removeEdgesAndNodes(order.consignments.email.giftCertificates).map(
172+
({ recipientEmail, lineItems }) => {
173+
return {
174+
email: recipientEmail,
175+
lineItems: removeEdgesAndNodes(lineItems).map(({ entityId, name, salePrice }) => ({
176+
entityId,
177+
name,
178+
salePrice,
179+
})),
180+
};
181+
},
182+
),
153183
},
154184
};
155185
});

core/app/[locale]/(default)/account/orders/fragment.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,15 @@ export const OrderItemFragment = graphql(`
3333
}
3434
}
3535
`);
36+
37+
export const OrderGiftCertificateItemFragment = graphql(`
38+
fragment OrderGiftCertificateItemFragment on OrderGiftCertificateLineItem {
39+
entityId
40+
name
41+
salePrice {
42+
value
43+
formattedV2
44+
currencyCode
45+
}
46+
}
47+
`);

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { PaginationFragment } from '~/client/fragments/pagination';
77
import { graphql, VariablesOf } from '~/client/graphql';
88
import { TAGS } from '~/client/tags';
99

10-
import { OrderItemFragment } from './fragment';
10+
import { OrderGiftCertificateItemFragment, OrderItemFragment } from './fragment';
1111

1212
const CustomerAllOrders = graphql(
1313
`
@@ -51,14 +51,29 @@ const CustomerAllOrders = graphql(
5151
}
5252
}
5353
}
54+
email {
55+
giftCertificates {
56+
edges {
57+
node {
58+
lineItems {
59+
edges {
60+
node {
61+
...OrderGiftCertificateItemFragment
62+
}
63+
}
64+
}
65+
}
66+
}
67+
}
68+
}
5469
}
5570
}
5671
}
5772
}
5873
}
5974
}
6075
`,
61-
[OrderItemFragment, PaginationFragment],
76+
[OrderItemFragment, OrderGiftCertificateItemFragment, PaginationFragment],
6277
);
6378

6479
type OrdersFiltersInput = VariablesOf<typeof CustomerAllOrders>['filters'];
@@ -116,6 +131,21 @@ export const getCustomerOrders = cache(
116131
lineItems: removeEdgesAndNodes(consignment.lineItems),
117132
};
118133
}),
134+
email:
135+
order.consignments?.email &&
136+
removeEdgesAndNodes(order.consignments.email.giftCertificates).map(
137+
({ lineItems }) => {
138+
return {
139+
lineItems: removeEdgesAndNodes(lineItems).map(
140+
({ entityId, name, salePrice }) => ({
141+
entityId,
142+
name,
143+
salePrice,
144+
}),
145+
),
146+
};
147+
},
148+
),
119149
},
120150
};
121151
}),
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use server';
2+
3+
import { revalidateTag } from 'next/cache';
4+
5+
import { getSessionCustomerAccessToken } from '~/auth';
6+
import { client } from '~/client';
7+
import { graphql, VariablesOf } from '~/client/graphql';
8+
import { TAGS } from '~/client/tags';
9+
10+
const ApplyCheckoutGiftCertificateMutation = graphql(`
11+
mutation ApplyCheckoutGiftCertificateMutation(
12+
$applyCheckoutGiftCertificateInput: ApplyCheckoutGiftCertificateInput!
13+
) {
14+
checkout {
15+
applyCheckoutGiftCertificate(input: $applyCheckoutGiftCertificateInput) {
16+
checkout {
17+
entityId
18+
}
19+
}
20+
}
21+
}
22+
`);
23+
24+
type Variables = VariablesOf<typeof ApplyCheckoutGiftCertificateMutation>;
25+
26+
interface Props {
27+
checkoutEntityId: Variables['applyCheckoutGiftCertificateInput']['checkoutEntityId'];
28+
giftCertificateCode: Variables['applyCheckoutGiftCertificateInput']['data']['giftCertificateCode'];
29+
}
30+
31+
export const applyGiftCertificate = async ({ checkoutEntityId, giftCertificateCode }: Props) => {
32+
const customerAccessToken = await getSessionCustomerAccessToken();
33+
34+
const response = await client.fetch({
35+
document: ApplyCheckoutGiftCertificateMutation,
36+
variables: {
37+
applyCheckoutGiftCertificateInput: {
38+
checkoutEntityId,
39+
data: {
40+
giftCertificateCode,
41+
},
42+
},
43+
},
44+
customerAccessToken,
45+
fetchOptions: { cache: 'no-store' },
46+
});
47+
48+
const checkout = response.data.checkout.applyCheckoutGiftCertificate?.checkout;
49+
50+
revalidateTag(TAGS.checkout);
51+
52+
return checkout;
53+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use server';
2+
3+
import { revalidateTag } from 'next/cache';
4+
5+
import { getSessionCustomerAccessToken } from '~/auth';
6+
import { client } from '~/client';
7+
import { graphql, VariablesOf } from '~/client/graphql';
8+
import { TAGS } from '~/client/tags';
9+
10+
const UnapplyCheckoutGiftCertificateMutation = graphql(`
11+
mutation UnapplyCheckoutGiftCertificateMutation(
12+
$unapplyCheckoutGiftCertificateInput: UnapplyCheckoutGiftCertificateInput!
13+
) {
14+
checkout {
15+
unapplyCheckoutGiftCertificate(input: $unapplyCheckoutGiftCertificateInput) {
16+
checkout {
17+
entityId
18+
}
19+
}
20+
}
21+
}
22+
`);
23+
24+
type Variables = VariablesOf<typeof UnapplyCheckoutGiftCertificateMutation>;
25+
26+
interface Props {
27+
checkoutEntityId: Variables['unapplyCheckoutGiftCertificateInput']['checkoutEntityId'];
28+
giftCertificateCode: Variables['unapplyCheckoutGiftCertificateInput']['data']['giftCertificateCode'];
29+
}
30+
31+
export const removeGiftCertificate = async ({ checkoutEntityId, giftCertificateCode }: Props) => {
32+
const customerAccessToken = await getSessionCustomerAccessToken();
33+
34+
const response = await client.fetch({
35+
document: UnapplyCheckoutGiftCertificateMutation,
36+
variables: {
37+
unapplyCheckoutGiftCertificateInput: {
38+
checkoutEntityId,
39+
data: {
40+
giftCertificateCode,
41+
},
42+
},
43+
},
44+
customerAccessToken,
45+
fetchOptions: { cache: 'no-store' },
46+
});
47+
48+
const checkout = response.data.checkout.unapplyCheckoutGiftCertificate?.checkout;
49+
50+
revalidateTag(TAGS.checkout);
51+
52+
return checkout;
53+
};

0 commit comments

Comments
 (0)