Skip to content

Storefront hardening #13026

Storefront hardening

Storefront hardening #13026

Workflow file for this run

name: CI
on:
pull_request:
push:
branches:
- master
- staging
- "dev/*"
- "fix/*"
paths-ignore:
- "**.md"
- "**.txt"
- "LICENSE"
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CI: true
MONGOMS_VERSION: 8.0.4
MONGOMS_DOWNLOAD_DIR: /home/runner/.cache/mongodb-binaries
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_REMOTE_CACHE_TIMEOUT: 120
SHOPIFY_API_KEY: ${{ secrets.SHOPIFY_API_KEY }}
SHOPIFY_API_SECRET_KEY: ${{ secrets.SHOPIFY_API_SECRET_KEY }}
AUTH_SECRET: "development-secret"
AUTH_TRUST_HOST: "true"
EDGE_CONFIG: ${{ secrets.EDGE_CONFIG }}
ADMIN_DOMAIN: ${{ vars.ADMIN_DOMAIN }}
SERVICE_DOMAIN: ${{ vars.SERVICE_DOMAIN }}
LANDING_DOMAIN: ${{ vars.LANDING_DOMAIN }}
PAYLOAD_SECRET: ${{ secrets.PAYLOAD_SECRET }}
STOREFRONT_PREVIEW_SECRET: "development-secret"
VERCEL_AUTOMATION_BYPASS_SECRET: "development-secret"
NEXT_PUBLIC_DOCS_BASE_PATH: "/commerce"
NEXT_PUBLIC_DOCS_CANONICAL_URL: "https://filiphsps.github.io/commerce"
jobs:
lint:
name: 📋 Lint
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6
- name: 🚀 Bootstrap
id: bootstrap
uses: ./.github/common/bootstrap
with:
turbo-cache: "false"
- name: 📋 Lint
run: pnpm run lint
- name: 💾 Save bootstrap caches
if: always()
uses: ./.github/common/bootstrap-save
with:
node-modules-cache-hit: ${{ steps.bootstrap.outputs.node-modules-cache-hit }}
mongo-binary-cache-hit: ${{ steps.bootstrap.outputs.mongo-binary-cache-hit }}
save-node-modules: 'true'
typecheck:
name: ✅ Typecheck
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6
- name: 🚀 Bootstrap
id: bootstrap
uses: ./.github/common/bootstrap
- name: ✨ Generate
run: pnpm run generate
- name: 🔨 Build Packages
run: pnpm run build:packages
- name: ✅ Typecheck
run: pnpm run typecheck
- name: 💾 Save bootstrap caches
if: always()
uses: ./.github/common/bootstrap-save
with:
node-modules-cache-hit: ${{ steps.bootstrap.outputs.node-modules-cache-hit }}
turbo-cache-hit: ${{ steps.bootstrap.outputs.turbo-cache-hit }}
mongo-binary-cache-hit: ${{ steps.bootstrap.outputs.mongo-binary-cache-hit }}
test:
name: 🧪 Test
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6
- name: 🚀 Bootstrap
id: bootstrap
uses: ./.github/common/bootstrap
- name: ✨ Generate
run: pnpm run generate
- name: 🔨 Build Packages
run: pnpm run build:packages
- name: 🧪 Test
run: pnpm run test
- name: 🦺 Report Coverage to GitHub
if: ${{ !cancelled() && hashFiles('coverage/coverage-summary.json') != '' }}
uses: davelosert/vitest-coverage-report-action@v2.12
- name: 🦺 Codecov Coverage Reports
if: ${{ !cancelled() && hashFiles('coverage/coverage-final.json') != '' }}
uses: codecov/codecov-action@v6
with:
files: ./coverage/coverage-final.json
flags: unit
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: 🦺 Codecov Test Results
if: ${{ !cancelled() && hashFiles('junit.xml') != '' }}
uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./junit.xml
report_type: test_results
flags: unit
- name: 💾 Save bootstrap caches
if: always()
uses: ./.github/common/bootstrap-save
with:
node-modules-cache-hit: ${{ steps.bootstrap.outputs.node-modules-cache-hit }}
turbo-cache-hit: ${{ steps.bootstrap.outputs.turbo-cache-hit }}
mongo-binary-cache-hit: ${{ steps.bootstrap.outputs.mongo-binary-cache-hit }}
save-mongo-binary: 'true'
build:
name: 🔨 Build
timeout-minutes: 25
runs-on: ubuntu-latest
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6
- name: 🚀 Bootstrap
id: bootstrap
uses: ./.github/common/bootstrap
- name: 💾 Restore Next.js build cache
id: cache-nextjs
uses: actions/cache/restore@v5
with:
path: |
apps/*/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-
- name: 🔨 Build All
run: pnpm run build
- name: 📦 Upload app builds
uses: actions/upload-artifact@v7
with:
name: app-builds
path: |
apps/*/.next
!apps/*/.next/cache
!apps/*/.next/dev
!apps/*/.next/types
!apps/*/.next/diagnostics
packages/*/dist
retention-days: 1
include-hidden-files: true
- name: 💾 Save Next.js build cache
if: always() && steps.cache-nextjs.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
with:
path: |
apps/*/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ github.sha }}
- name: 💾 Save bootstrap caches
if: always()
uses: ./.github/common/bootstrap-save
with:
node-modules-cache-hit: ${{ steps.bootstrap.outputs.node-modules-cache-hit }}
turbo-cache-hit: ${{ steps.bootstrap.outputs.turbo-cache-hit }}
mongo-binary-cache-hit: ${{ steps.bootstrap.outputs.mongo-binary-cache-hit }}
save-turbo: 'true'
e2e:
name: 🎭 E2E
needs: build
timeout-minutes: 60
runs-on: ubuntu-latest
continue-on-error: true
if: false
strategy:
fail-fast: false
matrix:
app: [storefront, admin]
env:
NODE_V8_COVERAGE: ${{ github.workspace }}/coverage/e2e-raw
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6
- name: 🚀 Bootstrap
id: bootstrap
uses: ./.github/common/bootstrap
with:
turbo-cache: "false"
- name: 📥 Download app builds
uses: actions/download-artifact@v8
with:
name: app-builds
path: .
- name: 💾 Restore Playwright browsers
id: cache-playwright
uses: actions/cache/restore@v5
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ github.head_ref || github.ref_name }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-playwright-${{ github.head_ref || github.ref_name }}-
${{ runner.os }}-playwright-master-
${{ runner.os }}-playwright-
- name: 🎭 Install Playwright browsers (cache miss)
if: steps.cache-playwright.outputs.cache-hit != 'true'
run: pnpm --filter @nordcom/commerce-${{ matrix.app }} exec playwright install --with-deps chromium
- name: 🎭 Install Playwright system deps (cache hit)
if: steps.cache-playwright.outputs.cache-hit == 'true'
run: pnpm --filter @nordcom/commerce-${{ matrix.app }} exec playwright install-deps chromium
- name: 🧪 Run E2E Tests
run: pnpm test:e2e --filter @nordcom/commerce-${{ matrix.app }}
- name: 🦺 Convert V8 Coverage to Codecov Format
if: ${{ !cancelled() }}
run: |
pnpm dlx c8@10 report \
--reporter=json \
--reporter=lcov \
--reports-dir=./coverage/e2e \
--src=apps/${{ matrix.app }} \
--include='apps/${{ matrix.app }}/src/**' \
--exclude='**/*.d.ts' \
--exclude='**/*.config.*' \
--exclude='**/.next/**' \
--exclude='apps/*/e2e/**' \
|| echo "c8 report exited non-zero (likely no coverage emitted); continuing"
- name: 🦺 Codecov E2E Coverage
if: ${{ !cancelled() && hashFiles('coverage/e2e/coverage-final.json') != '' }}
uses: codecov/codecov-action@v6
with:
files: ./coverage/e2e/coverage-final.json,./coverage/e2e/lcov.info
flags: e2e,e2e-${{ matrix.app }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: 📦 Upload Report on Failure
if: failure()
uses: actions/upload-artifact@v7
with:
name: playwright-report-${{ matrix.app }}
path: apps/${{ matrix.app }}/playwright-report/
retention-days: 7
- name: 💾 Save Playwright browsers
if: always() && matrix.app == 'storefront' && steps.cache-playwright.outputs.cache-hit != 'true'
uses: actions/cache/save@v5
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ github.head_ref || github.ref_name }}-${{ hashFiles('pnpm-lock.yaml') }}
- name: 💾 Save bootstrap caches
if: always()
uses: ./.github/common/bootstrap-save
with:
node-modules-cache-hit: ${{ steps.bootstrap.outputs.node-modules-cache-hit }}
mongo-binary-cache-hit: ${{ steps.bootstrap.outputs.mongo-binary-cache-hit }}
cleanup-artifacts:
name: 🧹 Cleanup
needs: e2e
if: always() && needs.e2e.result != 'skipped'
timeout-minutes: 5
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- name: 🧹 Delete `app-builds` artifact
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}
run: |
set -euo pipefail
ids=$(gh api "repos/$REPO/actions/runs/$RUN_ID/artifacts" --jq '.artifacts[] | select(.name == "app-builds") | .id')
if [ -z "$ids" ]; then
echo "No app-builds artifact found; nothing to delete."
exit 0
fi
for id in $ids; do
echo "Deleting artifact $id"
gh api -X DELETE "repos/$REPO/actions/artifacts/$id"
done
dispatch:
name: 🗣️ Dispatch
needs: [lint, typecheck, test, build, e2e]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: 🕶️ Checkout repository
uses: actions/checkout@v6