name: Reusable Nightly QA on: workflow_call: inputs: TARGET_URL: description: 'The URL to test (e.g., https://testing.klz-cables.com)' required: true type: string PROJECT_NAME: description: 'The internal project name for notifications' required: true type: string secrets: GOTIFY_URL: required: true GOTIFY_TOKEN: required: true GATEKEEPER_PASSWORD: required: true NPM_TOKEN: required: false MINTEL_PRIVATE_TOKEN: required: false GITEA_PAT: required: false jobs: prepare: name: ๐Ÿ—๏ธ Prepare & Install 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://git.infra.mintel.me/api/packages/mmintel/npm" > .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 run: | pnpm store prune pnpm install --no-frozen-lockfile - name: ๐Ÿ“ฆ Archive dependencies uses: actions/upload-artifact@v4 with: name: node_modules path: | node_modules .npmrc retention-days: 1 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: 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: ๐Ÿ–ผ๏ธ Asset Scan env: NEXT_PUBLIC_BASE_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run check:assets 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 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: ๐Ÿ”— Lychee Link Check uses: lycheeverse/lychee-action@v2 with: args: --accept 200,204,429 --timeout 15 content/ app/ public/ fail: true 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 env: LHCI_URL: ${{ inputs.TARGET_URL }} GATEKEEPER_PASSWORD: ${{ secrets.GATEKEEPER_PASSWORD }} run: pnpm run pagespeed:test -- --collect.settings.preset=mobile notifications: name: ๐Ÿ”” Notify needs: [prepare, static, accessibility, analysis, performance] if: always() runs-on: docker container: image: catthehacker/ubuntu:act-latest steps: - name: ๐Ÿ”” Gotify shell: bash run: | 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 [[ "$PREPARE" != "success" || "$STATIC" != "success" || "$PERF" != "success" ]]; then PRIORITY=8 EMOJI="๐Ÿšจ" STATUS_LINE="Nightly QA Failed! Action required." else PRIORITY=2 EMOJI="โœ…" STATUS_LINE="Nightly QA Passed." fi TITLE="$EMOJI $PROJECT Nightly QA" 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" \ -F "message=$MESSAGE" \ -F "priority=$PRIORITY" || true