forked from nim-works/nimskull
-
Notifications
You must be signed in to change notification settings - Fork 0
129 lines (111 loc) · 4.52 KB
/
reproducible.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
name: Test compiler build reproducibility
on:
push:
# Only run on bors branches
branches:
- staging
- trying
# This is for passing required checks
pull_request:
merge_group:
jobs:
reprotest:
# This job is meant for testing whether the compiler can be built
# reproducibly given the same build environment.
#
# There are two tools used for this test:
#
# - reprotest: This tool varies the environment in multiple ways, like
# adjusting time, build user, locale, etc. then run the build.
# If the binary matches the control build (build without any
# variations), then it's a pass. Otherwise, diffoscope is
# employed to show the differences.
#
# - diffoscope: This tool visualize differences in binaries in a
# human-readable fashion. This would allow developers to
# figure out what of their changes caused the build to
# varies based on outside environment.
# Skip this for PRs
if: github.event_name != 'pull_request'
strategy:
fail-fast: false
matrix:
test:
- name: Source archive
command: "./koch.py boot -d:danger && ./koch.py csource -d:danger && ./koch.py archive"
pattern: "build/*.tar.zst"
- name: Unix binary archive
command: "./koch.py boot -d:danger && ./koch.py docs --docCmd:skip && ./koch.py unixrelease"
pattern: "build/*.tar.zst"
# Note: this tests the zip generation and not exe generation determinism.
#
# Testing exe generation will be done when cross-bootstrap is possible.
- name: Windows binary archive
command: "./koch.py boot -d:danger && ./koch.py docs --docCmd:skip && ./koch.py winrelease"
pattern: "build/*.zip"
name: "${{ matrix.test.name }} reproducibility tests"
runs-on: ubuntu-latest
steps:
- name: Install reprotest
run: |
sudo apt-get update -qq
# This tool is required for archive generation
sudo apt-get install -yqq libarchive-tools
# Diffoscope have a /lot/ of optional dependencies, but we don't need
# all of them
sudo apt-get install -yqq --no-install-recommends diffoscope
# On the contrary, reprotest needs all of those deps to work
sudo apt-get install -yqq reprotest
- uses: actions/checkout@v4
with:
fetch-depth: 0
filter: tree:0
# reprotest will manipulate the time which may cause bootstrapping
# source download to fail due to SSL errors. Download this beforehand
# as a workaround.
- name: Download bootstrapping source
run: ./koch.py fetch-bootstrap
- id: reprotest
name: Run reproducibility build
run: |
# Add a guest user for reprotest
sudo useradd -m guest-builder
# The path to output diffoscope HTML to
output_html=$RUNNER_TEMP/diffoscope.html
run_reprotest() {
# Disabled kernel variation as it messes with csources architecture
# detection.
#
# Can be re-enabled once reprotest is >= 0.7.18, where a fix is added
# to prevent 32-bit architectures from being selected.
reprotest \
--vary=domain_host.use_sudo=1 \
--vary=user_group.available+=guest-builder:guest-builder \
--vary=-kernel \
--diffoscope-arg="--html=$output_html" \
'export XDG_CACHE_HOME=$PWD/build/nimcache \
&& ${{ matrix.test.command }}' \
'${{ matrix.test.pattern }}'
}
if ! run_reprotest; then
echo "::error::Reproducibility test failed, check the diffoscope output uploaded to artifacts for more details"
echo "result=$output_html" >> $GITHUB_OUTPUT
exit 1
fi
- name: Upload diffoscope output
if: failure()
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.test.name }} reproducibility test diffoscope output
path: ${{ steps.reprotest.outputs.result }}
passed:
name: All reproducibility tests passed
needs: [reprotest]
if: always()
runs-on: ubuntu-latest
steps:
- name: Raise failure
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: |
echo "::error::There are failing required jobs"
exit 1