Skip to content

chore: add healthcheck commands to Dockerfiles for improved container… #107

chore: add healthcheck commands to Dockerfiles for improved container…

chore: add healthcheck commands to Dockerfiles for improved container… #107

name: DMZ Branch Validation
permissions:
contents: read
on:
push:
branches: [dmz]
env:
NODE_VERSION: "22.11.0"
jobs:
validate-dmz:
name: Validate DMZ Branch
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Validate XM Cloud credentials
id: credential-check
run: |
echo "=========================================="
echo "πŸ” Validating XM Cloud Credentials"
echo "=========================================="
echo ""
echo "Repository: ${{ github.repository }}"
echo "Event: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo ""
MISSING_CREDENTIALS=""
CREDENTIALS_OK=true
# Check required secrets
if [ -z "${{ secrets.SITECORE_EDGE_URL }}" ]; then
echo "❌ SITECORE_EDGE_URL is missing"
MISSING_CREDENTIALS="$MISSING_CREDENTIALS SITECORE_EDGE_URL"
CREDENTIALS_OK=false
else
echo "βœ… SITECORE_EDGE_URL is set"
fi
if [ -z "${{ secrets.SITECORE_EDGE_CONTEXT_ID }}" ]; then
echo "❌ SITECORE_EDGE_CONTEXT_ID is missing"
MISSING_CREDENTIALS="$MISSING_CREDENTIALS SITECORE_EDGE_CONTEXT_ID"
CREDENTIALS_OK=false
else
echo "βœ… SITECORE_EDGE_CONTEXT_ID is set"
fi
if [ -z "${{ secrets.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID }}" ]; then
echo "❌ NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID is missing"
MISSING_CREDENTIALS="$MISSING_CREDENTIALS NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID"
CREDENTIALS_OK=false
else
echo "βœ… NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID is set"
fi
if [ -z "${{ secrets.SITECORE_EDITING_SECRET }}" ]; then
echo "❌ SITECORE_EDITING_SECRET is missing"
MISSING_CREDENTIALS="$MISSING_CREDENTIALS SITECORE_EDITING_SECRET"
CREDENTIALS_OK=false
else
echo "βœ… SITECORE_EDITING_SECRET is set"
fi
# Check optional but recommended secrets
if [ -z "${{ secrets.NEXT_PUBLIC_SITECORE_API_KEY }}" ]; then
echo "⚠️ NEXT_PUBLIC_SITECORE_API_KEY is not set (optional)"
else
echo "βœ… NEXT_PUBLIC_SITECORE_API_KEY is set"
fi
if [ -z "${{ secrets.NEXT_PUBLIC_SITECORE_API_HOST }}" ]; then
echo "⚠️ NEXT_PUBLIC_SITECORE_API_HOST is not set (optional)"
else
echo "βœ… NEXT_PUBLIC_SITECORE_API_HOST is set"
fi
echo ""
echo "=========================================="
if [ "$CREDENTIALS_OK" = false ]; then
echo "❌ CREDENTIAL VALIDATION FAILED"
echo ""
echo "Missing required credentials:$MISSING_CREDENTIALS"
echo ""
echo "⚠️ IMPORTANT: This workflow runs in the upstream repository context."
echo " Fork secrets are NOT accessible - only upstream repository secrets are used."
echo ""
echo "This is an UPSTREAM REPOSITORY configuration issue."
echo "The upstream repository administrator needs to configure these secrets:"
echo ""
echo " Settings > Secrets and variables > Actions > Secrets"
echo ""
echo "Required secrets:"
echo " - SITECORE_EDGE_URL"
echo " - SITECORE_EDGE_CONTEXT_ID"
echo " - NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID"
echo " - SITECORE_EDITING_SECRET"
echo ""
echo "Once these secrets are configured in the upstream repository,"
echo "this workflow will be able to access them when PRs are merged."
echo ""
echo "::error::Missing required XM Cloud credentials in upstream repository:$MISSING_CREDENTIALS"
echo "credentials-valid=false" >> $GITHUB_OUTPUT
exit 1
else
echo "βœ… All required credentials are present"
echo "credentials-valid=true" >> $GITHUB_OUTPUT
fi
- name: Install dependencies for all starters
run: |
echo "Installing dependencies for all enabled starters..."
# Install dependencies for each enabled starter
if [ -d "examples/kit-nextjs-skate-park" ]; then
echo "Installing dependencies for kit-nextjs-skate-park..."
cd examples/kit-nextjs-skate-park
npm ci
cd ../..
fi
if [ -d "examples/kit-nextjs-article-starter" ]; then
echo "Installing dependencies for kit-nextjs-article-starter..."
cd examples/kit-nextjs-article-starter
npm ci
cd ../..
fi
if [ -d "examples/kit-nextjs-location-finder" ]; then
echo "Installing dependencies for kit-nextjs-location-finder..."
cd examples/kit-nextjs-location-finder
npm ci
cd ../..
fi
if [ -d "examples/kit-nextjs-product-listing" ]; then
echo "Installing dependencies for kit-nextjs-product-listing..."
cd examples/kit-nextjs-product-listing
npm ci
cd ../..
fi
- name: Generate Sitecore files for all starters
run: |
echo "Generating Sitecore configuration files..."
# Generate files for each enabled starter
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "Generating files for $starter..."
cd "$starter"
# 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 .sitecore directory and files
mkdir -p .sitecore
# 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
echo "βœ… Minimal Sitecore files created for $starter"
fi
cd ../..
fi
done
- name: Lint and format check
run: |
echo "Running linting and formatting checks..."
# Check each enabled starter
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "=================================="
echo "Checking $starter"
echo "=================================="
cd "$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 - WARNING ONLY (does not fail the workflow)
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 for now
else
echo "βœ… Formatting check passed for $starter"
fi
cd ../..
fi
done
- name: Type checking
run: |
echo "Running TypeScript type checking..."
# Check each enabled starter - WARNING ONLY (does not fail the workflow)
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "Type checking $starter..."
cd "$starter"
if npm run type-check 2>/dev/null; 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
cd ../..
fi
done
- name: Check configured site names and extract default
id: site-check
run: |
echo "=========================================="
echo "πŸ” Checking Configured Site Names"
echo "=========================================="
echo ""
CONFIGURED_SITE_NAME=""
FIRST_SITE_FOUND=""
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "Checking $starter..."
cd "$starter"
if [ -f ".sitecore/sites.json" ]; then
echo " Sites configured in .sitecore/sites.json:"
echo " Full contents of sites.json:"
cat .sitecore/sites.json | head -20
echo ""
# Extract site names from sites.json (handles JSON format)
if command -v jq &> /dev/null; then
FIRST_SITE=$(jq -r '.[0].name' .sitecore/sites.json 2>/dev/null)
if [ -n "$FIRST_SITE" ] && [ "$FIRST_SITE" != "null" ]; then
if [ -z "$FIRST_SITE_FOUND" ]; then
FIRST_SITE_FOUND="$FIRST_SITE"
fi
echo " - $FIRST_SITE (first site)"
jq -r '.[].name' .sitecore/sites.json 2>/dev/null | while read -r site_name; do
if [ "$site_name" != "$FIRST_SITE" ]; then
echo " - $site_name"
fi
done || true
else
echo " (Could not parse sites.json - first site is null or empty)"
fi
else
# Fallback: try to extract site names with grep/sed
FIRST_SITE=$(grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' .sitecore/sites.json 2>/dev/null | head -1 | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
if [ -n "$FIRST_SITE" ]; then
if [ -z "$FIRST_SITE_FOUND" ]; then
FIRST_SITE_FOUND="$FIRST_SITE"
fi
echo " - $FIRST_SITE (first site)"
grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' .sitecore/sites.json 2>/dev/null | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | while read -r site_name; do
if [ "$site_name" != "$FIRST_SITE" ]; then
echo " - $site_name"
fi
done || true
else
echo " (Could not parse sites.json - install jq for better parsing)"
fi
fi
else
echo " ⚠️ .sitecore/sites.json not found"
fi
cd ../..
fi
done
echo ""
CONFIGURED_VAR="${{ vars.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'basic' }}"
echo "Current NEXT_PUBLIC_DEFAULT_SITE_NAME variable: $CONFIGURED_VAR"
if [ -n "$FIRST_SITE_FOUND" ]; then
echo "First site found in sites.json: $FIRST_SITE_FOUND"
echo "site-name-from-config=$FIRST_SITE_FOUND" >> $GITHUB_OUTPUT
if [ "$CONFIGURED_VAR" != "$FIRST_SITE_FOUND" ]; then
echo ""
echo "⚠️ WARNING: Site name mismatch detected!"
echo " Variable value: '$CONFIGURED_VAR'"
echo " Actual site in config: '$FIRST_SITE_FOUND'"
echo ""
echo "The build will use the site name from sites.json: '$FIRST_SITE_FOUND'"
echo "To fix permanently, update NEXT_PUBLIC_DEFAULT_SITE_NAME variable to: $FIRST_SITE_FOUND"
else
echo "βœ… Site name matches!"
fi
else
echo "⚠️ Could not extract site name from sites.json"
echo "site-name-from-config=" >> $GITHUB_OUTPUT
fi
echo ""
echo "ℹ️ If the build fails with 'Site does not exist', verify that"
echo " NEXT_PUBLIC_DEFAULT_SITE_NAME matches one of the sites listed above."
echo ""
- name: Build all starters
if: steps.credential-check.outputs.credentials-valid == 'true'
env:
# Sitecore Edge API Configuration
SITECORE_EDGE_URL: ${{ secrets.SITECORE_EDGE_URL }}
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_EDGE_URL: ${{ secrets.SITECORE_EDGE_URL }}
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 "=========================================="
echo "πŸ—οΈ Building all enabled starters"
echo "=========================================="
echo ""
echo "Sitecore Environment Variables Status:"
echo " SITECORE_EDGE_URL: ${SITECORE_EDGE_URL:+βœ… [SET]}${SITECORE_EDGE_URL:-❌ [NOT SET]}"
echo " SITECORE_EDGE_CONTEXT_ID: ${SITECORE_EDGE_CONTEXT_ID:+βœ… [SET]}${SITECORE_EDGE_CONTEXT_ID:-❌ [NOT SET]}"
echo " NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID: ${NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID:+βœ… [SET]}${NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID:-❌ [NOT SET]}"
echo " NEXT_PUBLIC_DEFAULT_SITE_NAME: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
echo " SITECORE_EDITING_SECRET: ${SITECORE_EDITING_SECRET:+βœ… [SET]}${SITECORE_EDITING_SECRET:-❌ [NOT SET]}"
echo ""
# Build each enabled starter
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "=========================================="
echo "Building $starter..."
echo "=========================================="
cd "$starter"
# Try to read site name from sites.json as fallback
ACTUAL_SITE_NAME="${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
DETECTED_SITE=""
echo "Checking for site name in .sitecore/sites.json..."
if [ -f ".sitecore/sites.json" ]; then
echo " Found .sitecore/sites.json"
if command -v jq &> /dev/null; then
DETECTED_SITE=$(jq -r '.[0].name' .sitecore/sites.json 2>/dev/null)
else
DETECTED_SITE=$(grep -o '"name"[[:space:]]*:[[:space:]]*"[^"]*"' .sitecore/sites.json 2>/dev/null | head -1 | sed 's/.*"name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
fi
echo " Detected site name from sites.json: '${DETECTED_SITE:-<empty or null>}'"
echo " Variable site name: '${NEXT_PUBLIC_DEFAULT_SITE_NAME}'"
if [ -n "$DETECTED_SITE" ] && [ "$DETECTED_SITE" != "null" ] && [ "$DETECTED_SITE" != "$NEXT_PUBLIC_DEFAULT_SITE_NAME" ]; then
echo "⚠️ Site name mismatch detected for $starter:"
echo " Variable: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
echo " sites.json: $DETECTED_SITE"
echo " Using site name from sites.json: $DETECTED_SITE"
ACTUAL_SITE_NAME="$DETECTED_SITE"
# Set environment variable for npm command
export NEXT_PUBLIC_DEFAULT_SITE_NAME="$DETECTED_SITE"
elif [ -n "$DETECTED_SITE" ] && [ "$DETECTED_SITE" != "null" ]; then
echo "βœ… Site names match: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
ACTUAL_SITE_NAME="${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
else
echo "⚠️ Could not extract valid site name from sites.json, using variable: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
ACTUAL_SITE_NAME="${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
fi
else
echo " ⚠️ .sitecore/sites.json not found, using variable: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
ACTUAL_SITE_NAME="${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
fi
echo ""
echo "Final site name to be used: ${ACTUAL_SITE_NAME}"
echo "Environment variable NEXT_PUBLIC_DEFAULT_SITE_NAME: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
echo ""
echo "Running build for $starter..."
# Ensure the environment variable is set for the npm command
NEXT_PUBLIC_DEFAULT_SITE_NAME="${ACTUAL_SITE_NAME}" npm run build 2>&1 | tee build_output.log || BUILD_EXIT_CODE=$?
BUILD_OUTPUT=$(cat build_output.log)
rm -f build_output.log
if [ -n "$BUILD_EXIT_CODE" ]; then
echo "❌ Build failed for $starter"
echo ""
echo "Build output:"
echo "$BUILD_OUTPUT"
echo ""
# Detect site configuration errors
if echo "$BUILD_OUTPUT" | grep -qi "Site.*does not exist\|site.*missing\|site item tree is missing"; then
echo "πŸ”΄ SITE CONFIGURATION ERROR DETECTED"
echo ""
echo "The build failed because the site '${ACTUAL_SITE_NAME}' does not exist in XM Cloud."
echo ""
echo "Site name used in build: ${ACTUAL_SITE_NAME}"
echo "Variable value: ${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
echo ""
echo "⚠️ IMPORTANT: This means the site '${ACTUAL_SITE_NAME}' needs to exist in your XM Cloud instance."
echo ""
echo "Possible solutions:"
echo ""
echo "Option 1: Create the site in XM Cloud (if you have access)"
echo " 1. Log into XM Cloud"
echo " 2. Create a new site with the name: '${ACTUAL_SITE_NAME}'"
echo " 3. Publish the site"
echo ""
echo "Option 2: Use an existing site name (recommended)"
echo " 1. Check what site names actually exist in your XM Cloud instance"
echo " 2. Check the 'Check configured site names' step above to see what's in sites.json"
echo " 3. A repository administrator needs to update the 'NEXT_PUBLIC_DEFAULT_SITE_NAME'"
echo " variable in: Settings > Secrets and variables > Actions > Variables"
echo " 4. The variable should match an EXISTING site name in XM Cloud"
echo ""
echo "Option 3: Update sites.json (if you have access to modify it)"
echo " 1. Update .sitecore/sites.json to use a site name that exists in XM Cloud"
echo " 2. The site name in sites.json should match what's actually in XM Cloud"
echo ""
echo "πŸ“ Note: The site name MUST exist in XM Cloud for the build to succeed."
echo " The build process tries to fetch routes from XM Cloud, and if the site"
echo " doesn't exist, it will fail with this error."
echo ""
echo "::error::Build failed for $starter - Site '${ACTUAL_SITE_NAME}' does not exist in XM Cloud. Either create the site in XM Cloud or update NEXT_PUBLIC_DEFAULT_SITE_NAME to match an existing site."
# Detect credential-related errors
elif echo "$BUILD_OUTPUT" | grep -qi "edge.*context\|sitecore.*edge\|credential\|authentication\|unauthorized\|403\|401"; then
echo "πŸ” CREDENTIAL ISSUE DETECTED"
echo ""
echo "The build failure appears to be related to XM Cloud credentials."
echo "This could indicate:"
echo " - Invalid or expired credentials"
echo " - Missing environment variables"
echo " - Network/connectivity issues with XM Cloud Edge"
echo ""
echo "::error::Build failed for $starter due to credential/authentication issues"
else
echo "::error::Build failed for $starter (check logs above for details)"
fi
exit 1
fi
echo "βœ… Build successful for $starter"
cd ../..
fi
done
echo ""
echo "=========================================="
echo "βœ… All builds completed successfully"
echo "=========================================="
- name: Credential validation failed - skip build
if: steps.credential-check.outputs.credentials-valid != 'true'
run: |
echo "=========================================="
echo "❌ BUILD SKIPPED - CREDENTIALS MISSING"
echo "=========================================="
echo ""
echo "The build step was skipped because required XM Cloud credentials"
echo "are not configured in the UPSTREAM repository."
echo ""
echo "⚠️ IMPORTANT INFORMATION:"
echo ""
echo "This workflow runs in the upstream repository context after a PR merge."
echo "Fork secrets are NOT accessible - only upstream repository secrets are used."
echo ""
echo "πŸ”§ SOLUTION:"
echo ""
echo "An upstream repository administrator needs to configure these secrets:"
echo ""
echo " 1. Go to: Settings > Secrets and variables > Actions > Secrets"
echo " 2. Add the following required secrets:"
echo " - SITECORE_EDGE_URL"
echo " - SITECORE_EDGE_CONTEXT_ID"
echo " - NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID"
echo " - SITECORE_EDITING_SECRET"
echo ""
echo " 3. Once configured, future PR merges will be able to use these secrets"
echo ""
echo "πŸ“ NOTE:"
echo " - This is NOT a code issue - it's a repository configuration issue"
echo " - Contributors cannot fix this - only repository admins can"
echo " - The PR validation workflow (for forks) runs without credentials"
echo " - The dmz-validation workflow (after merge) requires upstream secrets"
echo ""
echo "::error::Build skipped - Missing required XM Cloud credentials in upstream repository"
exit 1
- name: Run tests with coverage
if: steps.credential-check.outputs.credentials-valid == 'true'
run: |
set -e # Exit immediately if any command fails
echo "Running tests with coverage for all starters..."
# Test each enabled starter
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "Testing $starter..."
cd "$starter"
# Check if test:coverage script exists, if not fail the workflow
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: Run GEO endpoint tests (with server)
id: run-geo-tests
env:
SITECORE_EDGE_URL: ${{ secrets.SITECORE_EDGE_URL }}
SITECORE_EDGE_CONTEXT_ID: ${{ secrets.SITECORE_EDGE_CONTEXT_ID }}
NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID: ${{ secrets.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID }}
NEXT_PUBLIC_DEFAULT_SITE_NAME: ${{ vars.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'basic' }}
SITECORE_EDITING_SECRET: ${{ secrets.SITECORE_EDITING_SECRET }}
NEXT_PUBLIC_SITECORE_EDGE_URL: ${{ secrets.SITECORE_EDGE_URL }}
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: |
echo "Running GEO endpoint tests (site must be running)..."
echo "Per-starter site names: skate-park | solterra | alaris | sync (must match build and exist in XM Cloud)"
# Why site names are hardcoded below: Each starter maps to the canonical Sitecore site name used by that
# kit in the All Things JSS / xmcloud-starter-js repo.
# GitHub Actions repository variables/secrets usually expose only ONE default NEXT_PUBLIC_DEFAULT_SITE_NAME;
# applying that single value to every starter would inline the wrong site into builds and break GEO tests.
# Whenever a site name changes in XM Cloud or in this repository, update the case arms to match β€” do not
# rely on the lone repo variable for per-kit site selection.
# Fully stop the previous Next.js server and free :3000 before starting the next starter
# (npm spawns child processes; killing only $! can leave node listening on the port)
stop_geo_server() {
local pid="${1:-}"
echo "Stopping GEO server (pid=${pid:-none})..."
if [ -n "$pid" ]; then
kill "$pid" 2>/dev/null || true
pkill -P "$pid" 2>/dev/null || true
fi
pkill -f "next start" 2>/dev/null || true
sleep 2
for i in $(seq 1 20); do
if ! curl -sf -o /dev/null --connect-timeout 1 --max-time 3 http://127.0.0.1:3000/ 2>/dev/null; then
echo "Port 3000 is free."
return 0
fi
echo "Waiting for port 3000 to be released ($i/20)..."
fuser -k 3000/tcp 2>/dev/null || true
sleep 2
done
echo "⚠️ Port 3000 may still be in use; attempting to continue."
}
SERVER_PID=""
for starter in examples/kit-nextjs-skate-park examples/kit-nextjs-article-starter examples/kit-nextjs-location-finder examples/kit-nextjs-product-listing; do
if [ -d "$starter" ]; then
echo "GEO tests for $starter..."
cd "$starter"
if grep -q '"test:geo"' package.json 2>/dev/null; then
stop_geo_server "$SERVER_PID"
SERVER_PID=""
# sync | solterra | alaris | skate-park β€” must match XM Cloud + All Things JSS kit (see comment above).
case "$starter" in
examples/kit-nextjs-product-listing)
export NEXT_PUBLIC_DEFAULT_SITE_NAME="sync"
;;
examples/kit-nextjs-article-starter)
export NEXT_PUBLIC_DEFAULT_SITE_NAME="solterra"
;;
examples/kit-nextjs-location-finder)
export NEXT_PUBLIC_DEFAULT_SITE_NAME="alaris"
;;
examples/kit-nextjs-skate-park)
export NEXT_PUBLIC_DEFAULT_SITE_NAME="skate-park"
;;
*)
export NEXT_PUBLIC_DEFAULT_SITE_NAME="${NEXT_PUBLIC_DEFAULT_SITE_NAME:-basic}"
;;
esac
echo "NEXT_PUBLIC_DEFAULT_SITE_NAME=${NEXT_PUBLIC_DEFAULT_SITE_NAME}"
# npm run start runs build then next:start (kit package.json). Allow time below for build before :3000 is up.
echo "Starting $starter for GEO (npm run start)..."
npm run start &
SERVER_PID=$!
# Wait for server (npm run start runs build first; large starters may need several minutes)
echo "Waiting for server on http://localhost:3000..."
for i in $(seq 1 120); do
if curl -sf -o /dev/null http://localhost:3000 2>/dev/null; then
echo "Server ready."
break
fi
if [ "$i" -eq 120 ]; then
echo "❌ Server did not become ready in time"
stop_geo_server "$SERVER_PID"
exit 1
fi
sleep 5
done
if GEO_BASE_URL=http://localhost:3000 npm run test:geo; then
echo "βœ… GEO tests passed for $starter"
else
echo "❌ GEO tests failed for $starter"
stop_geo_server "$SERVER_PID"
SERVER_PID=""
cd ../..
exit 1
fi
stop_geo_server "$SERVER_PID"
SERVER_PID=""
else
echo "⏭️ No test:geo script for $starter, skipping"
fi
cd ../..
fi
done
stop_geo_server "$SERVER_PID"
- name: Create success notification
if: success()
run: |
echo "## βœ… DMZ Validation Successful" >> $GITHUB_STEP_SUMMARY
echo "The dmz branch has passed all validation checks." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Validation Results:**" >> $GITHUB_STEP_SUMMARY
echo "- βœ… All builds passed" >> $GITHUB_STEP_SUMMARY
echo "- βœ… Unit tests with coverage (npm run test:coverage:unit)" >> $GITHUB_STEP_SUMMARY
echo "- βœ… Linting and formatting checks passed" >> $GITHUB_STEP_SUMMARY
echo "- βœ… Type checking passed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY
echo "You can now merge dmz into main via GitHub web interface:" >> $GITHUB_STEP_SUMMARY
echo "1. Create a Pull Request from \`dmz\` to \`main\`" >> $GITHUB_STEP_SUMMARY
echo "2. Select **\"Create a merge commit\"** option (not Squash or Rebase)" >> $GITHUB_STEP_SUMMARY
echo "3. Confirm the merge" >> $GITHUB_STEP_SUMMARY
notify-failure:
name: Notify Build Failure
runs-on: ubuntu-latest
needs: validate-dmz
if: failure()
steps:
- name: Create failure notification
run: |
echo "## ❌ DMZ Validation Failed" >> $GITHUB_STEP_SUMMARY
echo "The dmz branch failed validation and should not be merged to main." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Possible Issues:**" >> $GITHUB_STEP_SUMMARY
echo "- πŸ” **Missing XM Cloud credentials in upstream repository** (check 'Validate XM Cloud credentials' step)" >> $GITHUB_STEP_SUMMARY
echo "- Site configuration error: Site name mismatch (check 'Check configured site names' step)" >> $GITHUB_STEP_SUMMARY
echo "- Build failures (check 'Build all starters' step)" >> $GITHUB_STEP_SUMMARY
echo "- Unit tests with coverage (check 'Run tests with coverage:unit for all starters' step)" >> $GITHUB_STEP_SUMMARY
echo "- Code quality issues (linting, formatting, type checking)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**⚠️ IMPORTANT - Credential Issue:**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "If the failure is due to missing credentials:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "This workflow runs in the **upstream repository context** after a PR merge." >> $GITHUB_STEP_SUMMARY
echo "Fork secrets are NOT accessible - only upstream repository secrets are used." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Solution:** An upstream repository administrator must configure secrets:" >> $GITHUB_STEP_SUMMARY
echo "1. Go to: Settings > Secrets and variables > Actions > Secrets" >> $GITHUB_STEP_SUMMARY
echo "2. Add required secrets: SITECORE_EDGE_URL, SITECORE_EDGE_CONTEXT_ID, NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID, SITECORE_EDITING_SECRET" >> $GITHUB_STEP_SUMMARY
echo "3. This is NOT a code issue - it's a repository configuration issue" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY
echo "1. Review the failed checks above" >> $GITHUB_STEP_SUMMARY
echo "2. If credentials missing: Contact upstream repository admin to configure secrets" >> $GITHUB_STEP_SUMMARY
echo "3. If site configuration error: Repository admin needs to update 'NEXT_PUBLIC_DEFAULT_SITE_NAME' variable" >> $GITHUB_STEP_SUMMARY
echo "4. Fix code issues in the dmz branch and push" >> $GITHUB_STEP_SUMMARY
echo "5. The validation will run automatically" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Note:** Contributors cannot fix credential/variable issues - only repository admins can." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Alternative:** Use the 'Rebase DMZ Branch' workflow to remove problematic commits." >> $GITHUB_STEP_SUMMARY