Skip to content

Refactor CdpPageView tests to update event imports #311

Refactor CdpPageView tests to update event imports

Refactor CdpPageView tests to update event imports #311

Workflow file for this run

name: PR Validation for DMZ Branch
on:
pull_request:
branches: [dmz]
env:
NODE_VERSION: "22.11.0"
jobs:
pr-validation:
name: Validate Pull Request
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout PR
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch all branches
run: |
git fetch origin main
git fetch origin dmz
- name: Check if PR is based on latest main
id: base-check
run: |
echo "Checking if PR branch is up-to-date with main..."
# Get the merge base between PR branch and main
MERGE_BASE=$(git merge-base HEAD origin/main)
MAIN_HEAD=$(git rev-parse origin/main)
echo "Merge base: $MERGE_BASE"
echo "Main HEAD: $MAIN_HEAD"
if [ "$MERGE_BASE" != "$MAIN_HEAD" ]; then
echo "❌ ERROR: This PR branch is not based on the latest main branch."
echo ""
echo "Your branch was created from an outdated version of main."
echo "This will cause duplicate commits to appear in your PR."
echo ""
echo "To fix this, rebase your branch onto the latest main:"
echo ""
echo " git fetch origin main"
echo " git rebase origin/main"
echo " git push --force-with-lease"
echo ""
echo "base-check-passed=false" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ PR branch is based on the latest main branch"
echo "base-check-passed=true" >> $GITHUB_OUTPUT
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Detect changed starters
id: detect-changes
run: |
echo "Detecting changed starter applications..."
# For pull_request events, use PR base and head SHAs (not the merge commit)
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
echo "Base SHA: $BASE_SHA"
echo "Head SHA: $HEAD_SHA"
# Get list of changed files between PR base and PR head
CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
echo "Changed files:"
echo "$CHANGED_FILES"
# Detect which starters have changes
CHANGED_STARTERS=""
if echo "$CHANGED_FILES" | grep -q "^examples/kit-nextjs-skate-park/"; then
CHANGED_STARTERS="$CHANGED_STARTERS kit-nextjs-skate-park"
fi
if echo "$CHANGED_FILES" | grep -q "^examples/kit-nextjs-article-starter/"; then
CHANGED_STARTERS="$CHANGED_STARTERS kit-nextjs-article-starter"
fi
if echo "$CHANGED_FILES" | grep -q "^examples/kit-nextjs-location-finder/"; then
CHANGED_STARTERS="$CHANGED_STARTERS kit-nextjs-location-finder"
fi
if echo "$CHANGED_FILES" | grep -q "^examples/kit-nextjs-product-listing/"; then
CHANGED_STARTERS="$CHANGED_STARTERS kit-nextjs-product-listing"
fi
# If no specific starter changes detected, check for global changes
if [ -z "$CHANGED_STARTERS" ]; then
if echo "$CHANGED_FILES" | grep -q "^xmcloud.build.json\|^\.github/\|^README.md\|^CONTRIBUTING.md"; then
echo "Global changes detected, validating all starters"
CHANGED_STARTERS="kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing"
fi
fi
echo "Changed starters: $CHANGED_STARTERS"
echo "changed-starters=$CHANGED_STARTERS" >> $GITHUB_OUTPUT
- name: Install dependencies for all starters
run: |
echo "Installing dependencies for all starters..."
# Install dependencies for all enabled starters
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "Installing dependencies for $starter..."
cd "examples/$starter"
npm ci
cd ../..
fi
done
- name: Generate Sitecore files for all starters
run: |
echo "Generating Sitecore configuration files..."
# Generate files for all enabled starters
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "Generating files for $starter..."
cd "examples/$starter"
# Ensure .sitecore directory exists
mkdir -p .sitecore
# Try to generate files with Sitecore tools, fallback to minimal files if credentials are missing
if npm run sitecore-tools:generate-map 2>/dev/null; then
echo "✅ Sitecore files generated successfully for $starter"
else
echo "⚠️ Sitecore tools failed (likely missing credentials), creating minimal files for $starter"
# Create minimal sites.json
echo '[{"name":"basic","hostName":"*","language":"en"}]' > .sitecore/sites.json
# Create minimal metadata.json
echo '{"packages":{"@sitecore-content-sdk/core":"1.1.0","@sitecore-content-sdk/nextjs":"1.1.0"}}' > .sitecore/metadata.json
# Create minimal component-map.ts
echo 'export default new Map();' > .sitecore/component-map.ts
# Create minimal import-map.ts
echo 'export default [];' > .sitecore/import-map.ts
fi
# Always ensure required files exist (they may not be generated by tools)
if [ ! -f ".sitecore/sites.json" ]; then
echo '[{"name":"basic","hostName":"*","language":"en"}]' > .sitecore/sites.json
fi
if [ ! -f ".sitecore/metadata.json" ]; then
echo '{"packages":{"@sitecore-content-sdk/core":"1.1.0","@sitecore-content-sdk/nextjs":"1.1.0"}}' > .sitecore/metadata.json
fi
if [ ! -f ".sitecore/import-map.server.ts" ]; then
echo 'export default [] as any;' > .sitecore/import-map.server.ts
fi
if [ ! -f ".sitecore/import-map.client.ts" ]; then
echo 'export default [] as any;' > .sitecore/import-map.client.ts
fi
# Verify files were created
echo "Created Sitecore files:"
ls -la .sitecore/ || echo "Warning: .sitecore directory listing failed"
cd ../..
fi
done
- name: Lint and format check for all starters
run: |
echo "Running linting and formatting checks for all starters..."
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "=================================="
echo "Checking examples/$starter"
echo "=================================="
cd "examples/$starter"
# Run linting - WARNING ONLY (does not fail the workflow)
echo "Running lint for $starter..."
if ! npm run lint; then
echo "⚠️ WARNING: Linting issues found in $starter"
echo "::warning::Linting found issues in $starter (non-blocking)"
# Continue without failing - lint check is a warning only for now
else
echo "✅ Linting passed for $starter"
fi
# Check formatting (only if format:check script exists)
# WARNING ONLY - does not fail the workflow
if grep -q '"format:check"' package.json 2>/dev/null; then
echo "Running format check for $starter..."
if ! npm run format:check; then
echo "⚠️ WARNING: Formatting issues found in $starter"
echo "Run 'npm run prettier' to fix formatting issues"
echo "::warning::Formatting check found issues in $starter (non-blocking)"
# Continue without failing - format check is a warning only
else
echo "✅ Formatting check passed for $starter"
fi
else
echo "⏭️ Skipping format check (no format:check script found in package.json)"
fi
cd ../..
fi
done
- name: Type checking for all starters
run: |
echo "Running TypeScript type checking for all starters..."
# WARNING ONLY - does not fail the workflow
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "Type checking $starter..."
cd "examples/$starter"
# Check if type-check script exists
if grep -q '"type-check"' package.json 2>/dev/null; then
if npm run type-check; then
echo "✅ Type checking passed for $starter"
else
echo "⚠️ WARNING: Type checking issues found in $starter"
echo "::warning::Type checking found issues in $starter (non-blocking)"
# Continue without failing - type check is a warning only for now
fi
else
echo "⏭️ Skipping type check (no type-check script found in package.json)"
fi
cd ../..
fi
done
- name: Check if running in upstream repo
id: repo-check
run: |
# Check if this is the upstream Sitecore repo or a fork
if [ "${{ github.repository_owner }}" = "sitecore" ] || [ "${{ github.event.pull_request.head.repo.full_name }}" = "${{ github.repository }}" ]; then
echo "is-upstream=true" >> $GITHUB_OUTPUT
echo "✅ Running in upstream repo or same-repo PR - full build will run"
else
echo "is-upstream=false" >> $GITHUB_OUTPUT
echo "ℹ️ Running in fork - Sitecore build will be skipped (no XM Cloud credentials)"
fi
- name: Build all starters (Full - Upstream Only)
if: steps.repo-check.outputs.is-upstream == 'true'
env:
# Sitecore Edge API Configuration
NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME: ${{ secrets.NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME }}
SITECORE_EDGE_CONTEXT_ID: ${{ secrets.SITECORE_EDGE_CONTEXT_ID }}
NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID: ${{ secrets.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID }}
# Sitecore Configuration
NEXT_PUBLIC_DEFAULT_SITE_NAME: ${{ vars.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'basic' }}
SITECORE_EDITING_SECRET: ${{ secrets.SITECORE_EDITING_SECRET }}
# Additional Sitecore Environment Variables
NEXT_PUBLIC_SITECORE_API_KEY: ${{ secrets.NEXT_PUBLIC_SITECORE_API_KEY }}
NEXT_PUBLIC_SITECORE_API_HOST: ${{ secrets.NEXT_PUBLIC_SITECORE_API_HOST }}
NEXT_PUBLIC_DEFAULT_LANGUAGE: ${{ vars.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en' }}
NEXT_PUBLIC_PERSONALIZE_SCOPE: ${{ vars.NEXT_PUBLIC_PERSONALIZE_SCOPE }}
PERSONALIZE_MIDDLEWARE_EDGE_TIMEOUT: ${{ vars.PERSONALIZE_MIDDLEWARE_EDGE_TIMEOUT || '1000' }}
run: |
set -e # Exit immediately if any command fails
echo "Building all starters with full Sitecore integration..."
echo "Sitecore Environment Variables:"
echo " NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME: ${NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME:+[SET]}"
echo " SITECORE_EDGE_CONTEXT_ID: ${SITECORE_EDGE_CONTEXT_ID:+[SET]}"
echo " NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID: ${NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID:+[SET]}"
echo " NEXT_PUBLIC_DEFAULT_SITE_NAME: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
echo " SITECORE_EDITING_SECRET: ${SITECORE_EDITING_SECRET:+[SET]}"
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "=================================="
echo "Building $starter"
echo "=================================="
cd "examples/$starter"
if npm run build; then
echo "✅ Build successful for $starter"
else
echo "❌ Build failed for $starter"
echo "::error::Build failed for $starter"
exit 1
fi
cd ../..
fi
done
- name: TypeScript compilation check for forks (No XM Cloud credentials)
if: steps.repo-check.outputs.is-upstream != 'true'
run: |
set -e # Exit immediately if any command fails
echo "⚠️ =============================================="
echo "⚠️ FORK CI - RUNNING TYPESCRIPT COMPILATION CHECK"
echo "⚠️ =============================================="
echo ""
echo "The full Next.js build requires a real XM Cloud Edge connection"
echo "which is not available in fork CI (secrets are not shared)."
echo ""
echo "Running TypeScript compilation to validate code correctness..."
echo ""
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "=================================="
echo "TypeScript compile check: $starter"
echo "=================================="
cd "examples/$starter"
# Run TypeScript compilation without emitting files
# This validates all imports, types, and syntax
echo "Running tsc --noEmit..."
if npx tsc --noEmit; then
echo "✅ TypeScript compilation successful for $starter"
else
echo "❌ TypeScript compilation failed for $starter"
echo "::error::TypeScript compilation failed for $starter"
exit 1
fi
cd ../..
fi
done
echo ""
echo "✅ TypeScript compilation check passed for all starters"
echo ""
echo "ℹ️ Note: Full Next.js build with Sitecore integration will run"
echo " when this PR is reviewed in the upstream repository."
- name: Run tests with coverage for all starters
env:
# Provide mock values for tests (in case they need Sitecore config)
SITECORE_EDGE_CONTEXT_ID: "mock-context-id-for-ci-tests"
NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID: "mock-context-id-for-ci-tests"
NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME: "https://edge.sitecorecloud.io"
NEXT_PUBLIC_DEFAULT_SITE_NAME: "basic"
NEXT_PUBLIC_DEFAULT_LANGUAGE: "en"
SITECORE_EDITING_SECRET: "mock-editing-secret-for-ci-tests"
run: |
set -e # Exit immediately if any command fails
echo "Running tests with coverage for all starters..."
# Test all enabled starters
for starter in kit-nextjs-skate-park kit-nextjs-article-starter kit-nextjs-location-finder kit-nextjs-product-listing; do
if [ -d "examples/$starter" ]; then
echo "=================================="
echo "Testing $starter"
echo "=================================="
cd "examples/$starter"
# Check if test:coverage script exists
if grep -q '"test:coverage:unit"' package.json; then
echo "Running tests with coverage for $starter..."
if ! npm run test:coverage:unit; then
echo "❌ Tests failed for $starter"
echo "::error::Tests failed for $starter"
exit 1
fi
echo "✅ Tests passed for $starter"
else
echo "❌ No test:coverage:unit script found for $starter - tests are mandatory"
echo "::error::No test:coverage:unit script found for $starter"
exit 1
fi
cd ../..
fi
done
- name: Comment PR with results
if: always()
uses: actions/github-script@v7
with:
script: |
try {
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('## 🔍 PR Validation Results')
);
const status = '${{ job.status }}' === 'success' ? '✅ **PASSED**' : '❌ **FAILED**';
const emoji = '${{ job.status }}' === 'success' ? '✅' : '❌';
const isUpstream = '${{ steps.repo-check.outputs.is-upstream }}' === 'true';
const buildType = isUpstream ? '✅ Full build (with Sitecore integration)' : '⚠️ Next.js-only build (fork - no XM Cloud credentials)';
const body = `## 🔍 PR Validation Results
${emoji} **Status:** ${status}
**Base Branch Check:** ${'${{ steps.base-check.outputs.base-check-passed }}' === 'true' ? '✅ Based on latest main' : '❌ Not based on latest main - rebase required'}
**Build Type:** ${buildType}
**Validated Starters:** kit-nextjs-skate-park, kit-nextjs-article-starter, kit-nextjs-location-finder, kit-nextjs-product-listing
**Checks Performed:**
- ✅ Linting and formatting
- ✅ TypeScript type checking
- ${isUpstream ? '✅ Full build verification (Sitecore + Next.js)' : '✅ TypeScript compilation check (tsc --noEmit)'}
- ✅ Unit tests with coverage (npm run test:coverage:unit)
${!isUpstream ? '\n **Note:** Full Next.js build requires XM Cloud credentials and will run in upstream CI.' : ''}
**Next Steps:**
${'${{ job.status }}' === 'success' ?
(isUpstream ?
'- ✅ PR is ready for review and merge to dmz branch\n- After merge, the DMZ validation workflow will run as final gate\n- If DMZ validation passes, dmz can be manually merged to main using a merge commit' :
'- ✅ Fork CI passed - PR is ready for review\n- ⚠️ Full Sitecore build validation will run when PR is created to upstream repo\n- After upstream CI passes, PR can be merged to dmz branch'
) :
'- ❌ Please fix the issues above before merging\n- If not based on latest main: `git fetch origin main && git rebase origin/main && git push --force-with-lease`\n- If formatting issues: Run `npm run prettier`\n- Check the build logs for specific errors'
}
---
*This comment will be updated on each validation run*`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
} catch (error) {
// Handle permission errors gracefully (e.g., PRs from forks)
if (error.status === 403 || error.status === 404) {
console.log('⚠️ Unable to comment on PR (may be from a fork or insufficient permissions). Validation results are still available in the workflow logs.');
console.log('Validation Status:', '${{ job.status }}');
} else {
throw error;
}
}