Skip to content

TRAC-969: Create reusable preview deployment action - #3194

Open
jordanarldt wants to merge 11 commits into
canaryfrom
TRAC-969
Open

TRAC-969: Create reusable preview deployment action#3194
jordanarldt wants to merge 11 commits into
canaryfrom
TRAC-969

Conversation

@jordanarldt

@jordanarldt jordanarldt commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Jira: TRAC-969

What/Why?

Adds packages/deployment-preview-action, a GitHub Action that deploys a preview of a pull request to BigCommerce native hosting and keeps the PR comments describing it accurate. core/.github/ ships a ready-to-use workflow, so scaffolded storefronts get previews without writing one.

Three decisions worth knowing before reading the diff:

All previews share one hosting project. Native hosting assigns a hostname per project, not per deployment, so a second deploy replaces the first at the same URL. The project serves one PR at a time, which is why there is arbitration at all. The newest open PR deploys on push; any other takes the preview over by commenting redeploy preview. A PR that loses the preview gets its comment rewritten, so no thread advertises a URL that now serves someone else's code.

Shipped as both an action and a reusable workflow. A workflow can declare concurrency, permissions and environment; an action cannot. The concurrency group is load-bearing here — two deploys at once would race for the shared project — so the reusable wrapper is the recommended entry point and core/ uses it.

The comment path builds PR code with the store's deploy credentials. Write-permission and same-repo checks run before checkout, so nothing untrusted is fetched, let alone executed by pnpm install. These live inside the action rather than in copy-pasteable YAML so they can't be omitted by mistake.

Unconfigured repositories skip silently rather than failing, so a freshly scaffolded storefront doesn't get a red X on its first PR.

Testing

pnpm --filter @bigcommerce/deployment-preview-action test

43 tests against a stubbed BigCommerce and GitHub API — no credentials or network needed. They cover the deploy-eligibility rules, which comment updates notify vs. stay silent, and action.yml itself (every run block is syntax-checked, since nothing compiles it).

Verified end to end against a real store: auto-deploy on the newest PR, deferral on an older one, redeploy preview takeover, and the comment rewrite on the displaced PR.

Migration

None for existing projects. Previews stay off until configured with a PREVIEW_DEPLOYMENT_PROJECT_UUID variable and the store credentials — see the package README.

@changeset-bot

changeset-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 39883cd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@bigcommerce/deployment-preview-action Minor

Not sure what this means? Click here to learn what changesets are.

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

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
catalyst Ready Ready Preview Sep 4, 2026 4:45pm UTC

Request Review

@jordanarldt
jordanarldt force-pushed the TRAC-969 branch 2 times, most recently from 2a99903 to 74462d0 Compare August 26, 2026 18:28
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Report

Comparing against baseline from 49a3432 (2026-09-02).

No bundle size changes detected.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

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 89 93 92 95

Category Scores

Category Prod Desktop Prod Mobile Preview Desktop Preview Mobile
Performance 71 93 73 92
Accessibility 95 92 95 92
Best Practices 100 100 100 100
SEO 88 100 100 100

Core Web Vitals

Metric Prod Desktop Prod Mobile Preview Desktop Preview Mobile
LCP 5.2 s 3.2 s 4.0 s 3.2 s
CLS 0.037 0 0.037 0
FCP 1.2 s 1.2 s 1.2 s 1.2 s
TBT 0 ms 20 ms 10 ms 0 ms
Max Potential FID 50 ms 80 ms 60 ms 60 ms
Time to Interactive 5.2 s 3.7 s 6.2 s 4.3 s

Full Unlighthouse report →

Comment thread packages/deployment-preview-action/examples/with-action.yml Outdated
Comment thread packages/deployment-preview-action/scripts/catalyst-preview.mjs
…ter it deploys

A redeploy looked up its check run by name, which on a commit that had already
auto-deployed found the row GitHub manages for the job itself. GitHub refuses
API changes to those, and gh writes the refusal to stdout, so the 403 body was
captured as the check run id. Every later request built a URL out of that JSON
and failed, turning a run red after it had deployed, announced the preview and
reacted to the command.

Claim rows with an external_id and only ever update those; name the row for the
command rather than the job, so the two cannot collide. Filter every captured
id to digits, since a refused request leaves JSON, not nothing.

Treat both closing patches as bookkeeping. The failure handler patched before
commenting, so a redeploy that genuinely failed left no comment at all.

Refs TRAC-969
Co-Authored-By: Claude <noreply@anthropic.com>
…edeploy

Reusing the previous redeploy's row looked right and did nothing. A check run
belongs to the workflow run that created it; another run's PATCH returns 200 and
changes no field. Polling the row through a redeploy showed it sitting on the
previous result for the whole run, so the yellow in-progress check the command
is supposed to give never appeared on a repeat redeploy of the same commit.

Always POST. GitHub lists only the newest row per name, so the superseded rows
do not pile up, and the run that opened a row is the one that closes it.

Refs TRAC-969
Co-Authored-By: Claude <noreply@anthropic.com>
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