diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf051bf3f..3eca8742f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,9 +11,10 @@ on: jobs: build: - name: build-${{ matrix.os }}-${{ matrix.ghc }} - runs-on: ${{ matrix.os }} - + name: "Ubuntu: ${{ matrix.os }}, GHC: ${{ matrix.ghc }}" + env: + apps: "smp-server xftp-server ntf-server xftp" + runs-on: ubuntu-${{ matrix.os }} services: postgres: image: postgres:15 @@ -27,62 +28,49 @@ jobs: ports: # Maps tcp port 5432 on service container to the host - 5432:5432 - strategy: fail-fast: false matrix: include: - - os: ubuntu-20.04 - platform_name: 20_04-x86-64 + - os: 22.04 ghc: "8.10.7" - - os: ubuntu-20.04 platform_name: 20_04-x86-64 + - os: 20.04 + ghc: "9.6.3" + platform_name: 20_04-x86-64 + - os: 22.04 ghc: "9.6.3" - - os: ubuntu-22.04 platform_name: 22_04-x86-64 + - os: 24.04 ghc: "9.6.3" + platform_name: 24_04-x86-64 steps: - name: Clone project uses: actions/checkout@v3 - - name: Setup Haskell - uses: haskell-actions/setup@v2 - with: - ghc-version: ${{ matrix.ghc }} - cabal-version: "3.10.1.0" - - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: | - ~/.cabal/store - dist-newstyle - key: ${{ matrix.os }}-${{ hashFiles('cabal.project', 'simplexmq.cabal') }} - - - name: Build + - name: Prepare image shell: bash - run: cabal build --enable-tests + run: docker build -f Dockerfile.build --build-arg TAG=${{ matrix.os }} --build-arg GHC=${{ matrix.ghc }} -t local . - - name: Test - timeout-minutes: 40 + - name: Start container shell: bash - run: cabal test --test-show-details=direct - env: - PGHOST: localhost + run: docker run -t -d --name builder local - - name: Prepare binaries + - name: Build binaries + shell: bash + run: docker exec -t -e apps="$apps" builder sh -c 'cabal build --enable-tests && 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' + + - name: Copy binaries from container and prepare them if: startsWith(github.ref, 'refs/tags/v') shell: bash run: | - mv $(cabal list-bin smp-server) smp-server-ubuntu-${{ matrix.platform_name}} - mv $(cabal list-bin ntf-server) ntf-server-ubuntu-${{ matrix.platform_name}} - mv $(cabal list-bin xftp-server) xftp-server-ubuntu-${{ matrix.platform_name}} - mv $(cabal list-bin xftp) xftp-ubuntu-${{ matrix.platform_name}} + docker cp builder:/out . + for i in $apps; do mv ./out/$i ./$i-ubuntu-${{ matrix.platform_name }}; done - name: Build changelog if: startsWith(github.ref, 'refs/tags/v') id: build_changelog - uses: mikepenz/release-changelog-builder-action@v1 + uses: mikepenz/release-changelog-builder-action@v5 with: configuration: .github/changelog_conf.json failOnError: true @@ -93,7 +81,7 @@ jobs: - name: Create release if: startsWith(github.ref, 'refs/tags/v') && matrix.ghc != '8.10.7' - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: body: | See full changelog [here](https://github.com/simplex-chat/simplexmq/blob/master/CHANGELOG.md). @@ -103,10 +91,19 @@ jobs: prerelease: true files: | LICENSE - smp-server-ubuntu-${{ matrix.platform_name}} - ntf-server-ubuntu-${{ matrix.platform_name}} - xftp-server-ubuntu-${{ matrix.platform_name}} - xftp-ubuntu-${{ matrix.platform_name}} + smp-server-ubuntu-${{ matrix.platform_name }} + ntf-server-ubuntu-${{ matrix.platform_name }} + xftp-server-ubuntu-${{ matrix.platform_name }} + xftp-ubuntu-${{ matrix.platform_name }} fail_on_unmatched_files: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Test + shell: bash + env: + PGHOST: localhost + run: | + docker exec -t builder sh -c 'mv $(find /project/dist-newstyle -name "simplexmq-test" -type f -executable) /out/' + docker cp builder:/out/simplexmq-test . + ./simplexmq-test diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 000000000..fb7678f44 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,42 @@ +# syntax=docker/dockerfile:1.7.0-labs +ARG TAG=24.04 +FROM ubuntu:${TAG} AS build + +### Build stage + +ARG GHC=9.6.3 +ARG CABAL=3.14.1.1 + +# Install curl, git and and simplexmq dependencies +RUN apt-get update && apt-get install -y curl git sqlite3 libsqlite3-dev build-essential libgmp3-dev zlib1g-dev llvm llvm-dev libnuma-dev libssl-dev + +# Specify bootstrap Haskell versions +ENV BOOTSTRAP_HASKELL_GHC_VERSION=${GHC} +ENV BOOTSTRAP_HASKELL_CABAL_VERSION=${CABAL} + +# Do not install Stack +ENV BOOTSTRAP_HASKELL_INSTALL_NO_STACK=true +ENV BOOTSTRAP_HASKELL_INSTALL_NO_STACK_HOOK=true + +# Install ghcup +RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 sh + +# Adjust PATH +ENV PATH="/root/.cabal/bin:/root/.ghcup/bin:$PATH" + +# Set both as default +RUN ghcup set ghc "${GHC}" && \ + 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 + +# Compile app +RUN cabal update diff --git a/scripts/reproduce-builds.sh b/scripts/reproduce-builds.sh new file mode 100755 index 000000000..eb35287ae --- /dev/null +++ b/scripts/reproduce-builds.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env sh +set -eu + +tag="$1" + +git clone https://github.com/simplex-chat/simplexmq && cd simplexmq + +git checkout "$tag" + +for os in 20.04 22.04 24.04; do + mkdir -p out-${os}-github; + + docker build -f Dockerfile.build --build-arg TAG=${os} -t repro-${os} . + docker run -t -d --name builder-${os} repro-${os} + + 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} + + 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} + done + + docker stop builder-${os} + docker rm builder-${os} + docker image rm repro-${os} +done diff --git a/simplexmq.cabal b/simplexmq.cabal index d8a38e5ed..457394f72 100644 --- a/simplexmq.cabal +++ b/simplexmq.cabal @@ -1,7 +1,7 @@ cabal-version: 1.12 name: simplexmq -version: 6.3.0.6 +version: 6.3.0.8 synopsis: SimpleXMQ message broker description: This package includes <./docs/Simplex-Messaging-Server.html server>, <./docs/Simplex-Messaging-Client.html client> and diff --git a/src/Simplex/Messaging/Protocol.hs b/src/Simplex/Messaging/Protocol.hs index 679f077b7..122246868 100644 --- a/src/Simplex/Messaging/Protocol.hs +++ b/src/Simplex/Messaging/Protocol.hs @@ -1818,9 +1818,9 @@ tDecodeParseValidate THandleParams {sessionId, thVersion = v, implySessId} = \ca $(J.deriveJSON defaultJSON ''MsgFlags) -$(J.deriveJSON (taggedObjectJSON id) ''CommandError) +$(J.deriveJSON (sumTypeJSON id) ''CommandError) -$(J.deriveJSON (taggedObjectJSON id) ''BrokerErrorType) +$(J.deriveJSON (sumTypeJSON id) ''BrokerErrorType) $(J.deriveJSON defaultJSON ''BlockingInfo) diff --git a/tests/ServerTests.hs b/tests/ServerTests.hs index 5160070f0..c0232ec0f 100644 --- a/tests/ServerTests.hs +++ b/tests/ServerTests.hs @@ -871,7 +871,7 @@ testTiming = (C.AuthAlg C.SX25519, C.AuthAlg C.SX25519, 200) -- correct key type ] timeRepeat n = fmap fst . timeItT . forM_ (replicate n ()) . const - similarTime t1 t2 = abs (t2 / t1 - 1) < 0.25 -- normally the difference between "no queue" and "wrong key" is less than 5% + similarTime t1 t2 = abs (t2 / t1 - 1) < 0.30 -- normally the difference between "no queue" and "wrong key" is less than 5% testSameTiming :: forall c. Transport c => THandleSMP c 'TClient -> THandleSMP c 'TClient -> (C.AuthAlg, C.AuthAlg, Int) -> Expectation testSameTiming rh sh (C.AuthAlg goodKeyAlg, C.AuthAlg badKeyAlg, n) = do g <- C.newRandom