Skip to content

Add Zenkraft Shipping v1.0.0 - #80

Open
svetlanakostadinova wants to merge 14 commits into
SalesforceCommerceCloud:release/26.8from
zenkraft:add-zenkraft-shipping-v1.0.0
Open

Add Zenkraft Shipping v1.0.0#80
svetlanakostadinova wants to merge 14 commits into
SalesforceCommerceCloud:release/26.8from
zenkraft:add-zenkraft-shipping-v1.0.0

Conversation

@svetlanakostadinova

Copy link
Copy Markdown

Commerce App Submission

App Name: zenkraft-shipping
Display Name: Zenrkaft Shipping
Domain: shipping
ISV/Vendor Name: Zenkraft
Version: 1.0.0

Type of Change

  • New app submission
  • App version update
  • Bug fix for existing app
  • Documentation update
  • Other (please describe):

Architecture

  • UI-only (storefront-next only)
  • Backend-only (cartridges/impex only)
  • Fullstack (both UI and backend)

Description

This commerce app integrates the Zenkraft rate API with Storefront Next storefronts. The backend cartridge (int_zenkraft_sfnext) fetches real-time rates and estimated delivery dates from carriers at checkout and persists them to session and shipment custom attributes. The Storefront Next extension replaces the standard shipping options step at checkout with a component that displays those enriched shipping methods.

Checklist

Required Files

  • ZIP file name follows format: {appName}-v{version}.zip
  • ZIP contains single root folder: commerce-{appName}-app-v{version}/
  • Root manifest.json includes all required fields (id, name, description, iconName, domain, version, zip, sha256)
  • App icon exists in ZIP at commerce-{appName}-app-v{version}/icons/ (CI extracts automatically)
  • Icon filename in ZIP matches iconName field in root manifest
  • Translations added to commerce-apps-manifest/translations/en-US.json (minimum requirement)
  • catalog.json included for new apps only (with INIT values)
  • If updating existing app: Did NOT add new versions to catalog.json (CI handles this)
  • If deprecating a version: Added "deprecated": true to existing version in catalog.json

Version and Hash Validation

  • version in manifest.json matches version in commerce-app.json
  • zip field in manifest.json matches actual ZIP filename
  • sha256 in manifest.json matches computed hash of ZIP file
  • SHA256 hash verified with: shasum -a 256 [path-to-zip]

ZIP Content Validation

  • No junk files (.DS_Store, __MACOSX, Thumbs.db, hidden files)
  • No registry path prefixes in ZIP (no tax/, domain/, etc.)
  • Required files present: commerce-app.json, README.md, app-configuration/tasksList.json
  • All referenced scripts/files exist
  • No absolute paths in code
  • No hardcoded credentials

Directory Structure

  • App located at {domain}/{appName}/ where {appName} matches the "id" field in manifest
  • Only ZIP, root manifest.json, translations, and catalog.json (new apps) are committed
  • No extracted directories (commerce-*-app-v*/) committed
  • No system files (.DS_Store, Thumbs.db) committed

Validation (if using Claude Code)

  • Ran /validate-app skill
  • Ran /validate-impex skill (if app contains impex files)
  • Architecture-specific validations passed

Impex Files (if applicable)

  • Service install file has matching uninstall file
  • Uninstall files use mode="delete"
  • All attribute IDs prefixed with app name
  • No hardcoded production credentials in services.xml
  • SITEID placeholder used (not actual site ID)
  • XML files are well-formed and valid

Testing

  • Tested installation in sandbox environment
  • Verified service configurations work
  • Tested site preferences are configurable
  • Verified hooks execute correctly
  • Tested UI components render properly (if applicable)
  • Ran unit tests (if applicable)

Additional Notes

fphilip-sf and others added 10 commits July 14, 2026 18:03
…oud#48)

