ci/scripts: refactor reproducible builds (#1490)

* ci: build cache, remove 20.04, minor refactor

* scripts: update build reproducibility script

* script: add postgresql reproducibility

* script: no cache when building image

* scripts: force symlinks

* scripts: also download prebuilt postgresql binary

* scripts: add missing app var
This commit is contained in:
sh
2025-03-22 13:27:11 +00:00
committed by GitHub
parent 614fa2b163
commit 2e67ed9c4c
3 changed files with 117 additions and 35 deletions

View File

@@ -34,10 +34,7 @@ jobs:
include: include:
- os: 22.04 - os: 22.04
ghc: "8.10.7" ghc: "8.10.7"
platform_name: 20_04-x86-64 platform_name: 22_04-8.10.7
- os: 20.04
ghc: "9.6.3"
platform_name: 20_04-x86-64
- os: 22.04 - os: 22.04
ghc: "9.6.3" ghc: "9.6.3"
platform_name: 22_04-x86-64 platform_name: 22_04-x86-64
@@ -48,17 +45,54 @@ jobs:
- name: Clone project - name: Clone project
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Prepare image - name: Set up Docker Buildx
shell: bash uses: docker/setup-buildx-action@v3
run: docker build -f Dockerfile.build --build-arg TAG=${{ matrix.os }} --build-arg GHC=${{ matrix.ghc }} -t local .
- name: Build and cache Docker image
uses: docker/build-push-action@v6
with:
context: .
load: true
file: Dockerfile.build
tags: build/${{ matrix.platform_name }}:latest
cache-from: |
type=gha
type=gha,scope=master
cache-to: type=gha,mode=max
build-args: |
TAG=${{ matrix.os }}
GHC=${{ matrix.ghc }}
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cabal/store
dist-newstyle
key: ${{ matrix.os }}-${{ hashFiles('cabal.project', 'simplexmq.cabal') }}
- name: Start container - name: Start container
shell: bash shell: bash
run: docker run -t -d --name builder local run: |
docker run -t -d \
--name builder \
-v ~/.cabal:/root/.cabal \
-v /home/runner/work/_temp:/home/runner/work/_temp \
-v ${{ github.workspace }}:/project \
build/${{ matrix.platform_name }}:latest
- name: Build smp-server (postgresql) and tests - name: Build smp-server (postgresql) and tests
shell: bash shell: docker exec -t builder sh {0}
run: docker exec -t builder sh -c 'cabal build --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' run: |
cabal update
cabal build --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
- name: Copy simplexmq-test from container - name: Copy simplexmq-test from container
shell: bash shell: bash
@@ -72,15 +106,23 @@ jobs:
docker cp builder:/out/smp-server ./smp-server-postgres-ubuntu-${{ matrix.platform_name }} docker cp builder:/out/smp-server ./smp-server-postgres-ubuntu-${{ matrix.platform_name }}
- name: Build everything else (standard) - name: Build everything else (standard)
shell: bash shell: docker exec -t builder sh {0}
run: docker exec -t -e apps="$apps" builder sh -c 'cabal build && 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' run: |
cabal build
mkdir -p /out
for i in ${{ env.apps }}; do
bin=$(find /project/dist-newstyle -name "$i" -type f -executable)
strip "$bin"
chmod +x "$bin"
mv "$bin" /out/
done
- name: Copy binaries from container and prepare them - name: Copy binaries from container and prepare them
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
shell: bash shell: bash
run: | run: |
docker cp builder:/out . docker cp builder:/out .
for i in $apps; do mv ./out/$i ./$i-ubuntu-${{ matrix.platform_name }}; done for i in ${{ env.apps }}; do mv ./out/$i ./$i-ubuntu-${{ matrix.platform_name }}; done
- name: Build changelog - name: Build changelog
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')

View File

@@ -28,15 +28,4 @@ ENV PATH="/root/.cabal/bin:/root/.ghcup/bin:$PATH"
RUN ghcup set ghc "${GHC}" && \ RUN ghcup set ghc "${GHC}" && \
ghcup set cabal "${CABAL}" ghcup set cabal "${CABAL}"
# Copy only the source code
COPY apps /project/apps/
COPY cbits /project/cbits/
COPY src /project/src/
COPY tests /project/tests/
COPY cabal.project Setup.hs simplexmq.cabal LICENSE /project
WORKDIR /project WORKDIR /project
# Compile app
RUN cabal update

View File

@@ -1,30 +1,81 @@
#!/usr/bin/env sh #!/usr/bin/env sh
set -eu set -eu
tag="$1" TAG="$1"
git clone https://github.com/simplex-chat/simplexmq && cd simplexmq tempdir="$(mktemp -d)"
init_dir="$PWD"
git checkout "$tag" mkdir -p "$init_dir/$TAG/from-source" "$init_dir/$TAG/prebuilt"
git -C "$tempdir" clone https://github.com/simplex-chat/simplexmq.git &&\
cd "$tempdir/simplexmq" &&\
git checkout "$TAG"
for os in 20.04 22.04 24.04; do for os in 20.04 22.04 24.04; do
mkdir -p out-${os}-github; os_url="$(printf '%s' "$os" | tr '.' '_')"
mkdir -p "$init_dir/cache/cabal/builder-${os}" "$init_dir/cache/dist-newstyle/builder-${os}"
chmod g+wX "$init_dir/cache"
docker build -f Dockerfile.build --build-arg TAG=${os} -t repro-${os} . docker build \
docker run -t -d --name builder-${os} repro-${os} --no-cache \
-f "$tempdir/simplexmq/Dockerfile.build" \
--build-arg TAG=${os} \
-t repro-${os} \
.
docker run \
-t \
-d \
-v "$init_dir/cache/cabal/builder-${os}:/root/.cabal" \
-v "$init_dir/cache/dist-newstyle/builder-${os}:/dist-newstyle" \
-v "$tempdir/simplexmq:/project" \
--name builder-${os} \
repro-${os}
apps='smp-server xftp-server ntf-server xftp' apps='smp-server xftp-server ntf-server xftp'
os_url="$(printf '%s' "$os" | tr '.' '_')"
docker exec -t -e apps="$apps" builder-${os} sh -c 'cabal build && mkdir /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'
docker cp builder-${os}:/out out-${os} # Regular build (all)
docker exec \
-t \
-e apps="$apps" \
builder-${os} \
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'
docker cp \
builder-${os}:/out \
out-${os}
# PostgreSQL build (only smp-server)
docker exec \
-t \
builder-${os} \
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/'
docker cp \
builder-${os}:/out/smp-server \
"$init_dir/$TAG/from-source/smp-server-postgres-ubuntu-${os_url}-x86-64"
curl -L \
--output-dir "$init_dir/$TAG/prebuilt/" \
-O \
"https://github.com/simplex-chat/simplexmq/releases/download/${TAG}/smp-server-postgres-ubuntu-${os_url}-x86-64"
for app in $apps; do for app in $apps; do
curl -L "https://github.com/simplex-chat/simplexmq/releases/download/${tag}/${app}-ubuntu-${os_url}-x86-64" -o out-${os}-github/${app} curl -L \
--output-dir "$init_dir/$TAG/prebuilt/" \
-O \
"https://github.com/simplex-chat/simplexmq/releases/download/${TAG}/${app}-ubuntu-${os_url}-x86-64"
mv "./out-${os}/$app" "$init_dir/$TAG/from-source/${app}-ubuntu-${os_url}-x86-64"
done done
docker stop builder-${os} docker stop builder-${os}
docker rm builder-${os} docker rm builder-${os}
docker image rm repro-${os} docker image rm repro-${os}
done done
# Cleanup
cd "$init_dir"
rm -rf "$tempdir"