Skip to content

Commit c3f57be

Browse files
authored
scripts: fix script for reproducible builds (#1492)
* scripts: fix script for reproducible builds * scripts: add automatic hash comparasion + compute file with checksums * scripts: silence cleanup * ci/scripts: enable parallel build (#1493)
1 parent aace3fd commit c3f57be

File tree

2 files changed

+95
-38
lines changed

2 files changed

+95
-38
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
shell: docker exec -t builder sh {0}
8686
run: |
8787
cabal update
88-
cabal build --enable-tests -fserver_postgres
88+
cabal build --jobs=$(nproc) --enable-tests -fserver_postgres
8989
mkdir -p /out
9090
for i in smp-server simplexmq-test; do
9191
bin=$(find /project/dist-newstyle -name "$i" -type f -executable)
@@ -108,7 +108,7 @@ jobs:
108108
- name: Build everything else (standard)
109109
shell: docker exec -t builder sh {0}
110110
run: |
111-
cabal build
111+
cabal build --jobs=$(nproc)
112112
mkdir -p /out
113113
for i in ${{ env.apps }}; do
114114
bin=$(find /project/dist-newstyle -name "$i" -type f -executable)

scripts/reproduce-builds.sh

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,76 +6,133 @@ TAG="$1"
66
tempdir="$(mktemp -d)"
77
init_dir="$PWD"
88

9+
repo="https://github.com/simplex-chat/simplexmq"
10+
export DOCKER_BUILDKIT=1
11+
12+
cleanup() {
13+
docker exec -t builder sh -c 'rm -rf ./dist-newstyle' 2>/dev/null || :
14+
rm -rf -- "$tempdir"
15+
docker rm --force builder 2>/dev/null || :
16+
docker image rm local 2>/dev/null || :
17+
cd "$init_dir"
18+
}
19+
trap 'cleanup' EXIT INT
20+
921
mkdir -p "$init_dir/$TAG/from-source" "$init_dir/$TAG/prebuilt"
1022

11-
git -C "$tempdir" clone https://github.com/simplex-chat/simplexmq.git &&\
23+
git -C "$tempdir" clone "$repo.git" &&\
1224
cd "$tempdir/simplexmq" &&\
1325
git checkout "$TAG"
1426

15-
for os in 20.04 22.04 24.04; do
27+
for os in 22.04 24.04; do
1628
os_url="$(printf '%s' "$os" | tr '.' '_')"
17-
mkdir -p "$init_dir/cache/cabal/builder-${os}" "$init_dir/cache/dist-newstyle/builder-${os}"
18-
chmod g+wX "$init_dir/cache"
1929

30+
# Build image
2031
docker build \
2132
--no-cache \
22-
-f "$tempdir/simplexmq/Dockerfile.build" \
2333
--build-arg TAG=${os} \
24-
-t repro-${os} \
34+
--build-arg GHC=9.6.3 \
35+
-f "$tempdir/simplexmq/Dockerfile.build" \
36+
-t local \
2537
.
2638

27-
docker run \
28-
-t \
29-
-d \
30-
-v "$init_dir/cache/cabal/builder-${os}:/root/.cabal" \
31-
-v "$init_dir/cache/dist-newstyle/builder-${os}:/dist-newstyle" \
39+
# Run container in background
40+
docker run -t -d \
41+
--name builder \
3242
-v "$tempdir/simplexmq:/project" \
33-
--name builder-${os} \
34-
repro-${os}
35-
36-
37-
apps='smp-server xftp-server ntf-server xftp'
38-
39-
# Regular build (all)
40-
docker exec \
41-
-t \
42-
-e apps="$apps" \
43-
builder-${os} \
44-
sh -c 'ln -fs /dist-newstyle ./dist-newstyle && cabal update && cabal build && mkdir -p /out && for i in $apps; do bin=$(find /dist-newstyle -name "$i" -type f -executable); strip "$bin"; chmod +x "$bin"; mv "$bin" /out/; done'
45-
46-
docker cp \
47-
builder-${os}:/out \
48-
out-${os}
43+
local
4944

5045
# PostgreSQL build (only smp-server)
5146
docker exec \
5247
-t \
53-
builder-${os} \
54-
sh -c 'ln -fs /dist-newstyle ./dist-newstyle && cabal update && cabal build -fserver_postgres exe:smp-server && mkdir -p /out && bin=$(find /dist-newstyle -name "smp-server" -type f -executable); strip "$bin"; chmod +x "$bin"; mv "$bin" /out/'
48+
builder \
49+
sh -c 'cabal update && cabal build --jobs=$(nproc) --enable-tests -fserver_postgres && mkdir -p /out && for i in smp-server simplexmq-test; do bin=$(find /project/dist-newstyle -name "$i" -type f -executable) && chmod +x "$bin" && mv "$bin" /out/; done && strip /out/smp-server'
5550

51+
# Copy smp-server postgresql binary and prepare it
5652
docker cp \
57-
builder-${os}:/out/smp-server \
53+
builder:/out/smp-server \
5854
"$init_dir/$TAG/from-source/smp-server-postgres-ubuntu-${os_url}-x86-64"
5955

56+
# Download prebuilt postgresql binary
6057
curl -L \
6158
--output-dir "$init_dir/$TAG/prebuilt/" \
6259
-O \
63-
"https://github.com/simplex-chat/simplexmq/releases/download/${TAG}/smp-server-postgres-ubuntu-${os_url}-x86-64"
60+
"$repo/releases/download/${TAG}/smp-server-postgres-ubuntu-${os_url}-x86-64"
61+
62+
# Regular build (all)
63+
apps='smp-server xftp-server ntf-server xftp'
64+
65+
docker exec \
66+
-t \
67+
-e apps="$apps" \
68+
builder \
69+
sh -c 'cabal build --jobs=$(nproc) && mkdir -p /out && for i in $apps; do bin=$(find /project/dist-newstyle -name "$i" -type f -executable) && strip "$bin" && chmod +x "$bin" && mv "$bin" /out/; done'
70+
71+
# Copy regular binaries
72+
docker cp \
73+
builder:/out \
74+
out-${os}
6475

76+
# Prepare regular binaries and download the prebuilt ones
6577
for app in $apps; do
6678
curl -L \
6779
--output-dir "$init_dir/$TAG/prebuilt/" \
6880
-O \
69-
"https://github.com/simplex-chat/simplexmq/releases/download/${TAG}/${app}-ubuntu-${os_url}-x86-64"
81+
"$repo/releases/download/${TAG}/${app}-ubuntu-${os_url}-x86-64"
7082

7183
mv "./out-${os}/$app" "$init_dir/$TAG/from-source/${app}-ubuntu-${os_url}-x86-64"
7284
done
7385

74-
docker stop builder-${os}
75-
docker rm builder-${os}
76-
docker image rm repro-${os}
86+
# Important! Remove dist-newstyle for the next interation
87+
docker exec \
88+
-t \
89+
builder \
90+
sh -c 'rm -rf ./dist-newstyle'
91+
92+
# Also restore git to previous state
93+
git reset --hard && git clean -dfx
94+
95+
# Stop containers, delete images
96+
docker stop builder
97+
docker rm --force builder
98+
docker image rm local
7799
done
78100

79101
# Cleanup
102+
rm -rf -- "$tempdir"
80103
cd "$init_dir"
81-
rm -rf "$tempdir"
104+
105+
# Final stage: compare hashes
106+
107+
# Path to binaries
108+
path_bin="$init_dir/$TAG"
109+
110+
# Assume everything is okay for now
111+
bad=0
112+
113+
# Check hashes for all binaries
114+
for file in "$path_bin"/from-source/*; do
115+
# Extract binary name
116+
app="$(basename $file)"
117+
118+
# Compute hash for compiled binary
119+
compiled=$(sha256sum "$path_bin/from-source/$app" | awk '{print $1}')
120+
# Compute hash for prebuilt binary
121+
prebuilt=$(sha256sum "$path_bin/prebuilt/$app" | awk '{print $1}')
122+
123+
# Compare
124+
if [ "$compiled" != "$prebuilt" ]; then
125+
# If hashes doesn't match, sed bad...
126+
bad=1
127+
128+
# ... and print affected binary
129+
printf "%s - sha256sum hash doesn't match\n" "$app"
130+
fi
131+
done
132+
133+
# If everything is still okay, compute checksums file
134+
if [ "$bad" = 0 ]; then
135+
sha256sum "$path_bin"/from-source/* | sed -e "s|$PWD/||g" -e 's|from-source/||g' > "$path_bin/_sha256sums"
136+
137+
printf 'Checksums computed - %s\n' "$path_bin/_sha256sums"
138+
fi

0 commit comments

Comments
 (0)