refactor: consolidate CI pipeline (9→7 jobs), remove continue-on-error from smoke test
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 10s
Build & Deploy / 🧪 QA (push) Successful in 1m43s
Build & Deploy / 🏗️ Build (push) Successful in 5m37s
Build & Deploy / 🚀 Deploy (push) Successful in 22s
Build & Deploy / 🧪 Post-Deploy Verification (push) Failing after 1m21s
Build & Deploy / ⚡ Performance & Accessibility (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s

This commit is contained in:
2026-02-25 00:23:03 +01:00
parent c5851370bf
commit 323886443f

View File

@@ -365,12 +365,11 @@ jobs:
run: docker builder prune -f --filter "until=1h" run: docker builder prune -f --filter "until=1h"
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
# JOB 5: Smoke Test (OG Images) # JOB 5: Post-Deploy Verification (Smoke Tests + Quality Gates)
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
smoke_test: post_deploy_checks:
name: 🧪 Smoke Test name: 🧪 Post-Deploy Verification
needs: [prepare, deploy] needs: [prepare, deploy]
continue-on-error: true
if: needs.deploy.result == 'success' && needs.prepare.outputs.target != 'branch' if: needs.deploy.result == 'success' && needs.prepare.outputs.target != 'branch'
runs-on: docker runs-on: docker
container: container:
@@ -392,24 +391,52 @@ jobs:
echo "//${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}/:_authToken=${{ secrets.REGISTRY_PASS }}" >> .npmrc echo "//${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}/:_authToken=${{ secrets.REGISTRY_PASS }}" >> .npmrc
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: 🚀 Run OG Image Check
# ── Critical Smoke Tests (MUST pass) ──────────────────────────────────
- name: 🚀 OG Image Check
env: env:
TEST_URL: ${{ needs.prepare.outputs.next_public_url }} TEST_URL: ${{ needs.prepare.outputs.next_public_url }}
run: pnpm run check:og run: pnpm run check:og
- name: 🌐 Run Full Sitemap HTTP Validation - name: 🌐 Full Sitemap HTTP Validation
env: env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }} NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm run check:http run: pnpm run check:http
# ── Quality Gates (informational, don't block pipeline) ───────────────
- name: 🌐 HTML DOM Validation
continue-on-error: true
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:html
- name: 🔒 Security Headers Scan
continue-on-error: true
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:security
- name: 🔗 Lychee Deep Link Crawl
continue-on-error: true
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:links
- name: 🖼️ Dynamic Asset & Image Integrity Scan
continue-on-error: true
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:assets
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
# JOB 6: Lighthouse (Performance & Accessibility) # JOB 6: Performance & Accessibility (Lighthouse + WCAG)
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
lighthouse: performance:
name: Lighthouse name: Performance & Accessibility
needs: [prepare, deploy, smoke_test] needs: [prepare, post_deploy_checks]
continue-on-error: true continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip' && needs.prepare.outputs.target != 'branch' if: needs.post_deploy_checks.result == 'success' && needs.prepare.outputs.target != 'branch'
runs-on: docker runs-on: docker
container: container:
image: catthehacker/ubuntu:act-latest image: catthehacker/ubuntu:act-latest
@@ -424,7 +451,6 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
- name: 🔐 Registry Auth - name: 🔐 Registry Auth
run: | run: |
echo "@mintel:registry=https://${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}" > .npmrc echo "@mintel:registry=https://${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}" > .npmrc
@@ -465,78 +491,14 @@ jobs:
# Standardize binary paths # Standardize binary paths
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/google-chrome [ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/google-chrome
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/chromium-browser [ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/chromium-browser
- name: Run Lighthouse CI - name: ⚡ Lighthouse CI
env: env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }} NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
CHROME_PATH: /usr/bin/chromium CHROME_PATH: /usr/bin/chromium
PAGESPEED_LIMIT: 8 PAGESPEED_LIMIT: 8
run: pnpm run pagespeed:test run: pnpm run pagespeed:test
- name: ♿ WCAG Audit
# ──────────────────────────────────────────────────────────────────────────────
# JOB 7: WCAG Audit
# ──────────────────────────────────────────────────────────────────────────────
wcag:
name: ♿ WCAG
needs: [prepare, deploy, smoke_test, lighthouse]
continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip' && needs.prepare.outputs.target != 'branch'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: 🔐 Registry Auth
run: |
echo "@mintel:registry=https://${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}" > .npmrc
echo "//${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}/:_authToken=${{ secrets.REGISTRY_PASS }}" >> .npmrc
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: 🔍 Install Chromium (Native & ARM64)
run: |
rm -f /etc/apt/apt.conf.d/docker-clean
apt-get update
apt-get install -y gnupg wget ca-certificates
# Detect OS
OS_ID=$(. /etc/os-release && echo $ID)
CODENAME=$(. /etc/os-release && echo $VERSION_CODENAME)
if [ "$OS_ID" = "debian" ]; then
echo "🎯 Debian detected - installing native chromium"
apt-get install -y chromium
else
echo "🎯 Ubuntu detected - adding xtradeb PPA"
mkdir -p /etc/apt/keyrings
KEY_ID="82BB6851C64F6880"
# Fetch PPA key
wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$KEY_ID" | gpg --dearmor > /etc/apt/keyrings/xtradeb.gpg
# Add PPA repository
echo "deb [signed-by=/etc/apt/keyrings/xtradeb.gpg] http://ppa.launchpad.net/xtradeb/apps/ubuntu $CODENAME main" > /etc/apt/sources.list.d/xtradeb-ppa.list
# PRIORITY PINNING: Force PPA over Snap-dummy
printf "Package: *\nPin: release o=LP-PPA-xtradeb-apps\nPin-Priority: 1001\n" > /etc/apt/preferences.d/xtradeb
apt-get update
apt-get install -y --allow-downgrades chromium
fi
# Standardize binary paths
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/google-chrome
[ -f /usr/bin/chromium ] && ln -sf /usr/bin/chromium /usr/bin/chromium-browser
- name: ♿ Run WCAG Audit
env: env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }} NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
@@ -545,76 +507,24 @@ jobs:
run: pnpm run check:wcag run: pnpm run check:wcag
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
# JOB 9: Quality Assertions # JOB 7: Notifications
# ──────────────────────────────────────────────────────────────────────────────
quality_assertions:
name: 🛡️ Quality Gates
needs: [prepare, deploy, smoke_test, lighthouse, wcag]
continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip' && needs.prepare.outputs.target != 'branch'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: 🔐 Registry Auth
run: |
echo "@mintel:registry=https://${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}" > .npmrc
echo "//${{ vars.REGISTRY_HOST || 'npm.infra.mintel.me' }}/:_authToken=${{ secrets.REGISTRY_PASS }}" >> .npmrc
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: 🌐 HTML DOM Validation
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:html
- name: 🔒 Security Headers Scan
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:security
- name: 🔗 Lychee Deep Link Crawl
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:links
- name: 🖼️ Dynamic Asset & Image Integrity Scan
env:
NEXT_PUBLIC_BASE_URL: ${{ needs.prepare.outputs.next_public_url }}
GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD || 'klz2026' }}
run: pnpm check:assets
# ──────────────────────────────────────────────────────────────────────────────
# JOB 10: Notifications
# ────────────────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────────────────
notifications: notifications:
name: 🔔 Notify name: 🔔 Notify
needs: [prepare, deploy, smoke_test, lighthouse, wcag, quality_assertions] needs: [prepare, deploy, post_deploy_checks, performance]
if: always() if: always()
runs-on: docker runs-on: docker
container: container:
image: catthehacker/ubuntu:act-latest image: catthehacker/ubuntu:act-latest
steps: steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: 🔔 Gotify - name: 🔔 Gotify
run: | run: |
STATUS="${{ needs.deploy.result }}" STATUS="${{ needs.deploy.result }}"
TITLE="klz-cables.com: $STATUS" SMOKE="${{ needs.post_deploy_checks.result }}"
[[ "$STATUS" == "success" ]] && PRIORITY=5 || PRIORITY=8 TITLE="klz-cables.com: deploy=$STATUS smoke=$SMOKE"
[[ "$STATUS" == "success" && "$SMOKE" == "success" ]] && PRIORITY=5 || PRIORITY=8
curl -s -k -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \ curl -s -k -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \
-F "title=$TITLE" \ -F "title=$TITLE" \
-F "message=Deploy to ${{ needs.prepare.outputs.target }} finished with status $STATUS.\nVersion: ${{ needs.prepare.outputs.image_tag }}" \ -F "message=Deploy to ${{ needs.prepare.outputs.target }} finished.\nDeploy: $STATUS | Smoke: $SMOKE\nVersion: ${{ needs.prepare.outputs.image_tag }}" \
-F "priority=$PRIORITY" || true -F "priority=$PRIORITY" || true