diff --git a/.gitea/workflows/qa.yml b/.gitea/workflows/qa.yml index 153d18e..331ce89 100644 --- a/.gitea/workflows/qa.yml +++ b/.gitea/workflows/qa.yml @@ -10,11 +10,10 @@ on: env: TARGET_URL: "https://testing.mintel.me" PROJECT_NAME: "mintel.me" - PUPPETEER_SKIP_DOWNLOAD: "true" jobs: # ──────────────────────────────────────────────────── - # 1. Static Checks (OG Images, Links) + # 1. Static Checks (HTML, Assets, HTTP) # ──────────────────────────────────────────────────── static: name: 🔍 Static Analysis @@ -44,20 +43,62 @@ jobs: run: | pnpm store prune pnpm install --no-frozen-lockfile + - name: 🌐 Install Chrome & Dependencies + run: | + apt-get update && apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 + npx puppeteer browsers install chrome - name: 🖼️ OG Images continue-on-error: true env: TEST_URL: ${{ env.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm --filter @mintel/web run check:og - - name: 🔗 Lychee Link Check - uses: lycheeverse/lychee-action@v2 - with: - args: --accept 200,204,429 --timeout 15 --insecure --exclude "file://*" --exclude "https://logs.infra.*" --exclude "https://git.infra.*" --exclude "https://mintel.me/*" --include-verbatim '**/*.md' '**/*.mdx' - fail: true # ──────────────────────────────────────────────────── - # 2. Performance (Lighthouse) + # 2. E2E (Forms) + # ──────────────────────────────────────────────────── + e2e: + name: 📝 E2E + runs-on: docker + container: + image: catthehacker/ubuntu:act-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - 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.NPM_TOKEN }}" >> .npmrc + - name: 📦 Cache node_modules + uses: actions/cache@v4 + id: cache-deps + with: + path: node_modules + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + pnpm store prune + pnpm install --no-frozen-lockfile + - name: 🌐 Install Chrome & Dependencies + run: | + apt-get update && apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 + npx puppeteer browsers install chrome + - name: 📝 E2E Form Submission Test + continue-on-error: true + env: + TEST_URL: ${{ env.TARGET_URL }} + NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} + GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} + run: pnpm --filter @mintel/web run check:forms + + # ──────────────────────────────────────────────────── + # 3. Performance (Lighthouse) # ──────────────────────────────────────────────────── lighthouse: name: 🎭 Lighthouse @@ -88,21 +129,16 @@ jobs: pnpm store prune pnpm install --no-frozen-lockfile - name: 🌐 Install Chrome & Dependencies - continue-on-error: true run: | - rm -f /etc/apt/apt.conf.d/docker-clean - apt-get update - apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 + apt-get update && apt-get install -y libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libasound2t64 libpango-1.0-0 libcairo2 npx puppeteer browsers install chrome - name: 🎭 Desktop - continue-on-error: true env: NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} PAGESPEED_LIMIT: 5 run: pnpm --filter @mintel/web run pagespeed:test -- --collect.settings.preset=desktop - name: 📱 Mobile - continue-on-error: true env: NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} @@ -110,10 +146,10 @@ jobs: run: pnpm --filter @mintel/web run pagespeed:test -- --collect.settings.preset=mobile # ──────────────────────────────────────────────────── - # 3. E2E (Forms, Smoke) + # 4. Link Check & Dependency Audit # ──────────────────────────────────────────────────── - e2e: - name: 📝 E2E + links: + name: 🔗 Links & Deps runs-on: docker container: image: catthehacker/ubuntu:act-latest @@ -140,41 +176,21 @@ jobs: run: | pnpm store prune pnpm install --no-frozen-lockfile - - name: 🔍 Install Chromium (Native) - 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 - - name: 📝 E2E Form Submission Test + - name: 📦 Depcheck continue-on-error: true - env: - TEST_URL: ${{ env.TARGET_URL }} - NEXT_PUBLIC_BASE_URL: ${{ env.TARGET_URL }} - GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} - PUPPETEER_EXECUTABLE_PATH: /usr/bin/chromium - run: pnpm --filter @mintel/web run check:forms + 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*" || true + - name: 🔗 Lychee Link Check + uses: lycheeverse/lychee-action@v2 + with: + args: --accept 200,204,429 --timeout 15 --insecure --exclude "file://*" --exclude "https://logs.infra.mintel.me/*" --exclude "https://git.infra.mintel.me/*" --exclude "https://mintel.me/*" . + fail: true # ──────────────────────────────────────────────────── - # 4. Notification + # 5. Notification # ──────────────────────────────────────────────────── notify: name: 🔔 Notify - needs: [static, lighthouse, e2e] + needs: [static, e2e, lighthouse, links] if: always() runs-on: docker container: @@ -184,10 +200,11 @@ jobs: shell: bash run: | STATIC="${{ needs.static.result }}" - LIGHTHOUSE="${{ needs.lighthouse.result }}" E2E="${{ needs.e2e.result }}" + LIGHTHOUSE="${{ needs.lighthouse.result }}" + LINKS="${{ needs.links.result }}" - if [[ "$STATIC" != "success" || "$LIGHTHOUSE" != "success" || "$E2E" != "success" ]]; then + if [[ "$STATIC" != "success" || "$LIGHTHOUSE" != "success" ]]; then PRIORITY=8 EMOJI="🚨" STATUS="Failed" @@ -198,7 +215,7 @@ jobs: fi TITLE="$EMOJI ${{ env.PROJECT_NAME }} QA $STATUS" - MESSAGE="Static: $STATIC | Lighthouse: $LIGHTHOUSE | E2E: $E2E + MESSAGE="Static: $STATIC | E2E: $E2E | Lighthouse: $LIGHTHOUSE | Links: $LINKS ${{ env.TARGET_URL }}" curl -s -k -X POST "${{ secrets.GOTIFY_URL }}/message?token=${{ secrets.GOTIFY_TOKEN }}" \