Conversation
…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>
…oud#48) (SalesforceCommerceCloud#49) 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: fphilip-sf <132393744+fphilip-sf@users.noreply.github.com> 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>
…alesforceCommerceCloud#60) Bring the forward-integration cascade (already merged to main in SalesforceCommerceCloud#58) onto release/26.8 so a ZIP landing here promotes forward along the chain release/26.8 -> release/26.9 -> main. Identical to the main version: - promotion-utils.sh, test-promotion-utils.sh (25 tests) - root-manifest-utils.sh: tolerant lookup_manifest_entry_for_zip + stderr errors - update-catalog.yml: release/** trigger, promote-forward job, skip unreferenced back-ports Co-authored-by: Claude Opus 4.8 <claude.noreply@salesforce.com>
…sforceCommerceCloud#62) * @W-23544905: auto-file GUS security-review WIs for external CAP submissions (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> (cherry picked from commit ef7ece7) * @W-23544905: disable GUS WI auto-file until Connected App is IP-relaxed (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. (cherry picked from commit 133e21d) * @W-23563851: extend CAP security scanner with S17/S18/S19 (WARN) (SalesforceCommerceCloud#54) * @W-23563851: extend CAP security scanner with S17/S18/S19 (WARN) Adds three new WARN-tier rules to `.github/scripts/security-scan.sh`, all surfaced by the Avalara Tax v1.1.0 CAP review: - S17: BM controller `guard.ensure([...])` includes a state-changing method (`post`/`put`/`patch`/`delete`) but omits `'csrf'`. Scoped to `/bm_cartridges/` so storefront controllers with their own CSRF token flow are not flagged. - S18: `Logger.(warn|error|info|debug|trace)(... JSON.stringify(err|error|e| response|svcResponse|svcResult|result ...))` — raw error/response objects stringified into logs; recommend logging only `error.message` or a redacted status object. - S19: `encodeURI(...)` with a `+` concatenation or template-literal interpolation in the argument. `encodeURI` preserves URL delimiters (`/ ? & = #`) and single quotes; recommend `encodeURIComponent` per user-provided segment/param. All three are WARN, not BLOCK, so exit code and blocking-finding count are unchanged on already-shipped apps. Comments are filtered via the existing `strip_comments` helper. Fixture tests in `test-security-scan.sh` add positive and negative cases per rule (fires; does not fire on comment-only, unrelated code, or out-of-scope paths). Total: 123 tests pass, 0 fail. Documented in `.claude/skills/shared/security-rules.md` (which `.claude/skills/validate-app/references/security-scan.md` links to as the canonical rule list) with a one-paragraph description and suggested fix per rule. Verified: Avalara v1.1.1 (v1.1.0 is no longer in the local registry — see commit a60c0f4 for the removal) → 3 S18 warnings on `logger.error(... JSON.stringify(response.details))`; S17/S19 have no live matches on the fixed versions, so their shape correctness is carried by fixture tests. Blocking count unchanged (0 → 0). Byte-identical scanner output vs. `main` on `commerce-noibu-analytics-app-v0.1.0` and `commerce-vertex-tax-app-v1.0.0`. Co-Authored-By: Claude <noreply@anthropic.com> * @W-23563851: cover S17/S18 regex alternatives in fixtures Address review nits by adding fixtures for every alternation in the S17 and S18 regex, so a future narrowing of either regex is caught by CI instead of silently reducing coverage. - S17: add `patch` and `delete` state-changing-method fixtures (previously only `post` and `put` were covered). - S18: add fixtures for the missing log levels (`info`, `trace`) and identifiers (`error`, `e`, `svcResult`, `result`). Tests: 129 passed, 0 failed (was 123). --------- Co-authored-by: Claude <noreply@anthropic.com> (cherry picked from commit 4f1c691) --------- Co-authored-by: Claude <noreply@anthropic.com>
* @W-23543664: Introduce Salesforce Payments (SFP) app into release/26.8 Port the sf-payments app (v1.0.1) from main, including its manifest entry, translations, and catalog, so release/26.8 carries the same payment app catalog as main. * @W-23543664: Reset sf-payments catalog.json to pre-1.0.1 state Step 2 of verify-zip.yml rejects a manifest version that's already listed in catalog.json, since the update-catalog workflow is expected to append it after merge (as it did via SalesforceCommerceCloud#57 on main). Copying main's already-updated catalog.json tripped that guard; reset it to the pre-SalesforceCommerceCloud#57 state so CI adds 1.0.1 post-merge instead. * @W-23543664: Use INIT stub for sf-payments catalog.json release/26.8 only ever carries the 1.0.1 zip (1.0.0 was never published there), so seeding catalog.json with a deprecated 1.0.0 entry was wrong - that version's artifact doesn't exist on this branch. This is the first introduction of the app here, so use the same INIT stub main used in SalesforceCommerceCloud#51 and let update-catalog.yml populate 1.0.1 as the first real entry post-merge.
Co-authored-by: jbisaSF <100236257+jbisaSF@users.noreply.github.com>
…ndentation (SalesforceCommerceCloud#67) Two coupled fixes to the forward-integration workflow: 1. promote-forward checked out a throwaway local branch `promote-work`, but peter-evans/create-pull-request treats the checked-out branch as its "working base" and during cleanup runs `git reset --hard origin/<branch>`. `origin/promote-work` never exists, so the reset aborts with exit 128 and the promotion PR is never opened. Check out a local branch named after the target ($next) tracking its real origin ref instead. 2. merge_manifest_entry now passes `jq --indent 4` so the manifest upsert keeps a minimal diff (the committed manifest.json is 4-space indented) instead of reformatting the whole file to jq's 2-space default on every promotion. Adds a regression test asserting the emitted indentation. Co-authored-by: Claude Opus 4.8 <claude.noreply@salesforce.com>
… release/26.8 (SalesforceCommerceCloud#76) * @W-23634047: Carry non-CAP file changes forward across release branches (SalesforceCommerceCloud#72) Extends the existing ZIP/catalog.json/manifest.json/icon auto-promotion chain to also promote everything else: arbitrary non-CAP files (docs, skills, etc.), manual manifest.json edits pushed with no ZIP, and translations/*.json locale files (additive per-key merge, keyed by app id). Non-CAP files are captured as one patch per changed path (not one combined patch) so a single conflicting or binary file can't cause unrelated files in the same push to be dropped. .github/workflows/** is excluded from the non-CAP pathspec since GITHUB_TOKEN cannot push workflow-file changes. Also fixes several promotion-utils.sh bugs found in review: a byte-identical manifest re-upsert reordered its category array instead of being a true no-op; merge_manifest_file silently dropped scalar top-level fields (e.g. defaultLocale) and aborted the whole merge on one malformed entry; validate_manifest ran unconditionally and could hard-fail unrelated pushes that never touch the manifest. Co-authored-by: Claude <noreply@anthropic.com> * @W-23651027: Enforce SFRA-requires-SFNext in verify-zip.yml CI validation (SalesforceCommerceCloud#73) Step 8 already validated presence-symmetry, unknown keys, and semver for storefrontSupport.sfnext/sfra, but never enforced that sfra is additive-only to sfnext. Add validate_sfra_requires_sfnext to root-manifest-utils.sh and call it against both the manifest entry and the extracted commerce-app.json, so a manifest.json edited directly (bypassing the Claude Code skills) can no longer merge an SFRA-only app. Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
|
@/home/runner/work/_temp/slack-marker.md |
shauryemahajanSF
left a comment
There was a problem hiding this comment.
Lets point this at the release/26.8 branch instead of main.
|
@/home/runner/work/_temp/slack-marker.md |
…merceCloud#88) Port the Avalara Tax CAP from main onto release/26.8 so 26.8 customers can install and use it through the CAP registry: - Add tax/avalara-tax/avalara-tax-v1.0.0.zip (identical bytes to main; SHA256 a54104de4c7072999107717d4f07a52ab13406361a207023dd0f5aaa61d8ff98). - Seed tax/avalara-tax/catalog.json with {latest: INIT/INIT, versions: []}, mirroring the pattern PR SalesforceCommerceCloud#85 used on main. update-catalog.yml populates it post-merge; a verbatim copy of main's populated catalog would fail verify-zip.yml Step 2 ("manifest version must not already exist in catalog.json"). - Insert the Avalara entry into commerce-apps-manifest/manifest.json's `tax` array between salesforce-flat-tax and custom-tax, matching main byte-for-byte. The 7891-byte commerce-apps-manifest/icons/avalara.png (CAP-root variant) was already present on release/26.8 at the same blob as main — no icon change is needed. Co-authored-by: Claude <noreply@anthropic.com>
…CommerceCloud#89) * CI: update catalog.json after ZIP merge * Remove non-icon images accidentally extracted from ZIP Drop circle-info-solid-min.png and ui-icons_444444_256x240.png, and revert avalara.png. Only catalog.json should change in this PR. --------- Co-authored-by: jbisaSF <100236257+jbisaSF@users.noreply.github.com> Co-authored-by: jbisa <jbisa@salesforce.com>
|
Hey Svetlana, thanks for the PR! Some things to consider:
Example of the performance stuff above are here: cds-shipping-v1.0.5.zip |
…greement (SalesforceCommerceCloud#71) (SalesforceCommerceCloud#93) An app may no longer declare SFRA support without also declaring SFNext support, closing the gap where SFRA-only apps were implicitly allowed. Also documents that every published app must be covered by an appropriate ISV partnership agreement with Salesforce. Co-authored-by: Jon Stahl <jonstahl@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
|
We should also include delivery estimates on PDP using the |
…INIT on new-app promotion (SalesforceCommerceCloud#95) (SalesforceCommerceCloud#96) Icon extraction in update-catalog.yml (and verify-zip.yml) used an unbounded find -name icons -print -quit, which could match a nested icons/ dir inside a bundled cartridge (e.g. BM static theme assets) instead of the CAP's own root-level icons/. Extract the lookup into a pure, tested find_cap_icons_dir() helper anchored two levels below the extraction root and use it everywhere. Also fix the promote-forward job seeding catalog.json with a concrete version during promotion of a brand-new app; it now writes the INIT template per the CONTRIBUTING.md contract and lets the target branch's own post-merge job populate the real version history. Cherry-picked from commerce-apps-testing@a12ceaf78e4d2fd257a19134f75a25bcea995185
Co-authored-by: jbisaSF <100236257+jbisaSF@users.noreply.github.com>
…ommerceCloud#117) Normalize regional locale filenames to BCP-47 dash form and keep validation and documentation aligned.
# 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
|
@/home/runner/work/_temp/slack-marker.md |
|
@/home/runner/work/_temp/slack-marker.md |
|
@svetlanakostadinova App looks good in shape, should be good to go in after these last comments are addressed: We shouldn't need to implement any storefront next UI components for shipping apps, the template already handles what we need. To get the template to display what we want, this app should
Take a look at the shipping option and order confirm UI that is already present in the template to see what fields they use. |
|
@/home/runner/work/_temp/slack-marker.md |
…loud/commerce-apps into add-zenkraft-shipping-v1.0.0 # Conflicts: # .claude/skills/package-app/SKILL.md # .github/scripts/promotion-utils.sh # .github/scripts/security-scan.sh # .github/scripts/test-promotion-utils.sh # .github/scripts/test-security-scan.sh # .github/scripts/validate-translations.sh # CONTRIBUTING.md # commerce-apps-manifest/manifest.json # 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 # tax/avalara-tax/catalog.json
|
@/home/runner/work/_temp/slack-marker.md |
|
@/home/runner/work/_temp/slack-marker.md |
|
@/home/runner/work/_temp/slack-marker.md |
|
@svetlanakostadinova We recently merged another app, so may be some slight conflicts. |
# Conflicts: # commerce-apps-manifest/manifest.json
d9a38a1
|
@/home/runner/work/_temp/slack-marker.md |
1 similar comment
|
@/home/runner/work/_temp/slack-marker.md |
f71dd35
into
SalesforceCommerceCloud:release/26.9
Commerce App Submission
App Name: zenkraft-shipping
Display Name: Zenrkaft Shipping
Domain: shipping
ISV/Vendor Name: Zenkraft
Version: 1.0.0
Type of Change
Architecture
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
{appName}-v{version}.zipcommerce-{appName}-app-v{version}/manifest.jsonincludes all required fields (id, name, description, iconName, domain, version, zip, sha256)commerce-{appName}-app-v{version}/icons/(CI extracts automatically)iconNamefield in root manifestcommerce-apps-manifest/translations/en-US.json(minimum requirement)catalog.jsonincluded for new apps only (with INIT values)catalog.json(CI handles this)"deprecated": trueto existing version incatalog.jsonVersion and Hash Validation
versioninmanifest.jsonmatchesversionincommerce-app.jsonzipfield inmanifest.jsonmatches actual ZIP filenamesha256inmanifest.jsonmatches computed hash of ZIP fileshasum -a 256 [path-to-zip]ZIP Content Validation
.DS_Store,__MACOSX,Thumbs.db, hidden files)tax/,domain/, etc.)commerce-app.json,README.md,app-configuration/tasksList.jsonDirectory Structure
{domain}/{appName}/where{appName}matches the "id" field in manifestcommerce-*-app-v*/) committed.DS_Store,Thumbs.db) committedValidation (if using Claude Code)
/validate-appskill/validate-impexskill (if app contains impex files)Impex Files (if applicable)
mode="delete"Testing
Additional Notes