Delete the Avalara app package and catalog, and remove its manifest and translation entries so it no longer appears as an installable app.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: jbisaSF <100236257+jbisaSF@users.noreply.github.com>
…ssions (SalesforceCommerceCloud#50)

* @W-23544905: auto-file GUS security-review WIs for external CAP submissions

Automate the security-review kickoff for third-party Commerce App submissions.
Two independent workflows share a single classifier so their gating stays in
lock-step and neither depends on the other running:

- `.github/scripts/classify-cap-pr.sh` — one JSON blob describing the added
  ZIP, ISV directory, manifest fields, author identity, and whether the PR
  qualifies for the GUS gate (external author AND net-new ISV dir). Anchored
  regex on the author email so a crafted `"@salesforce.com"` payload can't
  spoof internal-authorship.
- `.github/scripts/test-classify-cap-pr.sh` — five fixture cases exercising
  net-new external, version-bump, Salesforce-authored, non-ZIP-only, and
  hostile-email inputs. 26/26 assertions pass.
- `.github/workflows/gus-security-review.yml` — creates one `ADM_Work__c`
  under the C360 PSA: Commerce Apps - Submissions epic when the classifier
  says so, then comments back on the PR with the WI link. Idempotent via a
  hidden `<!-- gus-security-review-wi -->` marker so `synchronize` events
  don't file duplicates.
- `.github/workflows/notify-slack-cap-pr.yml` — canary that posts one Slack
  message per CAP PR regardless of author, so operators can distinguish a
  trigger-side failure from a GUS-gate skip. Idempotent via
  `<!-- slack-cap-notify -->`.
- `docs/maintainer-setup.md` — how to configure the `GUS_SFDX_AUTH_URL` and
  `SLACK_WEBHOOK_URL` repo secrets and rotate them.

Every untrusted PR field (title, author login/email, manifest values) is
passed via `env:` and referenced as a shell variable inside `run:` — never
interpolated directly through `${{ ... }}`. JSON envelopes are built with
`jq --arg` / `--argjson` so a hostile PR title or manifest name cannot
break the JSON or escape into shell.

Co-Authored-By: Claude <noreply@anthropic.com>

* @W-23544905: switch to pull_request_target so fork PRs work

External CAP submissions arrive from forks. Under the default `pull_request`
trigger, fork PRs get empty `secrets.*` and read-only `GITHUB_TOKEN` — so
the GUS auth step, the Slack post, and the marker-comment writes would all
fail on the exact PRs these workflows exist to handle.

Switch both workflows to `pull_request_target` and follow the
fetch-but-do-not-execute pattern:

- Checkout the base ref only (`ref: base.sha`). Every script that runs —
  classifier, jq payload builders, Slack action reference — comes from the
  trusted base commit, not the PR head.
- `git fetch` the PR head into `refs/remotes/origin/pr/N`. HEAD content is
  reachable for `git show` / `git diff` but never lands on the working tree.
- The classifier now reads the PR-head manifest via
  `git show "$HEAD_SHA:$MANIFEST_PATH"` instead of a working-tree file read,
  so a fork's manipulated manifest can't influence anything beyond the
  string fields we then pass through `jq --arg`.

Docs updated with a "Why pull_request_target" section that spells out the
threat model and warns against adding any `checkout head.sha` or
`bash <head-content>` step in the future.

All 26 classifier tests still pass. shellcheck + actionlint clean.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
…ed (SalesforceCommerceCloud#55)

The refresh-token backing `GUS_SFDX_AUTH_URL` is bound to a Connected App
whose OAuth policy enforces IP restrictions. GitHub-hosted runners come
from Azure IP ranges outside any Salesforce trusted-IP list, so the auth
step fails on every external CAP PR with:

  Error (RefreshTokenAuthError): Error authenticating with the refresh
  token due to: ip restricted

Gate the job on `if: false` for now so external PRs stop turning red on
the WI-file step. The Slack canary in `notify-slack-cap-pr.yml` keeps
posting, so operators still get a signal per submission.

Re-enable by removing the `if: false` once a Connected App with
"Relax IP restrictions" is provisioned and `GUS_SFDX_AUTH_URL` is
regenerated against it.
* Update Salesforce Payments to v1.0.1

Deprecates v1.0.0 in catalog.json.

* Fix Salesforce Payments v1.0.1 - update zip and sha256
Co-authored-by: jbisaSF <100236257+jbisaSF@users.noreply.github.com>
@svetlanakostadinova
svetlanakostadinova requested review from a team July 31, 2026 14:02
@github-actions

Copy link
Copy Markdown
Contributor

@/home/runner/work/_temp/slack-marker.md

@shauryemahajanSF shauryemahajanSF left a comment

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.

Lets point this at the release/26.8 branch instead of main.

@svetlanakostadinova
svetlanakostadinova changed the base branch from main to release/26.8 July 31, 2026 14:13
@github-actions

Copy link
Copy Markdown
Contributor

@/home/runner/work/_temp/slack-marker.md

@shauryemahajanSF

shauryemahajanSF commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Hey Svetlana, thanks for the PR! Some things to consider:

  • Do we want explicit guarding against fetching fresh estimates on add to cart/change qty?
  • Do we want portions of the Zenkraft estimate API call saved on the basket so that repeated GET shipping-methods and PUT shipping-methods calls when basket hasn’t changed can use them?
  • We use dimWeight, dimWidth, dimHeight, dimDepth, length fields. Do we want to add them as part of the type-extension impex + config task to tell merchant to fill them?
  • Not sure enableZenkraftShipping is used anywhere, we can remove it.
  • Lets use the deliveryWindowStartAt, deliveryWindowEndAt fields if possible, similar to whats used in the app example below.

Example of the performance stuff above are here: cds-shipping-v1.0.5.zip

@shauryemahajanSF

Copy link
Copy Markdown
Contributor

We should also include delivery estimates on PDP using the sfcc.app.shipping.estimate hook, which wires in to the new delivery estimates SCAPI. You can find an example here: cds-shipping-v1.0.5.zip

Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
Comment thread shipping/zenkraft-shipping/zenkraft-shipping-v1.0.0.zip
@github-actions

Copy link
Copy Markdown
Contributor

@/home/runner/work/_temp/slack-marker.md

# Conflicts:
#	commerce-apps-manifest/translations/ar-MA.json
#	commerce-apps-manifest/translations/de.json
#	commerce-apps-manifest/translations/en-US.json
#	commerce-apps-manifest/translations/es.json
#	commerce-apps-manifest/translations/fr.json
#	commerce-apps-manifest/translations/it.json
#	commerce-apps-manifest/translations/ja.json
#	commerce-apps-manifest/translations/ko.json
#	commerce-apps-manifest/translations/nl.json
#	commerce-apps-manifest/translations/pl.json
#	commerce-apps-manifest/translations/pt.json
#	commerce-apps-manifest/translations/zh-CN.json
#	commerce-apps-manifest/translations/zh-TW.json
@github-actions

Copy link
Copy Markdown
Contributor

@/home/runner/work/_temp/slack-marker.md

@github-actions

Copy link
Copy Markdown
Contributor

@/home/runner/work/_temp/slack-marker.md

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.

5 participants