Skip to content

chore(release): v0.3.2 #95

chore(release): v0.3.2

chore(release): v0.3.2 #95

name: Bundle Analysis
on:
pull_request:
branches: [main]
paths:
- 'src/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'tsconfig.json'
permissions:
contents: read
pull-requests: write
jobs:
analyze:
name: Analyze Bundle Size
runs-on: ubuntu-latest
steps:
- name: Checkout PR
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Checkout base
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
ref: ${{ github.base_ref }}
path: base
- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: '20'
cache: 'pnpm'
- name: Install and build PR
run: |
set -euo pipefail
pnpm install --frozen-lockfile
if ! pnpm build; then
echo "::error::PR build failed"
exit 1
fi
if [ ! -d "dist" ]; then
echo "::error::dist directory not found after build"
exit 1
fi
- name: Install and build base
run: |
set -euo pipefail
cd base
# For base comparison, don't use frozen-lockfile as it may be out of sync
if [ -f "pnpm-lock.yaml" ]; then
pnpm install --no-frozen-lockfile
elif [ -f "package-lock.json" ]; then
npm ci
else
pnpm install
fi
if ! pnpm build 2>/dev/null && ! npm run build 2>/dev/null; then
echo "::error::Base build failed"
exit 1
fi
if [ ! -d "dist" ]; then
echo "::error::base/dist directory not found after build"
exit 1
fi
- name: Compare bundle sizes
id: compare
run: |
set -euo pipefail
# Get PR bundle size
PR_SIZE=$(du -sb dist | cut -f1)
PR_SIZE_KB=$(echo "scale=2; $PR_SIZE / 1024" | bc)
# Get base bundle size
BASE_SIZE=$(du -sb base/dist | cut -f1)
BASE_SIZE_KB=$(echo "scale=2; $BASE_SIZE / 1024" | bc)
# Calculate difference with divide-by-zero protection
DIFF=$((PR_SIZE - BASE_SIZE))
DIFF_KB=$(echo "scale=2; $DIFF / 1024" | bc)
if [ "$BASE_SIZE" -eq 0 ]; then
DIFF_PERCENT="N/A"
else
DIFF_PERCENT=$(echo "scale=2; ($DIFF / $BASE_SIZE) * 100" | bc 2>/dev/null || echo "0")
fi
# Get bundle breakdown for PR comment
BUNDLE_BREAKDOWN=$(du -sh dist/* 2>/dev/null || echo "No files in dist/")
echo "pr_size=$PR_SIZE_KB" >> $GITHUB_OUTPUT
echo "base_size=$BASE_SIZE_KB" >> $GITHUB_OUTPUT
echo "diff=$DIFF_KB" >> $GITHUB_OUTPUT
echo "diff_percent=$DIFF_PERCENT" >> $GITHUB_OUTPUT
# Use heredoc for multiline output
{
echo 'bundle_breakdown<<EOF'
echo "$BUNDLE_BREAKDOWN"
echo 'EOF'
} >> $GITHUB_OUTPUT
# Determine status emoji
if [ "$DIFF" -gt 51200 ]; then
echo "status=:warning:" >> $GITHUB_OUTPUT
elif [ "$DIFF" -lt 0 ]; then
echo "status=:white_check_mark:" >> $GITHUB_OUTPUT
else
echo "status=:heavy_check_mark:" >> $GITHUB_OUTPUT
fi
- name: Comment on PR
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { owner, repo } = context.repo;
const prSize = '${{ steps.compare.outputs.pr_size }}';
const baseSize = '${{ steps.compare.outputs.base_size }}';
const diff = '${{ steps.compare.outputs.diff }}';
const diffPercent = '${{ steps.compare.outputs.diff_percent }}';
const status = '${{ steps.compare.outputs.status }}';
const bundleBreakdown = `${{ steps.compare.outputs.bundle_breakdown }}`;
const table = [
'| Metric | Value |',
'|--------|-------|',
`| **Base** | ${baseSize} KB |`,
`| **PR** | ${prSize} KB |`,
`| **Diff** | ${diff} KB (${diffPercent}%) |`
].join('\n');
const body = [
`## ${status} Bundle Size Analysis`,
'',
table,
'',
'<details>',
'<summary>Bundle breakdown</summary>',
'',
'```',
bundleBreakdown,
'```',
'',
'</details>'
].join('\n');
// Find existing comment
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number: context.issue.number,
});
const botComment = comments.data.find(c =>
c.user.type === 'Bot' && c.body.includes('Bundle Size Analysis')
);
if (botComment) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: botComment.id,
body
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number: context.issue.number,
body
});
}