Skip to content

perf(monorepo): ⚑️ optimize nx local task caching across workspace #646

perf(monorepo): ⚑️ optimize nx local task caching across workspace

perf(monorepo): ⚑️ optimize nx local task caching across workspace #646

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,
});
}