diff --git a/.github/workflows/lighthouse.yml b/.github/workflows/lighthouse.yml new file mode 100644 index 0000000..c67eea3 --- /dev/null +++ b/.github/workflows/lighthouse.yml @@ -0,0 +1,38 @@ +name: lighthouse + +on: + workflow_dispatch: + pull_request: + branches: + - "main" + - "develop" + types: + - opened + - synchronize +jobs: + lighthouseci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run lighthouse + uses: actions/setup-node@v4 + with: + node-version: 20.11.0 + - run: | + npm install -g pnpm + pnpm install && pnpm add -g @lhci/cli + pnpm run build + lhci autorun + env: + LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} + - name: Format lighthouse score + id: format_lighthouse_score + uses: actions/github-script@v6 + with: + script: | + const script = require('./scripts/lhciFormat.js') + await script({core}) + - name: comment result + uses: unsplash/comment-on-pr@v1.3.0 + with: + msg: ${{ steps.format_lighthouse_score.outputs.comments}} diff --git a/script/lhciFormat.js b/script/lhciFormat.js new file mode 100644 index 0000000..3f2c28f --- /dev/null +++ b/script/lhciFormat.js @@ -0,0 +1,52 @@ +const fs = require("fs") + +const workspace = process.env.GITHUB_WORKSPACE + +const results = JSON.parse( + fs.readFileSync(path.join(workspace, "lhci_reports", "manifest.json")) +) +const categories = [ + "first-contentful-paint", + "interactive", + "speed-index", + "total-blocking-time", + "largest-contentful-paint", + "cumulative-layout-shift", +] + +const formatResult = (res) => Math.round(res * 100) +const score = (res) => (res >= 90 ? "🟢" : res >= 50 ? "🟠" : "🔴") +const detailRow = (category, audits) => + `| ${score(audits[category].score * 100)} ${category} | ${ + audits[category].displayValue + } |` +const getComment = (performance) => + [ + `⚡️ Lighthouse report!`, + `| Summary | Score |`, + `| --- | --- |`, + `| ${score(performance)} Performance | ${performance} |`, + ].join("\n") + +module.exports = async ({ core }) => { + let comments = "" + + results.forEach((result) => { + const { summary, jsonPath } = result + const details = JSON.parse(fs.readFileSync(jsonPath)) + const { audits } = details + const summaryEntries = Object.entries(summary).map(([key, value]) => [ + key, + formatResult(value), + ]) + const { performance } = Object.fromEntries(summaryEntries) + const comment = getComment(performance) + const detailRows = categories + .map((category) => detailRow(category, audits)) + .join("\n") + const detail = [`| Category | Score |`, detailRows].join("\n") + comments += comment + "\n" + detail + "\n\n" + }) + + core.setOutput("comments", comments) +}