perf(monorepo): β‘οΈ optimize nx local task caching across workspace #646
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: π· Build Projects | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build-projects: | |
| name: π· Build Projects | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - name: π₯ Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: π Setup Monorepo | |
| uses: ./.github/actions/setup-monorepo | |
| - name: π· Build Projects | |
| run: npx nx run-many --all --target=build --parallel=3 | |
| - name: π¦ Measure Bundle - Pull Request | |
| if: github.event_name == 'pull_request' | |
| id: pr-sizes | |
| run: | | |
| LEXICO=$(cd applications/lexico && \ | |
| npx size-limit --json 2>/dev/null || echo '[]') | |
| COMPONENTS=$(cd packages/lexico-components && \ | |
| npx size-limit --json 2>/dev/null || echo '[]') | |
| COMBINED=$(printf '%s\n%s' "$LEXICO" "$COMPONENTS" | \ | |
| jq -s 'add // []') | |
| echo "data<<EOF" >> $GITHUB_OUTPUT | |
| echo "$COMBINED" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: π₯ Checkout Repository - Main | |
| if: github.event_name == 'pull_request' | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.base_ref }} | |
| clean: false | |
| - name: π Install Dependencies - Main | |
| if: github.event_name == 'pull_request' | |
| run: pnpm install --frozen-lockfile | |
| - name: π· Build Projects - Main | |
| if: github.event_name == 'pull_request' | |
| run: npx nx run-many --all --target=build --parallel=3 | |
| - name: π¦ Measure Bundle - Main | |
| if: github.event_name == 'pull_request' | |
| id: base-sizes | |
| run: | | |
| LEXICO=$(cd applications/lexico && \ | |
| npx size-limit --json 2>/dev/null || echo '[]') | |
| COMPONENTS=$(cd packages/lexico-components && \ | |
| npx size-limit --json 2>/dev/null || echo '[]') | |
| COMBINED=$(printf '%s\n%s' "$LEXICO" "$COMPONENTS" | \ | |
| jq -s 'add // []') | |
| echo "data<<EOF" >> $GITHUB_OUTPUT | |
| echo "$COMBINED" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| - name: π¬ Post bundle report | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| env: | |
| PR_DATA: ${{ steps.pr-sizes.outputs.data }} | |
| BASE_DATA: ${{ steps.base-sizes.outputs.data }} | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const prData = JSON.parse(process.env.PR_DATA || '[]'); | |
| const baseData = JSON.parse(process.env.BASE_DATA || '[]'); | |
| const toKB = bytes => (bytes / 1024).toFixed(2); | |
| const sign = n => n >= 0 ? '+' : ''; | |
| const baseMap = Object.fromEntries( | |
| baseData.map(e => [e.name, e]) | |
| ); | |
| const rows = prData.map(pr => { | |
| const base = baseMap[pr.name]; | |
| const diff = base != null ? pr.size - base.size : null; | |
| const pct = diff !== null && base.size > 0 ? | |
| (diff / base.size) * 100 : null; | |
| const status = !pr.passed ? 'β' : | |
| diff === null ? 'π' : | |
| diff > 0 ? (pct > 5 ? 'π' : 'β οΈ') : 'β '; | |
| const diffCol = diff !== null ? | |
| `${sign(diff)}${toKB(diff)} kB` : 'β'; | |
| const baseCol = base != null ? | |
| `${toKB(base.size)} kB` : 'β'; | |
| return `| ${status} | ${pr.name} | ${toKB(pr.size)} kB | ` + | |
| `${baseCol} | ${diffCol} | ${toKB(pr.sizeLimit)} kB |`; | |
| }); | |
| const totalPR = prData.reduce((s, e) => s + e.size, 0); | |
| const totalBase = baseData.reduce((s, e) => s + e.size, 0); | |
| const totalDiff = totalPR - totalBase; | |
| const totalPct = totalBase > 0 ? | |
| (totalDiff / totalBase) * 100 : 0; | |
| const overallStatus = prData.some(e => !e.passed) ? | |
| 'β' : totalDiff > 0 && totalPct > 5 ? 'π' : | |
| totalDiff > 0 ? 'β οΈ' : 'β '; | |
| const body = [ | |
| '## π¦ Bundle Size Report', | |
| '', | |
| `${overallStatus} **${toKB(totalPR)} kB** total ` + | |
| `(${sign(totalDiff)}${toKB(totalDiff)} kB, ` + | |
| `${sign(totalPct)}${totalPct.toFixed(1)}% vs base)`, | |
| '', | |
| '| | Bundle | PR Size | Base Size | Diff | Limit |', | |
| '|--|--------|---------|-----------|------|-------|', | |
| ...rows, | |
| '', | |
| '<details>', | |
| '<summary>π Guidelines</summary>', | |
| '', | |
| '- β Size decreased or unchanged', | |
| '- β οΈ Increased < 5%', | |
| '- π Increased β₯ 5%', | |
| '- β Exceeds limit', | |
| '</details>', | |
| '', | |
| '---', | |
| '*Updated automatically when you push new commits.*', | |
| ].join('\n'); | |
| const { data: comments } = | |
| await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.pull_request.number, | |
| }); | |
| const existing = comments.find( | |
| c => c.user.type === 'Bot' && | |
| c.body.includes('Bundle Size Report') | |
| ); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.pull_request.number, | |
| body, | |
| }); | |
| } |