From 2d36a4ec71697e7121f27c0888339560d177e06b Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Mon, 2 Mar 2026 11:51:12 +0100 Subject: [PATCH] ci(qa): refactor QA suite into granular jobs and fix NPM_TOKEN auth --- .../workflows/quality-assurance-template.yml | 204 ++++++++++++------ 1 file changed, 140 insertions(+), 64 deletions(-) diff --git a/.gitea/workflows/quality-assurance-template.yml b/.gitea/workflows/quality-assurance-template.yml index 8aa4453..82bcf95 100644 --- a/.gitea/workflows/quality-assurance-template.yml +++ b/.gitea/workflows/quality-assurance-template.yml @@ -18,10 +18,16 @@ on: required: true GATEKEEPER_PASSWORD: required: true + NPM_TOKEN: + required: false + MINTEL_PRIVATE_TOKEN: + required: false + GITEA_PAT: + required: false jobs: - qa_suite: - name: ๐Ÿ›ก๏ธ Nightly QA Suite + prepare: + name: ๐Ÿ—๏ธ Prepare & Install runs-on: docker container: image: catthehacker/ubuntu:act-latest @@ -39,95 +45,157 @@ jobs: - name: ๐Ÿ” Registry Auth run: | echo "@mintel:registry=https://git.infra.mintel.me/api/packages/mmintel/npm" > .npmrc - echo "//git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=${{ secrets.MINTEL_PRIVATE_TOKEN || secrets.GITEA_PAT }}" >> .npmrc + echo "//git.infra.mintel.me/api/packages/mmintel/npm/:_authToken=${{ secrets.NPM_TOKEN || secrets.MINTEL_PRIVATE_TOKEN || secrets.GITEA_PAT }}" >> .npmrc - name: Install dependencies - id: deps run: | pnpm store prune pnpm install --no-frozen-lockfile - - - name: ๐Ÿ“ฆ Cache APT Packages - uses: actions/cache@v4 + - name: ๐Ÿ“ฆ Archive dependencies + uses: actions/upload-artifact@v4 with: - path: /var/cache/apt/archives - key: apt-cache-${{ runner.os }}-${{ runner.arch }}-chromium + name: node_modules + path: | + node_modules + .npmrc + retention-days: 1 - - name: ๐Ÿ’พ Cache Chromium - id: cache-chromium - uses: actions/cache@v4 + static: + name: ๐Ÿ” Static Analysis + needs: prepare + 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: - path: /usr/bin/chromium - key: ${{ runner.os }}-chromium-native-${{ hashFiles('package.json') }} - - - name: ๐Ÿ” Install Chromium (Native & ARM64) - if: steps.cache-chromium.outputs.cache-hit != 'true' && steps.deps.outcome == 'success' - run: | - rm -f /etc/apt/apt.conf.d/docker-clean - apt-get update - apt-get install -y gnupg wget ca-certificates - OS_ID=$(. /etc/os-release && echo $ID) - CODENAME=$(. /etc/os-release && echo $VERSION_CODENAME) - if [ "$OS_ID" = "debian" ]; then - apt-get install -y chromium - else - mkdir -p /etc/apt/keyrings - KEY_ID="82BB6851C64F6880" - wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$KEY_ID" | gpg --dearmor > /etc/apt/keyrings/xtradeb.gpg - 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 - 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 - [ -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 - - # โ”€โ”€ Quality Gates โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - - - name: ๐ŸŒ Full Sitemap HTML Validation - if: always() && steps.deps.outcome == 'success' + version: 10 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: ๐Ÿ“ฅ Restore dependencies + uses: actions/download-artifact@v4 + with: + name: node_modules + - name: ๐ŸŒ HTML Validation env: NEXT_PUBLIC_BASE_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run check:html - - - name: ๐ŸŒ Dynamic Asset Presence & Error Scan - if: always() && steps.deps.outcome == 'success' + - name: ๐Ÿ–ผ๏ธ Asset Scan env: NEXT_PUBLIC_BASE_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run check:assets - - name: โ™ฟ Accessibility Scan (WCAG) - if: always() && steps.deps.outcome == 'success' + accessibility: + name: โ™ฟ Accessibility + needs: prepare + 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: ๐Ÿ“ฅ Restore dependencies + uses: actions/download-artifact@v4 + with: + name: node_modules + - name: ๐Ÿ” Install Chromium + run: | + apt-get update && apt-get install -y gnupg wget ca-certificates + CODENAME=$(. /etc/os-release && echo $VERSION_CODENAME) + mkdir -p /etc/apt/keyrings + wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x82BB6851C64F6880" | gpg --dearmor > /etc/apt/keyrings/xtradeb.gpg + 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 + 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 + ln -sf /usr/bin/chromium /usr/bin/google-chrome + - name: โ™ฟ WCAG Scan continue-on-error: true env: NEXT_PUBLIC_BASE_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run check:wcag - - name: ๐Ÿ“ฆ Unused Dependencies Scan (depcheck) - if: always() && steps.deps.outcome == 'success' + analysis: + name: ๐Ÿงช Maintenance & Links + needs: prepare + 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: ๐Ÿ“ฅ Restore dependencies + uses: actions/download-artifact@v4 + with: + name: node_modules + - name: ๐Ÿ“ฆ Depcheck continue-on-error: true run: pnpm dlx depcheck --ignores="*eslint*,*typescript*,*tailwindcss*,*postcss*,*prettier*,*@types/*,*husky*,*lint-staged*,*@next/*,*@lhci/*,*commitlint*,*cspell*,*rimraf*,*@payloadcms/*,*start-server-and-test*,*html-validate*,*critters*,*dotenv*,*turbo*" - - - name: ๐Ÿ”— Markdown & HTML Link Check (Lychee) - if: always() && steps.deps.outcome == 'success' + - name: ๐Ÿ”— Lychee Link Check uses: lycheeverse/lychee-action@v2 with: args: --accept 200,204,429 --timeout 15 content/ app/ public/ fail: true - - name: ๐ŸŽญ LHCI Desktop Audit - id: lhci_desktop - if: always() && steps.deps.outcome == 'success' + performance: + name: ๐ŸŽญ Lighthouse + needs: prepare + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 10 + - name: ๐Ÿ“ฅ Restore dependencies + uses: actions/download-artifact@v4 + with: + name: node_modules + - name: ๐Ÿ” Install Chromium + run: | + apt-get update && apt-get install -y gnupg wget ca-certificates + CODENAME=$(. /etc/os-release && echo $VERSION_CODENAME) + mkdir -p /etc/apt/keyrings + wget -qO- "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x82BB6851C64F6880" | gpg --dearmor > /etc/apt/keyrings/xtradeb.gpg + 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 + 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 + ln -sf /usr/bin/chromium /usr/bin/google-chrome + - name: ๐ŸŽญ LHCI Desktop env: LHCI_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run pagespeed:test -- --collect.settings.preset=desktop - - - name: ๐Ÿ“ฑ LHCI Mobile Audit - id: lhci_mobile - if: always() && steps.deps.outcome == 'success' + - name: ๐Ÿ“ฑ LHCI Mobile env: LHCI_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} @@ -135,7 +203,7 @@ jobs: notifications: name: ๐Ÿ”” Notify - needs: [qa_suite] + needs: [prepare, static, accessibility, analysis, performance] if: always() runs-on: docker container: @@ -144,22 +212,30 @@ jobs: - name: ๐Ÿ”” Gotify shell: bash run: | - SUITE="${{ needs.qa_suite.result }}" + PREPARE="${{ needs.prepare.result }}" + STATIC="${{ needs.static.result }}" + A11Y="${{ needs.accessibility.result }}" + ANALYSIS="${{ needs.analysis.result }}" + PERF="${{ needs.performance.result }}" + PROJECT="${{ inputs.PROJECT_NAME }}" URL="${{ inputs.TARGET_URL }}" - if [[ "$SUITE" != "success" ]]; then + if [[ "$PREPARE" != "success" || "$STATIC" != "success" || "$PERF" != "success" ]]; then PRIORITY=8 - EMOJI="โš ๏ธ" + EMOJI="๐Ÿšจ" STATUS_LINE="Nightly QA Failed! Action required." else PRIORITY=2 EMOJI="โœ…" - STATUS_LINE="Nightly QA Passed perfectly." + STATUS_LINE="Nightly QA Passed." fi TITLE="$EMOJI $PROJECT Nightly QA" - MESSAGE="$STATUS_LINE\n$URL\nPlease check Pipeline output for details." + MESSAGE="$STATUS_LINE + Prepare: $PREPARE | Static: $STATIC | A11y: $A11Y + Analysis: $ANALYSIS | Perf: $PERF + $URL" curl -s -k -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \ -F "title=$TITLE" \