From a8f31f82b83d235b2d870e4c7e7b6baa2e3b9fec Mon Sep 17 00:00:00 2001 From: Bart van der Braak Date: Fri, 16 Feb 2024 08:49:20 +0100 Subject: [PATCH] feat: add cicd and renovate dependabot config --- .github/dependabot.yaml | 14 +++ .github/renovate.json | 5 + .github/workflows/linting.yaml | 38 +++++++ .github/workflows/unlighthouse.yaml | 170 ++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+) create mode 100644 .github/dependabot.yaml create mode 100644 .github/renovate.json create mode 100644 .github/workflows/linting.yaml create mode 100644 .github/workflows/unlighthouse.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..5661b31 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + reviewers: + - "bartvdbraak" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "bartvdbraak" \ No newline at end of file diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..7269f0b --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:base"], + "reviewers": ["bartvdbraak"] +} \ No newline at end of file diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml new file mode 100644 index 0000000..4bb5963 --- /dev/null +++ b/.github/workflows/linting.yaml @@ -0,0 +1,38 @@ +name: Linting + +on: [pull_request] + +permissions: + checks: write + contents: write + +jobs: + run-checks: + name: Run checks + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18] + steps: + - name: Checkout Git repository + uses: actions/checkout@v4.1.1 + + - name: Setup pnpm + uses: pnpm/action-setup@v3.0.0 + with: + version: latest + + - name: Setup Node.js + uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + + - name: Install Node.js dependencies + run: pnpm install --frozen-lockfile + + - name: Run linters + uses: wearerequired/lint-action@v2.3.0 + with: + eslint: true + prettier: true \ No newline at end of file diff --git a/.github/workflows/unlighthouse.yaml b/.github/workflows/unlighthouse.yaml new file mode 100644 index 0000000..6738805 --- /dev/null +++ b/.github/workflows/unlighthouse.yaml @@ -0,0 +1,170 @@ +name: Unlighthouse + +on: + push: + branches: main + pull_request: + +permissions: + pull-requests: write + +jobs: + unlighthouse: + runs-on: ubuntu-latest + env: + COMMENT_ID: unlighthouse-node${{matrix.node-version}} + PORT: 8000 + CLOUDFLARE_PROJECT: hellobart-unlighthouse + strategy: + matrix: + node-version: [20] + steps: + - name: Create initial comment + uses: marocchino/sticky-pull-request-comment@v2.9.0 + if: github.ref != 'refs/heads/main' + with: + header: ${{ env.COMMENT_ID }} + message: | + ⚡️ Lighthouse report + + ![loading](https://github.com/bartvdbraak/hellob.art/assets/3996360/0e00b3fc-d5f9-490b-9aa7-07cb4b59f85f) + + - name: Set variables based on trigger + run: | + if [[ ${{ github.ref == 'refs/heads/main' }} == true ]]; then + echo "CLOUDFLARE_BRANCH=main" >> $GITHUB_ENV + echo "CLOUDFLARE_URL=https://${{ env.CLOUDFLARE_PROJECT }}.pages.dev" >> $GITHUB_ENV + else + echo "CLOUDFLARE_BRANCH=pull-${{ github.event.pull_request.number }}" >> $GITHUB_ENV + echo "CLOUDFLARE_URL=https://pull-${{ github.event.pull_request.number }}.${{ env.CLOUDFLARE_PROJECT }}.pages.dev" >> $GITHUB_ENV + fi + + - name: Checkout repository + uses: actions/checkout@v4.1.1 + + - name: Setup pnpm + uses: pnpm/action-setup@v3.0.0 + with: + version: latest + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + + - 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.43 + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + with: + deployment-url: ${{ steps.vercel_preview_url.outputs.preview_url }} + timeout: 360 + + - name: Install Dependencies + run: pnpm install -g @unlighthouse/cli puppeteer + + - name: Run Unlighthouse + run: | + unlighthouse-ci \ + --site "${{ github.ref == 'refs/heads/main' && 'https://hellob.art' || steps.vercel_preview_url.outputs.preview_url }}" \ + --reporter jsonExpanded \ + --build-static + + - name: Upload report to Cloudflare pages + uses: cloudflare/wrangler-action@v3.4.1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + command: pages deploy .unlighthouse --project-name="${{ env.CLOUDFLARE_PROJECT }}" --branch=${{ env.CLOUDFLARE_BRANCH }} + + - name: Create result content + id: create_result_content + uses: actions/github-script@v7.0.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 getColor = score => score >= 0.9 ? '4c1' : score >= 0.5 ? 'ffa400' : 'eb0f00'; + + const score = res => `${getEmoji(res)} ${formatScore(res)}`; + + const reportUrl = `${{ env.CLOUDFLARE_URL }}`; + + 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}).`, + ].join('\n'); + + core.setOutput("comment", comment); + core.setOutput("score", `${Math.round(result.summary.score * 100)}`); + core.setOutput("scoreColor", getColor(result.summary.score)); + + - name: Update comment with result + uses: marocchino/sticky-pull-request-comment@v2.9.0 + if: github.ref != 'refs/heads/main' + with: + header: ${{ env.COMMENT_ID }} + message: ${{ steps.create_result_content.outputs.comment }} + + - name: Create Lighthouse Score badge + uses: schneegans/dynamic-badges-action@v1.7.0 + if: github.ref == 'refs/heads/main' + with: + auth: ${{ secrets.GIST_SECRET }} + gistID: 795a3d6af5b0db5754cf7279898c3c16 + filename: hellob.art-unlighthouse.json + namedLogo: Lighthouse + label: lighthouse + message: ${{ steps.create_result_content.outputs.score }} + color: ${{ steps.create_result_content.outputs.scoreColor }} + + - name: Update comment on failure + uses: marocchino/sticky-pull-request-comment@v2.9.0 + if: failure() && github.ref != 'refs/heads/main' + with: + header: ${{ env.COMMENT_ID }} + message: | + ⚡️ Lighthouse report failed + + See deployment for any errors + + - name: Update comment on cancel + uses: marocchino/sticky-pull-request-comment@v2.9.0 + if: cancelled() && github.ref != 'refs/heads/main' + with: + header: ${{ env.COMMENT_ID }} + message: | + ⚡️ Lighthouse report cancelled \ No newline at end of file