Skip to content

feat(cli): auto-update BC channel site URL on deploy#3001

Open
jorgemoya wants to merge 5 commits intoalphafrom
jorgemoya/ltrac-446-cli-auto-update-bc-channel-site-url-on-deploy
Open

feat(cli): auto-update BC channel site URL on deploy#3001
jorgemoya wants to merge 5 commits intoalphafrom
jorgemoya/ltrac-446-cli-auto-update-bc-channel-site-url-on-deploy

Conversation

@jorgemoya
Copy link
Copy Markdown
Contributor

@jorgemoya jorgemoya commented May 2, 2026

Jira: LTRAC-446

What/Why?

Adds an opt-in --update-site-url <channelId> flag (also bound to CATALYST_UPDATE_SITE_URL) to catalyst deploy. When passed, the CLI PUTs the deployment URL onto the given channel's site (PUT /v3/channels/{id}/site) after the bundle goes live, so merchants no longer have to copy the new URL into the control panel by hand. When the flag is omitted, deploy behaves exactly as before.

A few decisions worth flagging for review:

  • Always PUT when the flag is passed. No GET-and-skip-when-equal dance — if the caller asked for the update, we make the call.
  • Soft-fail on update errors. If the PUT returns 401/403 (most likely the access token is missing the new scope) or any other error, we log a warning + a catalyst auth login hint instead of failing the deploy. The bundle is already live by the time we hit this step, so a non-zero exit would be misleading.
  • OAuth scope. store_channel_settings is added to DEVICE_OAUTH_SCOPES. Existing logged-in users will need to re-run catalyst auth login to mint a token with the new scope; the soft-fail catches the 401/403 they would otherwise hit.
  • deployment_url deprecation. The deployment-status SSE will eventually replace deployment_url with deployment_hostnames (string array). For this change we keep using deployment_url and leave the migration as a commented TODO in DeploymentStatusSchema.

Testing

Unit tests:

  • pnpm --filter @bigcommerce/catalyst test — 141/141 passing (added 4 in channels.spec.ts for updateChannelSiteUrl, 3 in deploy.spec.ts covering the new flag).
  • pnpm --filter @bigcommerce/catalyst typecheck and pnpm --filter @bigcommerce/catalyst lint clean.

Manual end-to-end (requires a real store + at least one channel):

  1. catalyst auth login — pulls the new store_channel_settings scope.
  2. catalyst deploy --update-site-url <channelId> — confirm the post-deploy line: Updated channel <id> site URL to https://... and verify in the BC control panel.
  3. CATALYST_UPDATE_SITE_URL=<channelId> catalyst deploy — confirm env var is honored.
  4. catalyst deploy (no flag) — confirm no channel API call is made.
  5. With a token missing store_channel_settings, run catalyst deploy --update-site-url <channelId> and confirm the warning + catalyst auth login hint instead of a crash.

Migration

None. The flag is purely opt-in. Users who want the auto-update should re-run catalyst auth login (new OAuth scope) and then add --update-site-url <channelId> to their deploy invocation (or set CATALYST_UPDATE_SITE_URL in CI).

jorgemoya and others added 2 commits May 1, 2026 21:00
After a successful `catalyst deploy`, automatically update the linked
BigCommerce channel's site URL to the new deployment URL so merchants no
longer have to remember to do it manually in the control panel.

The channel ID is selected interactively at `catalyst project link` /
`project create` time (with a "skip" option for users who don't want to
link a channel) and persisted to `.bigcommerce/project.json`. At deploy
time the resolution order is `--channel-id` flag, then
`CATALYST_CHANNEL_ID`, then project.json. Pass `--no-update-channel` to
opt out of the auto-update.

The deploy first GETs the current channel site and skips the PUT when
the URL already matches, and any failure during the update is treated as
a soft warning so the deploy itself remains successful — the bundle is
already live by the time we hit this step.

Adds the `store_channel_settings` scope to the device-OAuth flow;
existing logged-in users will need to re-run `catalyst auth login` to
pick it up. The new endpoint also requires that scope, so the soft-fail
path points users at `catalyst auth login` if they hit a 401/403.

Refs LTRAC-446
Co-Authored-By: Claude <noreply@anthropic.com>
Add coverage for the post-deploy channel site URL auto-update introduced
in cce879a:

- channels.spec.ts: unit tests for fetchChannels, fetchChannelSite (incl.
  404→null), and updateChannelSiteUrl, asserting that 401/403 responses
  surface the re-auth hint.
- project.spec.ts: tests the new channel picker in `project link` and
  `project create` — a selection writes channelId to project.json, the
  Skip option leaves it untouched, an empty storefront list is handled,
  and a 403 from the channels API soft-fails so users can still proceed.
- deploy.spec.ts: tests the post-deploy update path — successful update,
  channelId resolution from project.json, the GET-and-skip-when-equal
  optimization, --no-update-channel as a hard skip, the no-channel-id
  warning, and the 401 soft-fail with re-auth hint.
