-
Notifications
You must be signed in to change notification settings - Fork 251
153 lines (144 loc) · 5.5 KB
/
check-binary-size.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# This workflow checks if a PR commit has changed the size of a hello world Rust program.
# It downloads Rustc and compiles two versions of a stage0 compiler - one using the base commit
# of the PR, and one using the latest commit in the PR.
# If the size of the hello world program has changed, it posts a comment to the PR.
name: Check binary size
on:
pull_request_target:
# HACK(jubilee): something broke the distributed LLVM libso and I don't know what.
branches: []
# - master
# Both the "measure" and "report" jobs need to know this.
env:
SIZE_DATA_DIR: sizes
# Responsibility is divided between two jobs "measure" and "report", so that the
# job that builds (and potentnially runs) untrusted code does not have PR write
# permission, and vice-versa.
jobs:
measure:
name: Check binary size
strategy:
matrix:
platform: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.platform }}
permissions:
contents: read
env:
# This cannot be used as a context variable in the 'uses' key later. If it
# changes, update those steps too.
BACKTRACE_DIR: backtrace
RUSTC_DIR: rustc
TEST_MAIN_RS: foo.rs
BASE_COMMIT: ${{ github.event.pull_request.base.sha }}
HEAD_COMMIT: ${{ github.event.pull_request.head.sha }}
SIZE_DATA_FILE: size-${{ strategy.job-index }}.json
steps:
- name: Print info
shell: bash
run: |
echo "Current SHA: $HEAD_COMMIT"
echo "Base SHA: $BASE_COMMIT"
# Note: the backtrace source that's cloned here is NOT the version to be
# patched in to std. It's cloned here to access the Github action for
# building and measuring the test binary.
- name: Clone backtrace to access Github action
uses: actions/checkout@v4
with:
path: ${{ env.BACKTRACE_DIR }}
- name: Clone Rustc
uses: actions/checkout@v4
with:
repository: rust-lang/rust
path: ${{ env.RUSTC_DIR }}
- name: Set up std repository and backtrace submodule for size test
shell: bash
working-directory: ${{ env.RUSTC_DIR }}
env:
PR_SOURCE_REPO: ${{ github.event.pull_request.head.repo.full_name }}
run: |
# Bootstrap config
cat <<EOF > config.toml
change-id = 9999999
[llvm]
download-ci-llvm = true
[rust]
incremental = false
EOF
# Test program source
cat <<EOF > $TEST_MAIN_RS
fn main() {
panic!();
}
EOF
git submodule update --init library/backtrace
cd library/backtrace
git remote add head-pr "https://github.com/$PR_SOURCE_REPO"
git fetch --all
- name: Build binary with base version of backtrace
uses: ./backtrace/.github/actions/build-with-patched-std
with:
backtrace-commit: ${{ env.BASE_COMMIT }}
main-rs: ${{ env.TEST_MAIN_RS }}
rustc-dir: ${{ env.RUSTC_DIR }}
id: size-reference
- name: Build binary with PR version of backtrace
uses: ./backtrace/.github/actions/build-with-patched-std
with:
backtrace-commit: ${{ env.HEAD_COMMIT }}
main-rs: ${{ env.TEST_MAIN_RS }}
rustc-dir: ${{ env.RUSTC_DIR }}
id: size-updated
# There is no built-in way to "collect" all the outputs of a set of jobs
# run with a matrix strategy. Subsequent jobs that have a "needs"
# dependency on this one will be run once, when the last matrix job is
# run. Appending data to a single file within a matrix is subject to race
# conditions. So we write the size data to files with distinct names
# generated from the job index.
- name: Write sizes to file
uses: actions/github-script@v6
env:
SIZE_REFERENCE: ${{ steps.size-reference.outputs.test-binary-size }}
SIZE_UPDATED: ${{ steps.size-updated.outputs.test-binary-size }}
PLATFORM: ${{ matrix.platform }}
with:
script: |
const fs = require("fs");
const path = require("path");
fs.mkdirSync(process.env.SIZE_DATA_DIR, {recursive: true});
const output_data = JSON.stringify({
platform: process.env.PLATFORM,
reference: process.env.SIZE_REFERENCE,
updated: process.env.SIZE_UPDATED,
});
// The "wx" flag makes this fail if the file exists, which we want,
// because there should be no collisions.
fs.writeFileSync(
path.join(process.env.SIZE_DATA_DIR, process.env.SIZE_DATA_FILE),
output_data,
{ flag: "wx" },
);
- name: Upload size data
uses: actions/upload-artifact@v4
with:
name: size-files
path: ${{ env.SIZE_DATA_DIR }}/${{ env.SIZE_DATA_FILE }}
retention-days: 1
if-no-files-found: error
report:
name: Report binary size changes
runs-on: ubuntu-latest
needs: measure
permissions:
pull-requests: write
steps:
# Clone backtrace to access Github composite actions to report size.
- uses: actions/checkout@v4
- name: Download size data
uses: actions/download-artifact@v4
with:
name: size-files
path: ${{ env.SIZE_DATA_DIR }}
- name: Analyze and report size changes
uses: ./.github/actions/report-code-size-changes
with:
data-directory: ${{ env.SIZE_DATA_DIR }}