mirror of
https://github.com/ghndrx/k8s-game-2048.git
synced 2026-02-10 06:45:07 +00:00
🎯 Update all workflows to test canonical Knative domains
✨ Improvements: - Prioritize canonical domain testing over custom domains - Add fallback testing for both canonical and custom domains - More reliable smoke tests using direct Knative service URLs - Separate performance testing for canonical vs custom domains - Enhanced auto-promotion pipeline with canonical domain validation 🧪 Testing Strategy: - Primary: Test canonical domains (game-2048-*.*.wa.darknex.us) - Secondary: Verify custom domains work via redirects - Fallback: Test both domains in smoke tests for reliability 🔗 Canonical Domains: - Dev: game-2048-dev.game-2048-dev.dev.wa.darknex.us - Staging: game-2048-staging.game-2048-staging.staging.wa.darknex.us - Prod: game-2048-prod.game-2048-prod.wa.darknex.us This ensures tests are more reliable since canonical domains are always accessible while custom domains may have redirect complexity.
This commit is contained in:
216
.github/workflows/auto-promote.yml
vendored
Normal file
216
.github/workflows/auto-promote.yml
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
name: Auto-Promote Pipeline
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Deploy to Development"]
|
||||
types:
|
||||
- completed
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
test-and-promote:
|
||||
name: Test Dev and Auto-Promote
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Wait for dev deployment to settle
|
||||
run: |
|
||||
echo "⏳ Waiting for dev deployment to fully settle..."
|
||||
sleep 60
|
||||
|
||||
- name: Run comprehensive dev tests
|
||||
run: |
|
||||
echo "🧪 Running comprehensive tests on dev environment..."
|
||||
|
||||
# Test canonical domain first (primary test)
|
||||
echo "Testing canonical domain: game-2048-dev.game-2048-dev.dev.wa.darknex.us"
|
||||
canonical_response=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://game-2048-dev.game-2048-dev.dev.wa.darknex.us/)
|
||||
if [ "$canonical_response" != "200" ]; then
|
||||
echo "❌ Canonical domain returned HTTP $canonical_response"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Canonical domain accessible"
|
||||
|
||||
# Test SSL certificate on custom domain
|
||||
echo "Testing SSL certificate on custom domain..."
|
||||
cert_expiry=$(echo | openssl s_client -servername 2048-dev.wa.darknex.us -connect 2048-dev.wa.darknex.us:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
|
||||
expiry_epoch=$(date -d "$cert_expiry" +%s)
|
||||
current_epoch=$(date +%s)
|
||||
days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
|
||||
|
||||
if [ $days_until_expiry -lt 30 ]; then
|
||||
echo "❌ SSL certificate expires in less than 30 days!"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ SSL certificate valid for $days_until_expiry days"
|
||||
|
||||
# Test custom domain accessibility
|
||||
echo "Testing custom domain accessibility..."
|
||||
response_code=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://2048-dev.wa.darknex.us/)
|
||||
if [ "$response_code" != "200" ]; then
|
||||
echo "❌ Custom domain returned HTTP $response_code"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Custom domain accessible"
|
||||
|
||||
# Test content validation on canonical domain
|
||||
echo "Testing content validation on canonical domain..."
|
||||
content=$(curl -s -L --max-time 30 https://game-2048-dev.game-2048-dev.dev.wa.darknex.us/)
|
||||
|
||||
if ! echo "$content" | grep -q "2048"; then
|
||||
echo "❌ Content missing 2048 title"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$content" | grep -q "HOW TO PLAY"; then
|
||||
echo "❌ Content missing game instructions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$content" | grep -q "style.css"; then
|
||||
echo "❌ CSS file not referenced"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! echo "$content" | grep -q "script.js"; then
|
||||
echo "❌ JavaScript file not referenced"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ All content validation tests passed"
|
||||
|
||||
# Test performance on canonical domain
|
||||
echo "Testing performance on canonical domain..."
|
||||
response_time=$(curl -s -o /dev/null -w "%{time_total}" -L --max-time 30 https://game-2048-dev.game-2048-dev.dev.wa.darknex.us/)
|
||||
if (( $(echo "$response_time > 10.0" | bc -l) )); then
|
||||
echo "❌ Response time too slow: ${response_time}s"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Performance test passed: ${response_time}s"
|
||||
|
||||
- name: Auto-promote to staging
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
console.log('🚀 All dev tests passed! Auto-promoting to staging...');
|
||||
|
||||
const response = await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'deploy-staging.yml',
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
image_tag: 'latest'
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ Staging deployment triggered');
|
||||
|
||||
return response;
|
||||
|
||||
- name: Create promotion summary
|
||||
run: |
|
||||
echo "## 🎯 Auto-Promotion Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Stage | Status | Action |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-------|--------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Dev Tests | ✅ Passed | Comprehensive validation completed |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Staging | 🚀 Triggered | Auto-promotion initiated |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### 📋 Tests Performed" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- SSL certificate validation" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Domain accessibility check" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Content and functionality validation" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Performance testing" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### 🔗 Next Steps" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Monitor staging deployment progress" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Staging tests will run automatically" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- Production promotion requires manual approval" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
promote-to-production:
|
||||
name: Test Staging and Promote to Production
|
||||
runs-on: ubuntu-latest
|
||||
needs: test-and-promote
|
||||
if: success()
|
||||
environment: production-approval # This requires manual approval
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Wait for staging deployment
|
||||
run: |
|
||||
echo "⏳ Waiting for staging deployment to complete..."
|
||||
sleep 120 # Give staging time to deploy
|
||||
|
||||
- name: Test staging environment
|
||||
run: |
|
||||
echo "🧪 Running staging tests..."
|
||||
|
||||
# Test canonical staging domain first
|
||||
echo "Testing canonical staging domain: game-2048-staging.game-2048-staging.staging.wa.darknex.us"
|
||||
canonical_response=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://game-2048-staging.game-2048-staging.staging.wa.darknex.us/)
|
||||
if [ "$canonical_response" != "200" ]; then
|
||||
echo "❌ Staging canonical domain returned HTTP $canonical_response"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Staging canonical domain accessible"
|
||||
|
||||
# Test custom staging domain
|
||||
echo "Testing custom staging domain: 2048-staging.wa.darknex.us"
|
||||
response_code=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://2048-staging.wa.darknex.us/)
|
||||
if [ "$response_code" != "200" ]; then
|
||||
echo "❌ Staging custom domain returned HTTP $response_code"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Staging custom domain accessible"
|
||||
|
||||
# Test staging content on canonical domain
|
||||
echo "Testing staging content..."
|
||||
content=$(curl -s -L --max-time 30 https://game-2048-staging.game-2048-staging.staging.wa.darknex.us/)
|
||||
if ! echo "$content" | grep -q "2048"; then
|
||||
echo "❌ Staging content validation failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Staging content validation passed"
|
||||
|
||||
- name: Auto-promote to production
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
console.log('🎯 Staging tests passed! Promoting to production...');
|
||||
|
||||
const response = await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'deploy-prod.yml',
|
||||
ref: 'main',
|
||||
inputs: {
|
||||
image_tag: 'latest',
|
||||
confirmation: 'DEPLOY'
|
||||
}
|
||||
});
|
||||
|
||||
console.log('🚀 Production deployment triggered');
|
||||
|
||||
return response;
|
||||
|
||||
- name: Create final summary
|
||||
run: |
|
||||
echo "## 🎉 Full Pipeline Completion" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Environment | Status | URL |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-------------|--------|-----|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Development | ✅ Tested & Live | https://2048-dev.wa.darknex.us |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Staging | ✅ Tested & Live | https://2048-staging.wa.darknex.us |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Production | 🚀 Deploying | https://2048.wa.darknex.us |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### 🎮 Your 2048 Game is Live!" >> $GITHUB_STEP_SUMMARY
|
||||
echo "All environments have been automatically tested and promoted successfully." >> $GITHUB_STEP_SUMMARY
|
||||
11
.github/workflows/deploy-dev.yml
vendored
11
.github/workflows/deploy-dev.yml
vendored
@@ -6,6 +6,8 @@ on:
|
||||
types:
|
||||
- completed
|
||||
branches: [ main ]
|
||||
push:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
image_tag:
|
||||
@@ -85,8 +87,13 @@ jobs:
|
||||
|
||||
for i in {1..5}; do
|
||||
echo "Attempt $i/5..."
|
||||
if curl -s --max-time 30 https://2048-dev.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Smoke test passed!"
|
||||
# Test canonical domain first
|
||||
if curl -s --max-time 30 https://game-2048-dev.game-2048-dev.dev.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Canonical domain smoke test passed!"
|
||||
break
|
||||
# Fallback to custom domain
|
||||
elif curl -s --max-time 30 https://2048-dev.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Custom domain smoke test passed!"
|
||||
break
|
||||
elif [ $i -eq 5 ]; then
|
||||
echo "⚠️ Smoke test failed after 5 attempts"
|
||||
|
||||
9
.github/workflows/deploy-prod.yml
vendored
9
.github/workflows/deploy-prod.yml
vendored
@@ -83,8 +83,13 @@ jobs:
|
||||
|
||||
for i in {1..5}; do
|
||||
echo "Attempt $i/5..."
|
||||
if curl -s --max-time 30 https://2048.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Smoke test passed!"
|
||||
# Test canonical domain first
|
||||
if curl -s --max-time 30 https://game-2048-prod.game-2048-prod.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Canonical domain smoke test passed!"
|
||||
break
|
||||
# Fallback to custom domain
|
||||
elif curl -s --max-time 30 https://2048.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Custom domain smoke test passed!"
|
||||
break
|
||||
elif [ $i -eq 5 ]; then
|
||||
echo "⚠️ Smoke test failed after 5 attempts"
|
||||
|
||||
9
.github/workflows/deploy-staging.yml
vendored
9
.github/workflows/deploy-staging.yml
vendored
@@ -79,8 +79,13 @@ jobs:
|
||||
|
||||
for i in {1..5}; do
|
||||
echo "Attempt $i/5..."
|
||||
if curl -s --max-time 30 https://2048-staging.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Smoke test passed!"
|
||||
# Test canonical domain first
|
||||
if curl -s --max-time 30 https://game-2048-staging.game-2048-staging.staging.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Canonical domain smoke test passed!"
|
||||
break
|
||||
# Fallback to custom domain
|
||||
elif curl -s --max-time 30 https://2048-staging.wa.darknex.us/ | grep -q "2048"; then
|
||||
echo "✅ Custom domain smoke test passed!"
|
||||
break
|
||||
elif [ $i -eq 5 ]; then
|
||||
echo "⚠️ Smoke test failed after 5 attempts"
|
||||
|
||||
84
.github/workflows/smoke-test.yml
vendored
84
.github/workflows/smoke-test.yml
vendored
@@ -82,27 +82,42 @@ jobs:
|
||||
echo "✅ Certificate is valid for $days_until_expiry days"
|
||||
fi
|
||||
|
||||
- name: Test Domain Accessibility
|
||||
- name: Test Canonical Domain (Primary Test)
|
||||
run: |
|
||||
echo "🌐 Testing domain accessibility for ${{ env.DOMAIN }}"
|
||||
echo "🎯 Testing canonical Knative domain: ${{ env.CANONICAL_DOMAIN }}"
|
||||
|
||||
# Test HTTPS access
|
||||
response_code=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
echo "HTTP response code: $response_code"
|
||||
# Test HTTPS access to canonical domain
|
||||
response_code=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://${{ env.CANONICAL_DOMAIN }}/)
|
||||
echo "Canonical domain HTTP response code: $response_code"
|
||||
|
||||
if [ "$response_code" != "200" ]; then
|
||||
echo "❌ Domain ${{ env.DOMAIN }} returned HTTP $response_code"
|
||||
echo "❌ Canonical domain ${{ env.CANONICAL_DOMAIN }} returned HTTP $response_code"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Domain ${{ env.DOMAIN }} is accessible"
|
||||
echo "✅ Canonical domain ${{ env.CANONICAL_DOMAIN }} is accessible"
|
||||
fi
|
||||
|
||||
- name: Test Content Validation
|
||||
- name: Test Custom Domain Accessibility
|
||||
run: |
|
||||
echo "📄 Testing content validation for ${{ env.DOMAIN }}"
|
||||
echo "🌐 Testing custom domain accessibility for ${{ env.DOMAIN }}"
|
||||
|
||||
# Download the page content
|
||||
content=$(curl -s -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
# Test HTTPS access (allow redirects)
|
||||
response_code=$(curl -s -o /dev/null -w "%{http_code}" -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
echo "Custom domain HTTP response code: $response_code"
|
||||
|
||||
if [ "$response_code" != "200" ]; then
|
||||
echo "❌ Custom domain ${{ env.DOMAIN }} returned HTTP $response_code"
|
||||
exit 1
|
||||
else
|
||||
echo "✅ Custom domain ${{ env.DOMAIN }} is accessible"
|
||||
fi
|
||||
|
||||
- name: Test Content Validation (Canonical Domain)
|
||||
run: |
|
||||
echo "📄 Testing content validation on canonical domain: ${{ env.CANONICAL_DOMAIN }}"
|
||||
|
||||
# Download the page content from canonical domain
|
||||
content=$(curl -s -L --max-time 30 https://${{ env.CANONICAL_DOMAIN }}/)
|
||||
|
||||
# Check if it contains expected 2048 game elements
|
||||
if echo "$content" | grep -q "2048"; then
|
||||
@@ -123,6 +138,7 @@ jobs:
|
||||
echo "✅ Page shows correct environment: ${{ env.ENV_NAME }}"
|
||||
else
|
||||
echo "⚠️ Environment indicator not found or incorrect"
|
||||
# Don't fail on this, just warn
|
||||
fi
|
||||
|
||||
# Check if CSS and JS files are referenced
|
||||
@@ -140,6 +156,21 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Content Validation (Custom Domain)
|
||||
run: |
|
||||
echo "📄 Testing content validation on custom domain: ${{ env.DOMAIN }}"
|
||||
|
||||
# Download the page content from custom domain
|
||||
content=$(curl -s -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
|
||||
# Basic content check to ensure redirect worked
|
||||
if echo "$content" | grep -q "2048"; then
|
||||
echo "✅ Custom domain serves correct content"
|
||||
else
|
||||
echo "❌ Custom domain does not serve correct content"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Redirect Behavior
|
||||
run: |
|
||||
echo "🔄 Testing redirect behavior for ${{ env.DOMAIN }}"
|
||||
@@ -162,23 +193,23 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Performance
|
||||
- name: Test Performance (Canonical Domain)
|
||||
run: |
|
||||
echo "⚡ Testing performance for ${{ env.DOMAIN }}"
|
||||
echo "⚡ Testing performance for canonical domain: ${{ env.CANONICAL_DOMAIN }}"
|
||||
|
||||
# Measure response time
|
||||
response_time=$(curl -s -o /dev/null -w "%{time_total}" -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
echo "Response time: ${response_time}s"
|
||||
# Measure response time on canonical domain
|
||||
response_time=$(curl -s -o /dev/null -w "%{time_total}" -L --max-time 30 https://${{ env.CANONICAL_DOMAIN }}/)
|
||||
echo "Canonical domain response time: ${response_time}s"
|
||||
|
||||
# Check if response time is reasonable (under 10 seconds)
|
||||
if (( $(echo "$response_time < 10.0" | bc -l) )); then
|
||||
echo "✅ Response time is acceptable"
|
||||
echo "✅ Canonical domain response time is acceptable"
|
||||
else
|
||||
echo "⚠️ Response time is slow: ${response_time}s"
|
||||
echo "⚠️ Canonical domain response time is slow: ${response_time}s"
|
||||
fi
|
||||
|
||||
# Check content size
|
||||
content_size=$(curl -s -L --max-time 30 https://${{ env.DOMAIN }}/ | wc -c)
|
||||
content_size=$(curl -s -L --max-time 30 https://${{ env.CANONICAL_DOMAIN }}/ | wc -c)
|
||||
echo "Content size: $content_size bytes"
|
||||
|
||||
if [ $content_size -gt 1000 ]; then
|
||||
@@ -188,6 +219,21 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Test Performance (Custom Domain)
|
||||
run: |
|
||||
echo "⚡ Testing performance for custom domain: ${{ env.DOMAIN }}"
|
||||
|
||||
# Measure response time including any redirects
|
||||
response_time=$(curl -s -o /dev/null -w "%{time_total}" -L --max-time 30 https://${{ env.DOMAIN }}/)
|
||||
echo "Custom domain response time (with redirects): ${response_time}s"
|
||||
|
||||
# More lenient for custom domain due to potential redirects
|
||||
if (( $(echo "$response_time < 15.0" | bc -l) )); then
|
||||
echo "✅ Custom domain response time is acceptable"
|
||||
else
|
||||
echo "⚠️ Custom domain response time is slow: ${response_time}s"
|
||||
fi
|
||||
|
||||
test-infrastructure:
|
||||
name: Infrastructure Tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
24
scripts/setup-environments.sh
Normal file
24
scripts/setup-environments.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup GitHub Environments for Protection Rules
|
||||
# This script documents the manual steps needed in GitHub UI
|
||||
|
||||
echo "🔧 Setting up GitHub Environments for Auto-Promotion Pipeline"
|
||||
echo ""
|
||||
echo "📋 Manual Steps Required in GitHub Repository Settings:"
|
||||
echo ""
|
||||
echo "1. Go to Settings → Environments"
|
||||
echo "2. Create 'production-approval' environment"
|
||||
echo "3. Add required reviewers (yourself)"
|
||||
echo "4. Set deployment protection rules"
|
||||
echo ""
|
||||
echo "Environment Configuration:"
|
||||
echo "- Environment Name: production-approval"
|
||||
echo "- Required Reviewers: Repository admins"
|
||||
echo "- Wait Timer: 0 minutes (immediate on approval)"
|
||||
echo "- Deployment Branches: main branch only"
|
||||
echo ""
|
||||
echo "This ensures production deployments require manual approval"
|
||||
echo "while dev → staging promotion happens automatically on successful tests."
|
||||
echo ""
|
||||
echo "🔗 Navigate to: https://github.com/YOUR_USERNAME/k8s-game-2048/settings/environments"
|
||||
Reference in New Issue
Block a user