Skip to content

Add Angular 21 + Spartacus 221121.15.1 storefront with Contentstack CMS connector - #1

Merged
Aravind-Kumar-cstk merged 11 commits into
mainfrom
storefront-scaffold
Aug 21, 2026
Merged

Aravind-Kumar-cstk merged 11 commits into
mainfrom
storefront-scaffold

Conversation

@Rushikesh-Argade-Stack

Copy link
Copy Markdown
Contributor

Summary

  • Fresh Angular 21 storefront scaffolded with SAP Composable Storefront (Spartacus 221121.15.1), wired to OCC base site electronics-spa
  • CMS layer driven by @contentstack/contentstack-spartacus-connector, pointed at a live, fully-seeded Contentstack stack (hybrid mode: Contentstack overrides homepage/nav/footer/product/category slots, OCC serves everything else and all commerce data)
  • Credentials (CS_API_KEY/CS_DELIVERY_TOKEN) are generated into src/environments/contentstack.environment.ts at build time from env vars via scripts/generate-contentstack-env.js (wired through npm's prestart/prebuild hooks) — nothing credential-bearing is committed; see .env.example
  • Verified end-to-end: homepage, /faq, product, and category pages all confirmed rendering live Contentstack content in a real browser

Test plan

  • npm run build succeeds
  • npm start renders homepage with Contentstack-sourced banners/carousel (images.contentstack.io assets confirmed in DOM)
  • /faq, /contact, /sale render Contentstack landing_page content
  • Product/category pages render Contentstack shared layout + live OCC commerce data
  • gitleaks + trufflehog scanned clean (0 leaks / 0 verified secrets) across full git history

Copilot AI lite review requested due to automatic review settings August 20, 2026 07:33
@Rushikesh-Argade-Stack
Rushikesh-Argade-Stack requested a review from a team as a code owner August 20, 2026 07:33
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR scaffolds a new Angular 21 + SAP Composable Storefront (Spartacus 221121.15.1) application and wires in a Contentstack-driven CMS layer (hybrid mode with OCC fallback), with build-time generation of a gitignored Contentstack environment file from env vars.

Changes:

  • Added Angular/Spartacus storefront bootstrap (standalone app config + Spartacus feature module composition).
  • Integrated Contentstack connector configuration and a prebuild/prestart env generator script.
  • Added global and feature SCSS imports plus project tooling configs (Angular CLI, TS configs, Prettier/EditorConfig, VS Code tasks).

Reviewed changes

Copilot reviewed 49 out of 54 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tsconfig.spec.json Adds spec TS config (extends base) with vitest globals type declarations.
tsconfig.json Defines base TypeScript + Angular compiler strictness and project references.
tsconfig.app.json Adds app TS config and excludes spec files from app compilation.
src/styles/spartacus/user.scss Imports Spartacus user feature styles.
src/styles/spartacus/storefinder.scss Imports storefinder styles plus required Bootstrap SCSS utilities.
src/styles/spartacus/product.scss Imports product styles plus required Bootstrap SCSS utilities.
src/styles/spartacus/order.scss Imports Spartacus order feature styles.
src/styles/spartacus/checkout.scss Imports checkout styles plus required Bootstrap SCSS utilities.
src/styles/spartacus/cart.scss Imports cart styles plus required Bootstrap SCSS utilities.
src/styles/spartacus/asm.scss Imports ASM feature styles.
src/styles.scss Sets global stylesheet import order (Spartacus core → Bootstrap copies → Spartacus index).
src/styles-config.scss Defines Spartacus style version variable.
src/main.ts Bootstraps the standalone Angular application with bootstrapApplication.
src/index.html Adds the base HTML shell for the Angular app.
src/app/spartacus/spartacus.module.ts Composes the top-level Spartacus module imports/exports.
src/app/spartacus/spartacus-features.module.ts Registers Spartacus core/storefront modules and feature toggles, plus feature modules.
src/app/spartacus/spartacus-configuration.module.ts Provides Spartacus configuration (layout/media/CMS providers, OCC/site context/i18n/features).
src/app/spartacus/features/user/user-feature.module.ts Configures lazy-loaded user account/profile feature modules + i18n resources.
src/app/spartacus/features/tracking/personalization-feature.module.ts Configures lazy-loaded personalization feature module.
src/app/spartacus/features/storefinder/store-finder-feature.module.ts Configures lazy-loaded store finder feature module + i18n resources.
src/app/spartacus/features/smartedit/smart-edit-feature.module.ts Configures lazy-loaded SmartEdit feature module and SmartEdit config placeholders.
src/app/spartacus/features/product/product-variants-feature.module.ts Configures lazy-loaded product variants feature module + i18n resources.
src/app/spartacus/features/product/product-image-zoom-feature.module.ts Configures lazy-loaded product image zoom feature module + i18n resources.
src/app/spartacus/features/order/order-feature.module.ts Configures lazy-loaded order feature module + i18n resources.
src/app/spartacus/features/contentstack/contentstack-feature.module.ts Adds Contentstack CMS connector configuration (hybrid CMS override with OCC fallback).
src/app/spartacus/features/checkout/checkout-feature.module.ts Configures lazy-loaded checkout feature module + i18n resources.
src/app/spartacus/features/cart/wish-list-feature.module.ts Configures wish list + add-to-wishlist feature modules + i18n resources.
src/app/spartacus/features/cart/cart-saved-cart-feature.module.ts Configures saved cart feature module + i18n resources.
src/app/spartacus/features/cart/cart-quick-order-feature.module.ts Configures quick order feature module + i18n resources.
src/app/spartacus/features/cart/cart-import-export-feature.module.ts Configures import/export feature module + i18n resources.
src/app/spartacus/features/cart/cart-base-feature.module.ts Configures base cart + mini cart + add-to-cart feature modules + i18n resources.
src/app/spartacus/features/asm/asm-feature.module.ts Configures ASM feature module + i18n resources.
src/app/spartacus/features/asm/asm-customer360-feature.module.ts Configures ASM Customer 360 feature module + i18n resources.
src/app/app.routes.ts Introduces an (currently empty) Angular Router route list.
src/app/app.module.ts Adds NgRx root + Spartacus AppRoutingModule and feature composition via SpartacusModule.
src/app/app.config.ts Configures standalone app providers (router, HttpClient, imported NgModule providers).
src/app/app.component.ts Declares the root standalone component that hosts StorefrontComponent.
src/app/app.component.spec.ts Adds basic unit tests for the root component.
src/app/app.component.scss Adds component stylesheet placeholder.
src/app/app.component.html Hosts the Spartacus storefront element.
scripts/generate-contentstack-env.js Generates src/environments/contentstack.environment.ts from env vars at build/start time.
README.md Documents setup, RBSC registry access, and Contentstack env generation.
package.json Defines Angular/Spartacus/Contentstack dependencies and npm scripts.
angular.json Configures Angular build/serve/test targets and global feature styles.
.vscode/tasks.json Adds VS Code tasks for npm start and npm test.
.vscode/mcp.json Configures Angular CLI MCP server for VS Code.
.vscode/launch.json Adds debug launch configs for serve/test.
.vscode/extensions.json Recommends Angular extension.
.prettierrc Adds Prettier configuration with Angular HTML parser override.
.gitignore Ignores build outputs, IDE artifacts, and generated Contentstack env + .env files.
.env.example Provides example Contentstack environment variables for local development.
.editorconfig Adds formatting conventions across file types.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +17 to +22
it('should render title', async () => {
const fixture = TestBed.createComponent(App);
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, electronics-spa');
});
Comment thread package.json
"@angular/platform-browser": "^21.2.0",
"@angular/router": "^21.2.0",
"@angular/service-worker": "^21.2.14",
"@contentstack/contentstack-spartacus-connector": "file:../../contentstack-spartacus-connector/dist/contentstack-contentstack-spartacus-connector-0.1.0.tgz",
Comment thread package.json
Comment on lines +4 to +13
"scripts": {
"ng": "ng",
"generate-env": "node scripts/generate-contentstack-env.js",
"prestart": "npm run generate-env",
"start": "ng serve",
"prebuild": "npm run generate-env",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
Comment on lines +24 to +29
provideConfig(<OccConfig>{
backend: {
occ: {
baseUrl: 'https://40.76.109.9:9002',
},
},
Comment on lines +36 to +47
const content = `import { Region } from '@contentstack/delivery-sdk';

// AUTO-GENERATED by scripts/generate-contentstack-env.js — do not edit by hand,
// your changes will be overwritten on the next build. Edit .env instead.
export const contentstackDelivery = {
apiKey: '${process.env.CS_API_KEY}',
deliveryToken: '${process.env.CS_DELIVERY_TOKEN}',
environment: '${environment}',
region: Region.${region},
livePreview: ${livePreview},
};
`;
Comment thread README.md
## Development server

```bash
ng serve
Copilot AI review requested due to automatic review settings August 20, 2026 09:04
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 53 out of 58 changed files in this pull request and generated 2 comments.

Suppressed comments (7)

src/app/app.component.spec.ts:21

  • This test asserts an h1 with "Hello, electronics-spa", but the component template only renders <cx-storefront>, so the assertion will always fail.
  it('should render title', async () => {
    const fixture = TestBed.createComponent(App);
    await fixture.whenStable();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, electronics-spa');

package.json:13

  • npm test runs ng test without generating src/environments/contentstack.environment.ts, but the app imports that file (and the src/environments folder is not present in the repo). This will fail compilation unless the env generator runs first.
    "prebuild": "npm run generate-env",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },

scripts/generate-contentstack-env.js:45

  • The env generator interpolates raw env var values into a TS file using single quotes. If an env var contains a quote, backslash, or newline, the generated TypeScript becomes invalid (and can be code-injected). Use JSON.stringify to safely emit string literals.
  apiKey: '${process.env.CS_API_KEY}',
  deliveryToken: '${process.env.CS_DELIVERY_TOKEN}',
  environment: '${environment}',
  region: Region.${region},
  livePreview: ${livePreview},

src/app/spartacus/spartacus-configuration.module.ts:28

  • The OCC backend base URL is hardcoded to a specific IP. This makes local/dev/prod configuration difficult and risks accidentally pointing builds at the wrong backend. Prefer reading this from an Angular environment/config file or an injected runtime config.
    .github/workflows/issues-jira.yml:21
  • Pin GitHub Actions to a tag or (preferably) a commit SHA rather than @master to avoid supply-chain risk from unexpected upstream changes.
        uses: atlassian/gajira-create@master

package.json:24

  • The Contentstack connector dependency points to a local tarball path outside this repository (file:../../...). Fresh clones/CI installs will fail unless that tarball exists at the same relative path. Use a published package version or vendor the tarball inside this repo.
    "@contentstack/contentstack-spartacus-connector": "file:../../contentstack-spartacus-connector/dist/contentstack-contentstack-spartacus-connector-0.1.0.tgz",

README.md:57

  • The README instructs running ng serve, but that bypasses the prestart hook that generates src/environments/contentstack.environment.ts. For a fresh clone this will fail unless you run the generator manually.
```bash
ng serve
</details>

Comment thread src/app/app.component.ts
Comment on lines +5 to +8
selector: 'app-root',
imports: [StorefrontComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
Comment thread .github/workflows/issues-jira.yml Outdated
steps:

- name: Login to Jira
uses: atlassian/gajira-login@master
Verifies the connector is actually wired end-to-end (not just that the app
builds): Delivery API calls fire and return real entries, a CS-owned slot
renders the asset Contentstack returned rather than falling back silently,
Live Preview tags stay off the public DOM, and locale switches re-fetch the
mapped locale's content.
Copilot AI review requested due to automatic review settings August 21, 2026 05:22
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 60 out of 65 changed files in this pull request and generated no new comments.

Suppressed comments (5)

src/app/app.component.ts:9

  • bootstrapApplication() and the component metadata use imports, which requires a standalone component. Without standalone: true, Angular will error that imports is only valid on standalone components and the app won't compile.
@Component({
  selector: 'app-root',
  imports: [StorefrontComponent],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})

src/app/app.component.spec.ts:21

  • This spec asserts an <h1> with "Hello, electronics-spa", but the component template only renders <cx-storefront> so this test will fail.
  it('should render title', async () => {
    const fixture = TestBed.createComponent(App);
    await fixture.whenStable();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, electronics-spa');

.github/workflows/issues-jira.yml:25

  • Use consistent casing for the platform name: "GitHub" (not "Github").
          summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }}

package.json:26

  • This dependency points to a tarball outside the repository (file:../../contentstack-spartacus-connector/...). A clean clone of this repo will fail npm install unless the user happens to have that sibling path available.
    "@contentstack/contentstack-spartacus-connector": "file:../../contentstack-spartacus-connector/dist/contentstack-contentstack-spartacus-connector-0.1.0.tgz",

.github/workflows/issues-jira.yml:1

  • Use consistent casing for the platform name: "GitHub" (not "Github").

This issue also appears on line 25 of the same file.

name: Create Jira Ticket for Github Issue

Copilot AI review requested due to automatic review settings August 21, 2026 10:04
Updated CODEOWNERS to simplify workflow ownership.
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

1 similar comment
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

@Aravind-Kumar-cstk
Aravind-Kumar-cstk merged commit 6108b9d into main Aug 21, 2026
4 checks passed
@Aravind-Kumar-cstk
Aravind-Kumar-cstk deleted the storefront-scaffold branch August 21, 2026 10:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 59 out of 64 changed files in this pull request and generated no new comments.

Suppressed comments (9)

src/app/app.component.ts:9

  • @Component uses the imports field (standalone-only API) and the app is bootstrapped with bootstrapApplication, but the component isn't marked standalone: true. This will fail to compile/run as a standalone app.
@Component({
  selector: 'app-root',
  imports: [StorefrontComponent],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})

src/app/app.component.spec.ts:22

  • This spec asserts an h1 with "Hello, electronics-spa", but the component template only renders <cx-storefront> so the test will always fail.
  it('should render title', async () => {
    const fixture = TestBed.createComponent(App);
    await fixture.whenStable();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, electronics-spa');
  });

scripts/generate-contentstack-env.js:46

  • The generated TS file interpolates env var values directly into single-quoted strings. If any value contains ', newlines, or backslashes, the output becomes invalid TypeScript (and it also enables accidental code injection via env vars). Serialize values safely when generating code.
const content = `import { Region } from '@contentstack/delivery-sdk';

// AUTO-GENERATED by scripts/generate-contentstack-env.js — do not edit by hand,
// your changes will be overwritten on the next build. Edit .env instead.
export const contentstackDelivery = {
  apiKey: '${process.env.CS_API_KEY}',
  deliveryToken: '${process.env.CS_DELIVERY_TOKEN}',
  environment: '${environment}',
  region: Region.${region},
  livePreview: ${livePreview},
};

package.json:27

  • @contentstack/contentstack-spartacus-connector is referenced via a file:../../... tarball path outside this repo. Fresh clones/CI won't have that tarball, so npm install will fail unless the developer happens to have the sibling repo layout.
    "@angular/router": "^21.2.0",
    "@angular/service-worker": "^21.2.14",
    "@contentstack/contentstack-spartacus-connector": "file:../../contentstack-spartacus-connector/dist/contentstack-contentstack-spartacus-connector-0.1.0.tgz",
    "@contentstack/delivery-sdk": "^4.11.2",

src/app/spartacus/spartacus-configuration.module.ts:29

  • The OCC baseUrl is hard-coded to a specific IP address. That makes the app non-portable and forces everyone to use the same backend (and a potentially self-signed cert). Prefer reading this from an environment-specific config (Angular environment file / runtime config / env generator).
    package.json:14
  • The env generator is only wired into prestart/prebuild. Running npm test or npm run e2e directly can fail because src/environments/contentstack.environment.ts won't exist yet (it is gitignored but imported by app code). Consider adding pretest (and pree2e if you want npm run e2e to be runnable without relying on the Playwright webServer hook).
    "prestart": "npm run generate-env",
    "start": "ng serve",
    "prebuild": "npm run generate-env",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "e2e": "playwright test",
    "e2e:ui": "playwright test --ui"

package.json:62

  • @angular/compiler is declared in both dependencies and devDependencies (with different versions). This can produce non-deterministic installs and hard-to-debug Angular version skew; keep it in a single section and ensure versions match the rest of @angular/*.
  "devDependencies": {
    "@angular-devkit/core": "^21.2.13",
    "@angular-devkit/schematics": "^21.2.13",
    "@angular/build": "^21.2.19",
    "@angular/cli": "^21.2.19",
    "@angular/compiler": "^21.2.14",
    "@angular/compiler-cli": "^21.2.0",
    "@playwright/test": "^1.62.1",

e2e/README.md:25

  • This README links to ../../../../contentstack-spartacus-connector/..., but that path doesn't exist in this repository so the link will be broken on GitHub. Use an absolute link to the connector repo instead.
**Known gap, not fixed here:** `scripts/generate-contentstack-env.js` never writes a
`previewToken` into `contentstack.environment.ts`, so `CS_LIVE_PREVIEW=true` alone can't
actually turn Live Preview on ([contentstack-client.service.ts](../../../../contentstack-spartacus-connector/src/client/contentstack-client.service.ts)
requires `livePreview` + `previewToken` + dev mode together). The live-preview spec is written
against that reality — it only asserts the on-state when explicitly told to expect it.

src/app/spartacus/features/contentstack/contentstack-feature.module.ts:14

  • This module comment references GETTING_STARTED.md and CONTENT-MODEL.md, but those files aren't present in this repo, so new users will hit dead links. Either add the docs or update the references to existing documentation (e.g., the root README or the connector repo docs).

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.

3 participants