| # Github composite action to report on code size changes across different |
| # platforms. |
| |
| name: Report binary size changes on PR |
| description: | |
| Report on code size changes across different platforms resulting from a PR. |
| The only input argument is the path to a directory containing a set of |
| "*.json" files (extension required), each file containing the keys: |
| |
| - platform: the platform that the code size change was measured on |
| - reference: the size in bytes of the reference binary (base of PR) |
| - updated: the size in bytes of the updated binary (head of PR) |
| |
| The size is reported as a comment on the PR (accessed via context). |
| inputs: |
| data-directory: |
| description: > |
| Path to directory containing size data as a set of "*.json" files. |
| required: true |
| runs: |
| using: composite |
| steps: |
| - name: Post a PR comment if the size has changed |
| uses: actions/github-script@v6 |
| env: |
| DATA_DIRECTORY: ${{ inputs.data-directory }} |
| with: |
| script: | |
| const fs = require("fs"); |
| |
| const size_dir = process.env.DATA_DIRECTORY; |
| |
| // Map the set of all the *.json files into an array of objects. |
| const globber = await glob.create(`${size_dir}/*.json`); |
| const files = await globber.glob(); |
| const sizes = files.map(path => { |
| const contents = fs.readFileSync(path); |
| return JSON.parse(contents); |
| }); |
| |
| // Map each object into some text, but only if it shows any difference |
| // to report. |
| const size_reports = sizes.flatMap(size_data => { |
| const platform = size_data["platform"]; |
| const reference = size_data["reference"]; |
| const updated = size_data["updated"]; |
| |
| if (!(reference > 0)) { |
| core.setFailed(`Reference size invalid: ${reference}`); |
| return; |
| } |
| |
| if (!(updated > 0)) { |
| core.setFailed(`Updated size invalid: ${updated}`); |
| return; |
| } |
| |
| const formatter = Intl.NumberFormat("en", { |
| useGrouping: "always" |
| }); |
| |
| const updated_str = formatter.format(updated); |
| const reference_str = formatter.format(reference); |
| |
| const diff = updated - reference; |
| const diff_pct = (updated / reference) - 1; |
| |
| const diff_str = Intl.NumberFormat("en", { |
| useGrouping: "always", |
| sign: "exceptZero" |
| }).format(diff); |
| |
| const diff_pct_str = Intl.NumberFormat("en", { |
| style: "percent", |
| useGrouping: "always", |
| sign: "exceptZero", |
| maximumFractionDigits: 2 |
| }).format(diff_pct); |
| |
| if (diff !== 0) { |
| // The body is created here and wrapped so "weirdly" to avoid whitespace at the start of the lines, |
| // which is interpreted as a code block by Markdown. |
| const report = `On platform \`${platform}\`: |
| |
| - Original binary size: **${reference_str} B** |
| - Updated binary size: **${updated_str} B** |
| - Difference: **${diff_str} B** (${diff_pct_str}) |
| |
| `; |
| |
| return [report]; |
| } else { |
| return []; |
| } |
| }); |
| |
| // If there are any size changes to report, format a comment and post |
| // it. |
| if (size_reports.length > 0) { |
| const comment_sizes = size_reports.join(""); |
| const body = `Code size changes for a hello-world Rust program linked with libstd with backtrace: |
| |
| ${comment_sizes}`; |
| |
| github.rest.issues.createComment({ |
| issue_number: context.issue.number, |
| owner: context.repo.owner, |
| repo: context.repo.repo, |
| body |
| }); |
| } |