- tests/mocks/handlers.ts: default `/v3/channels` handler returns an
  empty list so unrelated tests no longer hit the unhandled-request
  warning while still exercising the soft-fail path.

Refs LTRAC-446
Co-Authored-By: Claude <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
catalyst Ready Ready Preview, Comment May 4, 2026 8:53pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 2, 2026

⚠️ No Changeset found

Latest commit: fa310a9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@jorgemoya jorgemoya changed the title LTRAC-446: feat(cli) - Auto-update BC channel site URL on deploy feat(cli): auto-update BC channel site URL on deploy May 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Bundle Size Report

Comparing against baseline from ec92930 (2026-05-04).

No bundle size changes detected.

The channel picker added in cce879a filtered to type=storefront, which
still surfaces non-Catalyst storefronts (Stencil, headless, etc.) that
the user can't meaningfully target with `catalyst deploy`. Narrow the
filter to platform=catalyst so the picker only shows channels actually
backed by Catalyst.

Refs LTRAC-446
Co-Authored-By: Claude <noreply@anthropic.com>
@jorgemoya jorgemoya marked this pull request as ready for review May 2, 2026 02:38
@jorgemoya jorgemoya requested a review from a team as a code owner May 2, 2026 02:38
…s.ts

Move the GET (404) and PUT (success) channel-site MSW handlers used by
the post-deploy auto-update tests into the shared handlers.ts so each
test only has to override the path it actually exercises.

Refs LTRAC-446
Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@chanceaclark chanceaclark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intention behind this change is good, but I think it might be very destructive and we should probably avoid this. Maybe we can go in the direction that you can pass a flag to do this?

if (current?.url === deploymentUrl) {
consola.info(`Channel ${channelId} site URL already up to date (${deploymentUrl}).`);
} else {
await updateChannelSiteUrl(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually might mess up people testing deployments to native hosting and would be very destructive.

For example, I might have channel 123 being deployed via Vercel and I am dual-deploying this to Vercel and Native Hosting, deploying will change the channels site, thus messing up the production deployment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good callout, 100% agree, lets make this work opt in via an explicit flag that needs to be passed when deploying.

Having said that, do we want to remove all logic from project create and project link to add the channel to project.json? Or we keep that and just add the explicit flag?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think hosting should be tied to a channel.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have simplified it considerably by simply having a --update-site-url flag that requires a channelId. Still kept the store_channel_settings oauth scope to allow this for users who are authing via the CLI.

The unknown I have is that once we merge the deployment_hostnames changes, the returned array can contain N urls. How will one select the one they want to update to? Obviously we could default to the first one, but maybe it needs to be user selected?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if instead of doing this on the deploy command we have a separate CLI command to manage this? We'd need to think through the UX for it, but I think it might be better than just a flag?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I see your point. I would wait to get the deployment_hostnames work merged first then.

What I would do is a new command that updates the site channel id. It will get all hostnames under the defined project, and then allow the user to select which hostname they want to be used for site url.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah something like that.

Drop the channel-picker UX added to `project link` / `project create` and
the persisted `channelId` in project.json. The auto-update is now driven
by a single `--update-site-url <channelId>` flag (or
`CATALYST_UPDATE_SITE_URL` env) on `catalyst deploy`: when passed, the
deployed URL is PUT to that channel's site after the bundle goes live.

Also drop the GET-then-skip-when-equal optimization so the command
unconditionally PUTs the deployment URL when the flag is supplied — the
caller opted in explicitly, so always make the call.

The implementation collapses to: keep `updateChannelSiteUrl`, drop
`fetchChannels` and `fetchChannelSite`, and keep the soft-fail (warn +
re-auth hint) so a 401/403 doesn't sour an otherwise-successful deploy.

Refs LTRAC-446
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Unlighthouse Performance Comparison — Vercel

Comparing PR preview deployment Unlighthouse scores vs production Unlighthouse scores.

Summary Score

Aggregate score across all categories as reported by Unlighthouse.

Prod Desktop Prod Mobile Preview Desktop Preview Mobile
Score 90 92 91 96

Category Scores

Category Prod Desktop Prod Mobile Preview Desktop Preview Mobile
Performance 74 73 75 95
Accessibility 95 95 95 98
Best Practices 100 100 95 100
SEO 88 100 100 100

Core Web Vitals

Metric Prod Desktop Prod Mobile Preview Desktop Preview Mobile
LCP 3.8 s 2.6 s 4.1 s 2.9 s
CLS 0.037 0.943 0.037 0.039
FCP 1.2 s 1.2 s 1.2 s 1.2 s
TBT 10 ms 20 ms 0 ms 10 ms
Max Potential FID 60 ms 90 ms 50 ms 70 ms
Time to Interactive 3.9 s 3.3 s 4.1 s 3.8 s

Full Unlighthouse report →

@jorgemoya jorgemoya requested a review from chanceaclark May 4, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants