From b53d351174a5c9401d74afa14df910dc2c505f5b Mon Sep 17 00:00:00 2001 From: Fy <1114550440@qq.com> Date: Fri, 14 Nov 2025 15:11:54 +0800 Subject: [PATCH] fix: triple with windows-msvc doesn't support -Cforce-unwind-tables=no (#12196) --- .github/actions/binary-limit/action.yml | 14 ++- .../binary-limit/binary-limit-script.js | 101 ++++++++++++------ .github/workflows/size-limit.yml | 85 +++++++++++++-- crates/node_binding/scripts/build.js | 4 +- 4 files changed, 163 insertions(+), 41 deletions(-) diff --git a/.github/actions/binary-limit/action.yml b/.github/actions/binary-limit/action.yml index bb473d1caa14..ade16ebc6c08 100644 --- a/.github/actions/binary-limit/action.yml +++ b/.github/actions/binary-limit/action.yml @@ -7,15 +7,27 @@ inputs: description: "the increase size limit in bytes, default is 50kb" default: "51200" required: false + platform: + description: "target triple name used to locate the binary" + default: "x86_64-unknown-linux-gnu" + required: false + +outputs: + result: + description: "JSON encoded size report" + value: ${{ steps.size-report.outputs.result }} runs: using: composite steps: - name: GitHub Script + id: size-report uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd with: script: | const limit = parseInt("${{ inputs.size-threshold }}") || 51200; + const platform = inputs.platform; const action = require("./.github/actions/binary-limit/binary-limit-script.js"); - await action({github, context, limit}); + const result = await action({github, context, limit, platform}); + core.setOutput("result", JSON.stringify(result)); diff --git a/.github/actions/binary-limit/binary-limit-script.js b/.github/actions/binary-limit/binary-limit-script.js index eb4093739f7d..f0990d993aef 100644 --- a/.github/actions/binary-limit/binary-limit-script.js +++ b/.github/actions/binary-limit/binary-limit-script.js @@ -1,10 +1,25 @@ const fs = require("node:fs"); +const SIZE_LIMIT_HEADING = "## 📦 Binary Size-limit"; +const DEFAULT_PLATFORM = "x86_64-unknown-linux-gnu"; + +const BINARY_PATHS = { + "x86_64-unknown-linux-gnu": "rspack.linux-x64-gnu.node", + "aarch64-apple-darwin": "rspack.darwin-arm64.node", + "x86_64-pc-windows-msvc": "rspack.win32-x64-msvc.node" +}; + +const PLATFORM_LABELS = { + "x86_64-unknown-linux-gnu": "Linux x64 (glibc)", + "aarch64-apple-darwin": "macOS arm64", + "x86_64-pc-windows-msvc": "Windows x64" +}; + /** - * @param {import("@octokit/rest")} github - * @param {Number} limit + * @param {{ github: import('@octokit/rest'), context: any, limit: number, platform?: string }} options */ -module.exports = async function action({ github, context, limit }) { +async function run({ github, context, limit, platform }) { + const target = platform || DEFAULT_PLATFORM; const commits = await github.rest.repos.listCommits({ owner: context.repo.owner, repo: context.repo.repo, @@ -18,10 +33,13 @@ module.exports = async function action({ github, context, limit }) { console.log(commit.sha); try { const data = await fetchDataBySha(commit.sha); - if (data?.size) { + const size = data?.sizes?.[target] ?? data?.size; + if (typeof size === "number") { baseCommit = commit; - baseSize = data.size; - console.log(`Commit ${commit.sha} has binary size: ${data.size}`); + baseSize = size; + console.log( + `Commit ${commit.sha} has binary size (${target}): ${size}` + ); break; } } catch (e) { @@ -35,48 +53,49 @@ module.exports = async function action({ github, context, limit }) { throw new Error(error); } - const headSize = fs.statSync( - "./crates/node_binding/rspack.linux-x64-gnu.node" - ).size; + const file = getBinaryPath(target); + console.log(`Checking binary size for ${file}`); + const headSize = fs.statSync(file).size; - console.log(`Base commit size: ${baseSize}`); - console.log(`Head commit size: ${headSize}`); - - const comment = compareBinarySize(headSize, baseSize, context, baseCommit); - - try { - await commentToPullRequest(github, context, comment); - } catch (e) { - console.error("Failed to comment on pull request:", e); - } + console.log(`Base commit size (${target}): ${baseSize}`); + console.log(`Head commit size (${target}): ${headSize}`); const increasedSize = headSize - baseSize; - if (increasedSize > limit) { - throw new Error( - `Binary size increased by ${increasedSize} bytes, exceeding the limit of ${limit} bytes` - ); - } -}; + return { + platform: target, + baseSize, + headSize, + increasedSize, + exceeded: increasedSize > limit, + comment: compareBinarySize(headSize, baseSize, context, baseCommit) + }; +} + +module.exports = run; +module.exports.commentToPullRequest = commentToPullRequest; +module.exports.formatReport = formatReport; +module.exports.getBinaryPath = getBinaryPath; +module.exports.SIZE_LIMIT_HEADING = SIZE_LIMIT_HEADING; -async function commentToPullRequest(github, context, comment) { +async function commentToPullRequest(github, context, body) { const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.number }); - const prevComment = comments.filter( + const prevComment = comments.find( comment => comment.user.login === "github-actions[bot]" && comment.body.startsWith(SIZE_LIMIT_HEADING) - )[0]; + ); if (prevComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: prevComment.id, - body: `${SIZE_LIMIT_HEADING}\n${comment}` + body }); return; } @@ -85,8 +104,19 @@ async function commentToPullRequest(github, context, comment) { owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.number, - body: `${SIZE_LIMIT_HEADING}\n${comment}` + body + }); +} + +function formatReport(entries) { + const ordered = [...entries].sort((a, b) => + a.platform.localeCompare(b.platform) + ); + const sections = ordered.map(entry => { + const title = PLATFORM_LABELS[entry.platform] || entry.platform; + return `### ${title}\n${entry.comment}`; }); + return `${SIZE_LIMIT_HEADING}\n\n${sections.join("\n\n")}`.trim(); } function fetchDataBySha(sha) { @@ -95,8 +125,6 @@ function fetchDataBySha(sha) { return fetch(dataUrl).then(res => res.json()); } -const SIZE_LIMIT_HEADING = "## 📦 Binary Size-limit"; - const DATA_URL_BASE = "https://raw.githubusercontent.com/web-infra-dev/rspack-ecosystem-benchmark/data"; @@ -118,6 +146,15 @@ function compareBinarySize(headSize, baseSize, context, baseCommit) { return `${info}🙈 Size remains the same at ${toHumanReadable(headSize)}`; } +function getBinaryPath(platform) { + const target = platform || DEFAULT_PLATFORM; + const filename = BINARY_PATHS[target]; + if (!filename) { + throw new Error(`Unsupported platform: ${target}`); + } + return `./crates/node_binding/${filename}`; +} + function toHumanReadable(size) { if (size < 1024) { return `${size}bytes`; diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml index 1011e2711029..285667b6834a 100644 --- a/.github/workflows/size-limit.yml +++ b/.github/workflows/size-limit.yml @@ -10,6 +10,16 @@ permissions: jobs: size-limit: name: Binding Size Limit + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + id: linux + - target: aarch64-apple-darwin + id: mac + - target: x86_64-pc-windows-msvc + id: win runs-on: ${{ fromJSON(vars.LINUX_SELF_HOSTED_RUNNER_LABELS || '"ubuntu-22.04"') }} steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 @@ -27,13 +37,11 @@ jobs: - name: Install Rust Toolchain uses: ./.github/actions/rustup with: - key: x86_64-unknown-linux-gnu-release - # don't need use cache in self-hosted windows; benefits of build with cargo build are wasted by cache restore + key: ${{ matrix.target }}-release save-if: ${{ runner.environment != 'self-hosted' || runner.os != 'Windows' }} - # setup rust target for native runner - name: Setup Rust Target - run: rustup target add x86_64-unknown-linux-gnu + run: rustup target add ${{ matrix.target }} - name: Run Cargo codegen run: cargo codegen @@ -50,13 +58,76 @@ jobs: with: tool-cache: fals - - name: Build x86_64-unknown-linux-gnu native + - name: Build ${{ matrix.target }} native run: | - rustup target add x86_64-unknown-linux-gnu - RUST_TARGET=x86_64-unknown-linux-gnu pnpm build:binding:release + rustup target add ${{ matrix.target }} + RUST_TARGET=${{ matrix.target }} pnpm build:binding:release - name: Binary Size-limit + id: size uses: ./.github/actions/binary-limit with: # 50k 50*1024 size-threshold: 51200 + platform: ${{ matrix.target }} + + - name: Save size result + if: steps.size.outputs.result != '' + shell: bash + env: + RESULT: ${{ steps.size.outputs.result }} + run: | + printf '%s' "$RESULT" > size-result.json + + - name: Upload size result + if: steps.size.outputs.result != '' + uses: actions/upload-artifact@v4 + with: + name: binary-size-${{ matrix.id }} + path: size-result.json + if-no-files-found: error + + gather-results: + name: Gather Binary Size Results + needs: size-limit + if: always() + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + + - name: Download size reports + uses: actions/download-artifact@4.1.7 + with: + pattern: binary-size-* + merge-multiple: true + path: size-results + if-no-files-found: error + + - name: Post combined report + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + env: + RESULTS_DIR: size-results + with: + script: | + const fs = require("node:fs"); + const path = require("node:path"); + const action = require("./.github/actions/binary-limit/binary-limit-script.js"); + const dir = process.env.RESULTS_DIR; + if (!fs.existsSync(dir)) { + core.info("No size reports found"); + return; + } + const files = fs.readdirSync(dir).filter(name => name.endsWith(".json")); + if (!files.length) { + core.info("No size reports to process"); + return; + } + const entries = files.map(file => { + const raw = fs.readFileSync(path.join(dir, file), "utf8"); + return JSON.parse(raw); + }); + const body = action.formatReport(entries); + await action.commentToPullRequest(github, context, body); + if (entries.some(entry => entry.exceeded)) { + core.setFailed("Binary size limit exceeded"); + } diff --git a/crates/node_binding/scripts/build.js b/crates/node_binding/scripts/build.js index 1254fb8372f2..a3589b094ab4 100644 --- a/crates/node_binding/scripts/build.js +++ b/crates/node_binding/scripts/build.js @@ -87,7 +87,9 @@ async function build() { } if (values.profile === "release") { features.push("info-level"); - rustflags.push("-Cforce-unwind-tables=no"); + if (process.env.RUST_TARGET && !process.env.RUST_TARGET.startsWith("windows-msvc")) { + rustflags.push("-Cforce-unwind-tables=no"); + } } if (features.length) { args.push("--features " + features.join(","));