Skip to content

@W-24044590 feat(mrt): add v2 bundle upload command - #646

Merged
kieran-sf merged 7 commits into
mainfrom
W-24044590-mrt-bundle-upload-v2
Sep 4, 2026
Merged

kieran-sf merged 7 commits into
mainfrom
W-24044590-mrt-bundle-upload-v2

Conversation

@kieran-sf

Copy link
Copy Markdown
Contributor

Summary

Adds b2c mrt bundle upload-v2 — build and upload a v2-format bundle to Managed Runtime. This is upload-only; deploy the returned bundle ID separately with b2c mrt bundle deploy <bundleId> -e <env>. Work item: @W-24044590.

  • New CLI command mrt bundle upload-v2 and shared bundle-flag helpers. The v2 archive is a gzip tar rooted under --root-dir (default bld/), with SSR configuration written inside the archive at {root-dir}/{config-path} (default .mrt/config.json) rather than sent as request fields.
  • SDK: v2 archive creation plus push/bundle operations, MRT client + spec updates, and a matchMode (strict | ignore_missing) form field so the server enforces SSR pattern matching.
  • SSR configuration resolves from the on-disk v2 config file, else config.server.ts (evaluated from source via jiti), else defaults; flags override per key. Project package.json dependencies are recorded as bundle metadata.
  • Reference/welcome apps gain v2 build/deploy scripts and updated config.server.ts.

Testing

  • Unit tests added for the CLI command (upload-v2.test.ts) and SDK operations (bundle.test.ts, push.test.ts); the full suite passes apart from one unrelated, pre-existing oauth-command config-isolation test that also fails on main.
  • Manual end-to-end: built the reference app and uploaded a v2 bundle to a live MRT project; verified the archive layout (built files under bld/, in-archive config.json), matchMode handling, and that strict mode rejects SSR patterns matching no files while ignore_missing accepts them.

Dependencies

Adds one net-new third-party dependency: jiti (2.6.1) in @salesforce/b2c-tooling-sdk, used to evaluate a project's config.server.ts from source when resolving SSR configuration. Flagged here for maintainer 3pl-approved review.

  • No net-new third-party dependencies were added
  • If net-new third-party dependencies were added, rationale/discussion is included and 3pl-approved is set by a maintainer

  • Tests pass (pnpm test)
  • Code is formatted (pnpm run format)

Add `b2c mrt bundle upload-v2` to build and upload a v2-format bundle
(gzip tar rooted under a configurable directory, with SSR config written
inside the archive at `{root-dir}/{config-path}`). This is upload-only;
deploy the returned bundle ID separately.

- New CLI command `mrt/bundle/upload-v2` and shared bundle-flag helpers.
- SDK: v2 archive creation (`createBundleV2`), push/bundle operations,
  MRT client + spec updates, and a `matchMode` (strict|ignore_missing)
  form field so the server enforces SSR pattern matching.
- Resolve SSR config from the on-disk v2 config file, else
  `config.server.ts` (via jiti), else defaults; flags override per key.
- Record project package.json dependencies as bundle metadata.
- Reference/welcome apps: v2 deploy scripts and config.server updates.
- Docs, skills, and a changeset.
@github-actions github-actions Bot added the needs-3pl-review PR introduces net-new third-party dependencies and needs discussion label Sep 2, 2026
// `if (error)` block.
const {status} = response;

if (error) {

@o-olaosebikan o-olaosebikan Sep 2, 2026

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.

@kieran-sf Can we guard this with (error || !response.ok)?

If the server returns a 403 with a completely empty body, it leaves the error undefined. Making it look like the upload succeeded

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 catch — done in 4b2824e. Added the error || !response.ok guard.

One subtlety worth flagging: for a truly empty body openapi-fetch doesn't leave error undefined — it falls back to the raw text, so error ends up as ''. That's still falsy, so the original if (error) skipped it exactly as you described; !response.ok is what catches it. The thrown message now reports Failed to push bundle (HTTP 403): empty response body for that case, and I added a unit test (new HttpResponse(null, {status: 403})) covering it.

…-body failures

A non-OK response with an empty body (e.g. a 403 with no payload) leaves
`error` falsy — undefined or the empty string openapi-fetch falls back to
when there's no JSON to parse. The previous `if (error)` guard let those
fall through and surface as a misleading "upload succeeded but omitted a
bundle id" error. Guard on `response.ok` as well and report "empty response
body" when there's no detail. Addresses PR review feedback.
@kieran-sf
kieran-sf marked this pull request as ready for review September 3, 2026 22:06
@kieran-sf
kieran-sf requested a review from clavery as a code owner September 3, 2026 22:06
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📘 Docs preview

🧹 The preview for this PR has been removed (PR closed).

@kieran-sf

Copy link
Copy Markdown
Contributor Author

The new library is already used in the storefront-next repo (jiti) for load typescript files.

"fuse.js": "7.1.0",
"glob": "catalog:",
"i18next": "25.7.4",
"jiti": "2.6.1",

@clavery clavery Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can you explain what this is for?

We already have runtime typescript support with tsx for supporting development. Is jiti necessary for runtime features like the config file loading?

EDIT: I see you added the note at the bottom of the summary and the SFNext comment above. So it is a runtime requirement. Approved, ideally we match SFNext's version spec for it.

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 can take a look at tsx and see if I can use that.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No this is fine if storefront next is using it. That's a good enough reason to align

@clavery clavery added 3pl-approved Maintainer approved net-new third-party dependency additions and removed needs-3pl-review PR introduces net-new third-party dependencies and needs discussion labels Sep 4, 2026
@clavery

clavery commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

@kieran-sf Just to confirm: we definitely want this to be a unique command upload-v2 versus just replacing the existing command? They are different enough that we want both styles available?

@kieran-sf

Copy link
Copy Markdown
Contributor Author

@kieran-sf Just to confirm: we definitely want this to be a unique command upload-v2 versus just replacing the existing command? They are different enough that we want both styles available?

Yes the upload v1 needs to stay around because v2 isn't widely used yet so we want to keep v1 for backwards compatibility. V2 will be become the default once we start using the SCAPI API for MRT.

@kieran-sf
kieran-sf merged commit c9cf71f into main Sep 4, 2026
12 of 13 checks passed
@kieran-sf
kieran-sf deleted the W-24044590-mrt-bundle-upload-v2 branch September 4, 2026 17:18

This branch was previously deployed

1 inactive deployment
b2c-docs-preview 3745947b Deployed Sep 4, 2026 by kieran-sf via Remove preview on close #425
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3pl-approved Maintainer approved net-new third-party dependency additions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants