|
| 1 | +name: VP Binary Size |
| 2 | + |
| 3 | +permissions: {} |
| 4 | + |
| 5 | +on: |
| 6 | + pull_request: |
| 7 | + types: [opened, synchronize, reopened] |
| 8 | + paths: |
| 9 | + - '.cargo/**' |
| 10 | + - '.github/actions/clone/**' |
| 11 | + - '.github/workflows/vp-binary-size.yml' |
| 12 | + - 'crates/**' |
| 13 | + - 'Cargo.lock' |
| 14 | + - 'Cargo.toml' |
| 15 | + - 'rust-toolchain.toml' |
| 16 | + |
| 17 | +concurrency: |
| 18 | + group: vp-binary-size-${{ github.event.pull_request.number }} |
| 19 | + cancel-in-progress: true |
| 20 | + |
| 21 | +defaults: |
| 22 | + run: |
| 23 | + shell: bash |
| 24 | + |
| 25 | +jobs: |
| 26 | + base: |
| 27 | + name: Build base binary |
| 28 | + runs-on: namespace-profile-linux-x64-default |
| 29 | + permissions: |
| 30 | + contents: read |
| 31 | + outputs: |
| 32 | + raw_size: ${{ steps.size.outputs.raw_size }} |
| 33 | + gzip_size: ${{ steps.size.outputs.gzip_size }} |
| 34 | + steps: |
| 35 | + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 |
| 36 | + with: |
| 37 | + ref: ${{ github.event.pull_request.base.sha }} |
| 38 | + persist-credentials: false |
| 39 | + |
| 40 | + - uses: ./.github/actions/clone |
| 41 | + |
| 42 | + - uses: oxc-project/setup-rust@68c3199c5339f965e6e163924c3c450773eba42b # main (pending v1.0.17 — Swatinem/rust-cache v2.9.1 for node24) |
| 43 | + with: |
| 44 | + save-cache: false |
| 45 | + cache-key: vp-binary-size-base |
| 46 | + |
| 47 | + - name: Build vp |
| 48 | + run: cargo build --release -p vite_global_cli |
| 49 | + |
| 50 | + - name: Measure binary |
| 51 | + id: size |
| 52 | + run: | |
| 53 | + set -euo pipefail |
| 54 | + binary=target/release/vp |
| 55 | + echo "raw_size=$(stat --format=%s "$binary")" >> "$GITHUB_OUTPUT" |
| 56 | + echo "gzip_size=$(gzip -9 --stdout "$binary" | wc --bytes | tr -d ' ')" >> "$GITHUB_OUTPUT" |
| 57 | +
|
| 58 | + head: |
| 59 | + name: Build PR binary |
| 60 | + runs-on: namespace-profile-linux-x64-default |
| 61 | + permissions: |
| 62 | + contents: read |
| 63 | + outputs: |
| 64 | + raw_size: ${{ steps.size.outputs.raw_size }} |
| 65 | + gzip_size: ${{ steps.size.outputs.gzip_size }} |
| 66 | + steps: |
| 67 | + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 |
| 68 | + with: |
| 69 | + ref: ${{ github.event.pull_request.head.sha }} |
| 70 | + persist-credentials: false |
| 71 | + |
| 72 | + - uses: ./.github/actions/clone |
| 73 | + |
| 74 | + - uses: oxc-project/setup-rust@68c3199c5339f965e6e163924c3c450773eba42b # main (pending v1.0.17 — Swatinem/rust-cache v2.9.1 for node24) |
| 75 | + with: |
| 76 | + save-cache: false |
| 77 | + cache-key: vp-binary-size-head |
| 78 | + |
| 79 | + - name: Build vp |
| 80 | + run: cargo build --release -p vite_global_cli |
| 81 | + |
| 82 | + - name: Measure binary |
| 83 | + id: size |
| 84 | + run: | |
| 85 | + set -euo pipefail |
| 86 | + binary=target/release/vp |
| 87 | + echo "raw_size=$(stat --format=%s "$binary")" >> "$GITHUB_OUTPUT" |
| 88 | + echo "gzip_size=$(gzip -9 --stdout "$binary" | wc --bytes | tr -d ' ')" >> "$GITHUB_OUTPUT" |
| 89 | +
|
| 90 | + comment: |
| 91 | + name: Report binary size |
| 92 | + needs: [base, head] |
| 93 | + if: github.event.pull_request.head.repo.full_name == github.repository |
| 94 | + runs-on: ubuntu-latest |
| 95 | + permissions: |
| 96 | + contents: read |
| 97 | + issues: write |
| 98 | + pull-requests: write |
| 99 | + steps: |
| 100 | + - name: Comment size comparison |
| 101 | + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 |
| 102 | + env: |
| 103 | + BASE_RAW_SIZE: ${{ needs.base.outputs.raw_size }} |
| 104 | + BASE_GZIP_SIZE: ${{ needs.base.outputs.gzip_size }} |
| 105 | + HEAD_RAW_SIZE: ${{ needs.head.outputs.raw_size }} |
| 106 | + HEAD_GZIP_SIZE: ${{ needs.head.outputs.gzip_size }} |
| 107 | + HEAD_SHA: ${{ github.event.pull_request.head.sha }} |
| 108 | + with: |
| 109 | + script: | |
| 110 | + const marker = '<!-- vp-binary-size -->'; |
| 111 | + const baseRaw = Number(process.env.BASE_RAW_SIZE); |
| 112 | + const baseGzip = Number(process.env.BASE_GZIP_SIZE); |
| 113 | + const headRaw = Number(process.env.HEAD_RAW_SIZE); |
| 114 | + const headGzip = Number(process.env.HEAD_GZIP_SIZE); |
| 115 | +
|
| 116 | + const formatSize = (bytes) => |
| 117 | + `${bytes.toLocaleString('en-US')} B (${(bytes / 1024 / 1024).toFixed(2)} MiB)`; |
| 118 | + const formatDelta = (base, head) => { |
| 119 | + const delta = head - base; |
| 120 | + const percent = base === 0 ? 0 : (delta / base) * 100; |
| 121 | + const sign = delta > 0 ? '+' : ''; |
| 122 | + return `${sign}${delta.toLocaleString('en-US')} B (${sign}${percent.toFixed(2)}%)`; |
| 123 | + }; |
| 124 | +
|
| 125 | + const shortSha = process.env.HEAD_SHA.slice(0, 7); |
| 126 | + const body = [ |
| 127 | + marker, |
| 128 | + '', |
| 129 | + `### vp binary size (\`${shortSha}\`)`, |
| 130 | + '', |
| 131 | + 'Release build for `x86_64-unknown-linux-gnu`.', |
| 132 | + '', |
| 133 | + '| Artifact | Base | PR | Change |', |
| 134 | + '| --- | ---: | ---: | ---: |', |
| 135 | + `| Binary | ${formatSize(baseRaw)} | ${formatSize(headRaw)} | ${formatDelta(baseRaw, headRaw)} |`, |
| 136 | + `| gzip -9 | ${formatSize(baseGzip)} | ${formatSize(headGzip)} | ${formatDelta(baseGzip, headGzip)} |`, |
| 137 | + ].join('\n'); |
| 138 | +
|
| 139 | + await core.summary.addRaw(body.replace(marker, '')).write(); |
| 140 | +
|
| 141 | + const comments = await github.paginate(github.rest.issues.listComments, { |
| 142 | + owner: context.repo.owner, |
| 143 | + repo: context.repo.repo, |
| 144 | + issue_number: context.issue.number, |
| 145 | + }); |
| 146 | + const existing = comments.find((comment) => comment.body?.includes(marker)); |
| 147 | + if (existing) { |
| 148 | + await github.rest.issues.updateComment({ |
| 149 | + owner: context.repo.owner, |
| 150 | + repo: context.repo.repo, |
| 151 | + comment_id: existing.id, |
| 152 | + body, |
| 153 | + }); |
| 154 | + } else { |
| 155 | + await github.rest.issues.createComment({ |
| 156 | + owner: context.repo.owner, |
| 157 | + repo: context.repo.repo, |
| 158 | + issue_number: context.issue.number, |
| 159 | + body, |
| 160 | + }); |
| 161 | + } |
0 commit comments