name: Lighthouse report

on:
  pull_request:

permissions:
  contents: write
  pages: write
  id-token: write
  pull-requests: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  unlighthouse:
    environment:
      name: github-pages
      url: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.BRANCH_NAME }}
    env:
      BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
    runs-on: ubuntu-latest
    steps:
      - name: Sticky Comment on Pull Request
        uses: marocchino/sticky-pull-request-comment@v2.6.2
        with:
          header: unlighthouse
          message: |
            ⚡️ Lighthouse report

            ![Loading](https://github.com/bartvdbraak/omnidash/assets/3996360/8e85bc78-53ac-41de-bdb6-bedfe8c6d8c1)

      - name: Check out
        uses: actions/checkout@v3.5.3

      - name: Set up Node.js
        uses: actions/setup-node@v3.6.0
        with:
          node-version: 18

      - name: Install Dependencies
        run: yarn global add @unlighthouse/cli puppeteer

      - name: Retrieve Vercel Preview URL
        uses: zentered/vercel-preview-url@v1.1.9
        id: vercel_preview_url
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
        with:
          vercel_project_id: ${{ vars.VERCEL_PROJECT_ID }}

      - name: Await Vercel Deployment
        uses: UnlyEd/github-action-await-vercel@v1.2.39
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
        with:
          deployment-url: ${{ steps.vercel_preview_url.outputs.preview_url }}
          timeout: 30

      - name: Build Unlighthouse report
        run: |
          unlighthouse-ci \
            --router-prefix "${{ github.event.repository.name }}/${{ env.BRANCH_NAME }}" \
            --site "${{ steps.vercel_preview_url.outputs.preview_url }}" \
            --reporter jsonExpanded \
            --build-static

      - name: Deploy report to GitHub pages
        uses: peaceiris/actions-gh-pages@v3.9.3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./.unlighthouse
          destination_dir: ${{ env.BRANCH_NAME }}

      - name: Format lighthouse score
        id: format_lighthouse_score
        uses: actions/github-script@v6.4.1
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            const fs = require('fs');

            const result = JSON.parse(fs.readFileSync('.unlighthouse/ci-result.json', 'utf8'));

            const formatScore = score => `${Math.round(score * 100)} (${score})`;
            const getEmoji = score => score >= 0.9 ? '🟢' : score >= 0.5 ? '🟠' : '🔴';

            const score = res => `${getEmoji(res)} ${formatScore(res)}`;

            const reportUrl = `https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.BRANCH_NAME }}`;

            const comment = [
                `⚡️ Lighthouse report for the changes in this PR:`,
                '| Category | Score |',
                '| --- | --- |',
                `| Performance | ${score(result.summary.categories.performance.averageScore)} |`,
                `| Accessibility | ${score(result.summary.categories.accessibility.averageScore)} |`,
                `| Best practices | ${score(result.summary.categories['best-practices'].averageScore)} |`,
                `| SEO | ${score(result.summary.categories.seo.averageScore)} |`,
                `| *Overall* | ${score(result.summary.score)} |`,
                '',
                '*Lighthouse scores for individual routes:*',
                '',
                '| Path | Performance | Accessibility | Best practices | SEO | Overall |',
                '| --- | --- | --- | --- | --- | --- |',
                `${result.routes.map(route => `| ${route.path} | ${score(route.categories.performance.score)} | ${score(route.categories.accessibility.score)} | ${score(route.categories['best-practices'].score)} | ${score(route.categories.seo.score)} | ${score(route.score)} |`).join('\n')}`,
                '',
                '*Lighthouse metrics:*',
                '',
                '| Metric | Average Value |',
                '| --- | --- |',
                `${Object.entries(result.summary.metrics).map(([metric, { averageNumericValue }]) => `| ${metric} | ${averageNumericValue} |`).join('\n')}`,
                '',
                `View the full Lighthouse report [here](${reportUrl}).`,
                '',
                'Learn more about the Lighthouse metrics:',
                '- [Largest Contentful Paint](https://web.dev/lighthouse-largest-contentful-paint/)',
                '- [Cumulative Layout Shift](https://web.dev/cls/)',
                '- [First Contentful Paint](https://web.dev/first-contentful-paint/)',
                '- [Total Blocking Time](https://web.dev/lighthouse-total-blocking-time/)',
                '- [Max Potential First Input Delay](https://web.dev/lighthouse-max-potential-fid/)',
                '- [Time to Interactive](https://web.dev/interactive/)',
            ].join('\n');

            core.setOutput("comment", comment);

      - name: Sticky Comment on Pull Request with result
        uses: marocchino/sticky-pull-request-comment@v2.6.2
        with:
          header: unlighthouse
          message: |
            ${{ steps.format_lighthouse_score.outputs.comment }}

      - name: Sticky Comment on Pull Request with failure
        uses: marocchino/sticky-pull-request-comment@v2.6.2
        if: ${{ failure() }}
        with:
          header: unlighthouse
          message: |
            ⚡️ Lighthouse report failed

            See deployment for any errors