Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
da702cc
chore(ci): remove conditionally based on deployments (#2807)
chanceaclark Jan 6, 2026
dd559b2
fix(core): minor UX improvements for Reviews components (#2809)
jorgemoya Jan 6, 2026
b57bffa
fix: clear pagination cursors when sort option changes (#2811)
chanceaclark Jan 6, 2026
ea9d633
fix(core): delete duplicate select component (#2813)
jorgemoya Jan 7, 2026
b4b87a3
feat: pass in additional attributes for script tags (#2816)
chanceaclark Jan 8, 2026
fcb946e
fix(form): display store password complexity requirements in registra…
matthewvolk Jan 8, 2026
d469078
fix(core): persist checkbox modifier in PDP (#2817)
jorgemoya Jan 9, 2026
74e4dd1
fix(catalyst): CATALYST-1537 Disable filters that are no longer avail…
jordanarldt Jan 12, 2026
52ee85e
Feat: add required indicators to form fields (#2815)
jamesqquick Jan 12, 2026
a50fa6f
fix(catalyst): Fix WishlistDetails page from exceeding complexity lim…
jordanarldt Jan 12, 2026
e5a03f6
fix(catalyst): Update data-disabled selectors to data-[disabled] (#2821)
jordanarldt Jan 12, 2026
a1f1ed8
[Catalyst 1677] Dont reset login form data (#2819)
jamesqquick Jan 14, 2026
f65d81f
chore(ci): non-sensitive gh action secrets moved to vars (#2824)
matthewvolk Jan 14, 2026
dcad856
refactor: decouple fields from state in DynamicForms (#2823)
jorgemoya Jan 16, 2026
b5f460c
Update translations (#2826)
bc-svc-local Jan 20, 2026
49b1097
feat(core): filter out child cart line items (#2827)
jorgemoya Jan 22, 2026
8096cc5
fix(core): improve accessibility for price displays (#2829)
jorgemoya Jan 22, 2026
a520dbc
[CATALYST-965] Audit placeholders (#2833)
jamesqquick Jan 23, 2026
5c3e4d2
chore(catalyst): CATALYST-1297 Run E2E tests on PRs (#2822)
jordanarldt Jan 23, 2026
9f54960
chore(ci): pass channel-specific env vars to vercel deploy (#2834)
matthewvolk Jan 26, 2026
06fd9aa
Update translations (#2836)
bc-svc-local Jan 26, 2026
588c53d
fix: Fix successMessage translations (#2831)
funivan Jan 26, 2026
0b65316
chore: change changeset from minor to patch (#2837)
jorgemoya Jan 26, 2026
81b13e4
Version Packages (`canary`) (#2810)
github-actions[bot] Jan 26, 2026
6299f51
Merge branch 'canary' into sync-integrations-makeswift
jorgemoya Jan 26, 2026
aaf5f46
chore: revert version
jorgemoya Jan 26, 2026
9529c3e
chore: remove changelog changes
jorgemoya Jan 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 97 additions & 2 deletions .github/workflows/basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
BIGCOMMERCE_STORE_HASH: ${{ secrets.BIGCOMMERCE_STORE_HASH }}
BIGCOMMERCE_STORE_HASH: ${{ vars.BIGCOMMERCE_STORE_HASH }}
BIGCOMMERCE_CHANNEL_ID: ${{ vars.BIGCOMMERCE_CHANNEL_ID }}
BIGCOMMERCE_CLIENT_ID: ${{ secrets.BIGCOMMERCE_CLIENT_ID }}
BIGCOMMERCE_CLIENT_SECRET: ${{ secrets.BIGCOMMERCE_CLIENT_SECRET }}
BIGCOMMERCE_STOREFRONT_TOKEN: ${{ secrets.BIGCOMMERCE_STOREFRONT_TOKEN }}
BIGCOMMERCE_CHANNEL_ID: ${{ secrets.BIGCOMMERCE_CHANNEL_ID }}
BIGCOMMERCE_ACCESS_TOKEN: ${{ secrets.BIGCOMMERCE_ACCESS_TOKEN }}
TEST_CUSTOMER_ID: ${{ vars.TEST_CUSTOMER_ID }}
TEST_CUSTOMER_EMAIL: ${{ vars.TEST_CUSTOMER_EMAIL }}
TEST_CUSTOMER_PASSWORD: ${{ secrets.TEST_CUSTOMER_PASSWORD }}
TESTS_FALLBACK_LOCALE: ${{ vars.TESTS_FALLBACK_LOCALE }}
TESTS_READ_ONLY: ${{ vars.TESTS_READ_ONLY }}
DEFAULT_PRODUCT_ID: ${{ vars.DEFAULT_PRODUCT_ID }}
DEFAULT_COMPLEX_PRODUCT_ID: ${{ vars.DEFAULT_COMPLEX_PRODUCT_ID }}

jobs:
lint-typecheck:
Expand Down Expand Up @@ -75,3 +85,88 @@ jobs:

- name: Run Tests
run: pnpm run test

e2e-tests:
name: E2E Functional Tests (${{ matrix.name }})

runs-on: ubuntu-latest

strategy:
matrix:
include:
- name: default
browsers: chromium webkit
test-filter: tests/ui/e2e
trailing-slash: true
locale-var: TESTS_LOCALE
artifact-name: playwright-report
- name: TRAILING_SLASH=false
browsers: chromium
test-filter: tests/ui/e2e --grep @no-trailing-slash
trailing-slash: false
locale-var: TESTS_LOCALE
artifact-name: playwright-report-no-trailing
- name: alternate locale
browsers: chromium
test-filter: tests/ui/e2e --grep @alternate-locale
trailing-slash: true
locale-var: TESTS_ALTERNATE_LOCALE
artifact-name: playwright-report-alternate-locale

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2

- uses: pnpm/action-setup@v3

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install Playwright browsers
run: pnpm exec playwright install --with-deps ${{ matrix.browsers }}
working-directory: ./core

# - name: Build catalyst-client
# run: pnpm --filter @bigcommerce/catalyst-client build

# - name: Build catalyst-core
# run: pnpm --filter @bigcommerce/catalyst-core build

- name: Build catalyst
run: pnpm build

- name: Start server
run: |
pnpm start &
npx wait-on http://localhost:3000 --timeout 60000
working-directory: ./core
env:
PORT: 3000
AUTH_SECRET: ${{ secrets.TESTS_AUTH_SECRET }}
AUTH_TRUST_HOST: ${{ vars.TESTS_AUTH_TRUST_HOST }}
BIGCOMMERCE_TRUSTED_PROXY_SECRET: ${{ secrets.BIGCOMMERCE_TRUSTED_PROXY_SECRET }}
TESTS_LOCALE: ${{ vars[matrix.locale-var] }}
TRAILING_SLASH: ${{ matrix.trailing-slash }}
DEFAULT_REVALIDATE_TARGET: ${{ matrix.name == 'default' && '1' || '' }}

- name: Run E2E tests
run: pnpm exec playwright test ${{ matrix.test-filter }}
working-directory: ./core
env:
PLAYWRIGHT_TEST_BASE_URL: http://localhost:3000

- name: Upload test results
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: ./core/.tests/reports/
retention-days: 3
69 changes: 53 additions & 16 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Production Tag Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
# secrets is for dependabot compatibility; prefer vars when available
VERCEL_ORG_ID: ${{ vars.VERCEL_ORG_ID != '' && vars.VERCEL_ORG_ID || secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ vars.VERCEL_PROJECT_ID != '' && vars.VERCEL_PROJECT_ID || secrets.VERCEL_PROJECT_ID }}
on:
push:
tags:
Expand All @@ -10,7 +11,7 @@ on:
- "@bigcommerce/catalyst-b2b-makeswift@latest"
jobs:
deploy-tag:
name: Deploy `{{ github.ref_name }}` tag
name: Deploy `${{ github.ref_name }}` tag
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
Expand All @@ -20,25 +21,61 @@ jobs:
- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Parse Tag and Build Domain
id: parse-tag
- name: Configure catalyst-core deployment
if: contains(github.ref_name, 'catalyst-core@')
run: |
TAG="${{ github.ref_name }}"
PACKAGE_NAME=$(echo "$TAG" | sed -E 's/^@bigcommerce\/([^@]+)@.*$/\1/')
case "$PACKAGE_NAME" in
"catalyst-core") DOMAIN="catalyst-demo.site" ;;
"catalyst-makeswift") DOMAIN="makeswift.catalyst-demo.site" ;;
"catalyst-b2b-makeswift") DOMAIN="b2b-makeswift.catalyst-demo.site" ;;
*) echo "Error: Unknown package name: $PACKAGE_NAME"; exit 1 ;;
esac
echo "domain=$DOMAIN" >> $GITHUB_OUTPUT
echo "DOMAIN=catalyst-demo.site" >> $GITHUB_ENV
echo "CHANNEL_ID=${{ vars.CORE_BIGCOMMERCE_CHANNEL_ID }}" >> $GITHUB_ENV
echo "STOREFRONT_TOKEN=${{ secrets.CORE_BIGCOMMERCE_STOREFRONT_TOKEN }}" >> $GITHUB_ENV

- name: Configure catalyst-makeswift deployment
if: contains(github.ref_name, 'catalyst-makeswift@')
run: |
echo "DOMAIN=makeswift.catalyst-demo.site" >> $GITHUB_ENV
echo "CHANNEL_ID=${{ vars.MAKESWIFT_BIGCOMMERCE_CHANNEL_ID }}" >> $GITHUB_ENV
echo "STOREFRONT_TOKEN=${{ secrets.MAKESWIFT_BIGCOMMERCE_STOREFRONT_TOKEN }}" >> $GITHUB_ENV
echo "MAKESWIFT_KEY=${{ secrets.MAKESWIFT_SITE_API_KEY }}" >> $GITHUB_ENV

- name: Configure catalyst-b2b-makeswift deployment
if: contains(github.ref_name, 'catalyst-b2b-makeswift@')
run: |
echo "DOMAIN=b2b-makeswift.catalyst-demo.site" >> $GITHUB_ENV
echo "CHANNEL_ID=${{ vars.B2B_MAKESWIFT_BIGCOMMERCE_CHANNEL_ID }}" >> $GITHUB_ENV
echo "STOREFRONT_TOKEN=${{ secrets.B2B_MAKESWIFT_BIGCOMMERCE_STOREFRONT_TOKEN }}" >> $GITHUB_ENV
echo "MAKESWIFT_KEY=${{ secrets.B2B_MAKESWIFT_SITE_API_KEY }}" >> $GITHUB_ENV
echo "B2B_API_HOST=${{ vars.B2B_API_HOST }}" >> $GITHUB_ENV
echo "BIGCOMMERCE_ACCESS_TOKEN=${{ secrets.B2B_BIGCOMMERCE_ACCESS_TOKEN }}" >> $GITHUB_ENV

- name: Deploy to Vercel
id: deploy
timeout-minutes: 15
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
DEPLOYMENT_URL=$(vercel deploy --token=${{ secrets.VERCEL_TOKEN }})
DEPLOY_ARGS=(
--token="$VERCEL_TOKEN"
--env BIGCOMMERCE_CHANNEL_ID="$CHANNEL_ID"
--env BIGCOMMERCE_STOREFRONT_TOKEN="$STOREFRONT_TOKEN"
)

if [[ -n "$MAKESWIFT_KEY" ]]; then
DEPLOY_ARGS+=(--env MAKESWIFT_SITE_API_KEY="$MAKESWIFT_KEY")
fi

if [[ -n "$B2B_API_HOST" ]]; then
DEPLOY_ARGS+=(--env B2B_API_HOST="$B2B_API_HOST")
fi

if [[ -n "$BIGCOMMERCE_ACCESS_TOKEN" ]]; then
DEPLOY_ARGS+=(--env BIGCOMMERCE_ACCESS_TOKEN="$BIGCOMMERCE_ACCESS_TOKEN")
fi

DEPLOYMENT_URL=$(vercel deploy "${DEPLOY_ARGS[@]}")
echo "deployment_url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT

- name: Set Vercel Domain Alias
timeout-minutes: 5
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
vercel alias ${{ steps.deploy.outputs.deployment_url }} ${{ steps.parse-tag.outputs.domain }} --token=${{ secrets.VERCEL_TOKEN }}
vercel alias ${{ steps.deploy.outputs.deployment_url }} $DOMAIN --token="$VERCEL_TOKEN"
1 change: 0 additions & 1 deletion .github/workflows/regression-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ concurrency:

jobs:
unlighthouse-audit:
if: ${{ contains(fromJson('["Production – catalyst-canary", "Preview – catalyst-canary"]'), github.event.deployment_status.environment) }}
name: Unlighthouse Audit - ${{ matrix.device }}
runs-on: ubuntu-latest
strategy:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { parseWithZod } from '@conform-to/zod';
import { getLocale, getTranslations } from 'next-intl/server';
import { z } from 'zod';

import { DynamicFormActionArgs } from '@/vibes/soul/form/dynamic-form';
import { Field, FieldGroup, schema } from '@/vibes/soul/form/dynamic-form/schema';
import { signIn } from '~/auth';
import { client } from '~/client';
Expand Down Expand Up @@ -335,24 +336,28 @@ function parseRegisterCustomerInput(
}

export async function registerCustomer<F extends Field>(
prevState: { lastResult: SubmissionResult | null; fields: Array<F | FieldGroup<F>> },
{ fields, passwordComplexity }: DynamicFormActionArgs<F>,
_prevState: {
lastResult: SubmissionResult | null;
},
formData: FormData,
) {
const t = await getTranslations('Auth.Register');
const locale = await getLocale();
const cartId = await getCartId();

const submission = parseWithZod(formData, { schema: schema(prevState.fields) });
const submission = parseWithZod(formData, {
schema: schema(fields, passwordComplexity),
});

if (submission.status !== 'success') {
return {
lastResult: submission.reply(),
fields: prevState.fields,
};
}

try {
const input = parseRegisterCustomerInput(submission.value, prevState.fields);
const input = parseRegisterCustomerInput(submission.value, fields);
const response = await client.fetch({
document: RegisterCustomerMutation,
variables: {
Expand All @@ -368,7 +373,6 @@ export async function registerCustomer<F extends Field>(
lastResult: submission.reply({
formErrors: response.data.customer.registerCustomer.errors.map((error) => error.message),
}),
fields: prevState.fields,
};
}

Expand All @@ -389,20 +393,17 @@ export async function registerCustomer<F extends Field>(
lastResult: submission.reply({
formErrors: error.errors.map(({ message }) => message),
}),
fields: prevState.fields,
};
}

if (error instanceof Error) {
return {
lastResult: submission.reply({ formErrors: [error.message] }),
fields: prevState.fields,
};
}

return {
lastResult: submission.reply({ formErrors: [t('somethingWentWrong')] }),
fields: prevState.fields,
};
}

Expand Down
14 changes: 14 additions & 0 deletions core/app/[locale]/(default)/(auth)/register/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ const RegisterCustomerQuery = graphql(
) {
site {
settings {
customers {
passwordComplexitySettings {
minimumNumbers
minimumPasswordLength
minimumSpecialCharacters
requireLowerCase
requireNumbers
requireSpecialCharacters
requireUpperCase
}
}
formFields {
customer(filters: $customerFilters, sortBy: $customerSortBy) {
...FormFieldsFragment
Expand Down Expand Up @@ -68,6 +79,8 @@ export const getRegisterCustomerQuery = cache(async ({ address, customer }: Prop
const addressFields = response.data.site.settings?.formFields.shippingAddress;
const customerFields = response.data.site.settings?.formFields.customer;
const countries = response.data.geography.countries;
const passwordComplexitySettings =
response.data.site.settings?.customers?.passwordComplexitySettings;

if (!addressFields || !customerFields) {
return null;
Expand All @@ -77,5 +90,6 @@ export const getRegisterCustomerQuery = cache(async ({ address, customer }: Prop
addressFields,
customerFields,
countries,
passwordComplexitySettings,
};
});
4 changes: 3 additions & 1 deletion core/app/[locale]/(default)/(auth)/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export default async function Register({ params }: Props) {
notFound();
}

const { addressFields, customerFields, countries } = registerCustomerData;
const { addressFields, customerFields, countries, passwordComplexitySettings } =
registerCustomerData;

const fields = transformFieldsToLayout(
[
Expand Down Expand Up @@ -109,6 +110,7 @@ export default async function Register({ params }: Props) {
<DynamicFormSection
action={registerCustomer}
fields={fields}
passwordComplexity={passwordComplexitySettings}
submitLabel={t('cta')}
title={t('heading')}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ export interface State {
addresses: Address[];
lastResult: SubmissionResult | null;
defaultAddress?: DefaultAddressConfiguration;
fields: Array<Field | FieldGroup<Field>>;
}

export async function addressAction(prevState: Awaited<State>, formData: FormData): Promise<State> {
export async function addressAction(
fields: Array<Field | FieldGroup<Field>>,
prevState: Awaited<State>,
formData: FormData,
): Promise<State> {
'use server';

const intent = formData.get('intent');

switch (intent) {
case 'create': {
return await createAddress(prevState, formData);
return await createAddress(fields, prevState, formData);
}

case 'update': {
return await updateAddress(prevState, formData);
return await updateAddress(fields, prevState, formData);
}

case 'delete': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,11 @@ function parseAddAddressInput(
return inputSchema.parse(mappedInput);
}

export async function createAddress(prevState: Awaited<State>, formData: FormData): Promise<State> {
export async function createAddress(
fields: Array<Field | FieldGroup<Field>>,
prevState: Awaited<State>,
formData: FormData,
): Promise<State> {
const t = await getTranslations('Account.Addresses');
const customerAccessToken = await getSessionCustomerAccessToken();

Expand All @@ -210,7 +214,7 @@ export async function createAddress(prevState: Awaited<State>, formData: FormDat
}

try {
const input = parseAddAddressInput(submission.value, prevState.fields);
const input = parseAddAddressInput(submission.value, fields);

const response = await client.fetch({
document: AddCustomerAddressMutation,
Expand Down Expand Up @@ -242,7 +246,6 @@ export async function createAddress(prevState: Awaited<State>, formData: FormDat
],
lastResult: submission.reply({ resetForm: true }),
defaultAddress: prevState.defaultAddress,
fields: prevState.fields,
};
} catch (error) {
// eslint-disable-next-line no-console
Expand Down
Loading
Loading