ci: cache build artifacts for faster builds (#7730)

* ci: cache build artifacts for faster builds

* test build

* compression

* fix macos-latest

* debug build

* better caching

* test cache

* update build

* test cache

* ci: check toolchain restore

* ci: remove Windows toolchain cache

* ci: skip tests on macOS Intel

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
EvgenyandEvgeny @ SimpleX Chat authored and GitHub committed 2026-10-17 17:12:08 +01:00
1 parent a932c8298a
commit 9a90d8e230
8 files changed
+818 -67

No files matched your search

+5 -15
View File
@@ -10,21 +10,19 @@ inputs:
github_ref:
required: true
description: "Git reference"
os:
required: true
description: "Target OS"
cache_path:
required: false
default: "~/.cabal/store"
description: "Cache path"
cabal_ver:
required: false
default: 3.10.2.0
description: "GHC version to install"
outputs:
cabal-store:
description: "Cabal store path"
value: ${{ steps.setup.outputs.cabal-store }}
runs:
using: "composite"
steps:
- name: Setup Haskell
id: setup
uses: simplex-chat/setup-haskell-action@v2
with:
ghc-version: ${{ inputs.ghc_ver }}
@@ -37,11 +35,3 @@ runs:
distribution: 'corretto'
java-version: ${{ inputs.java_ver }}
cache: 'gradle'
- name: Restore cached build
uses: actions/cache@v4
with:
path: |
${{ inputs.cache_path }}
dist-newstyle
key: ${{ inputs.os }}-ghc${{ inputs.ghc_ver }}-${{ hashFiles('cabal.project', 'simplex-chat.cabal') }}
+528 -45
View File
@@ -27,6 +27,14 @@ on:
- "scripts/desktop/**"
- ".github/**"
env:
opt: ${{ github.event_name == 'pull_request' && 'O0' || 'O2' }}
ghc_options: ${{ github.event_name == 'pull_request' && '--ghc-options=-O0' || '' }}
release: ${{ startsWith(github.ref, 'refs/tags/v') }}
branch: ${{ github.base_ref || github.ref_name }}
cache_o0: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/stable') }}
ZSTD_CLEVEL: 9
# This workflow uses custom actions (prepare-build and prepare-release) defined in:
#
# .github/actions/
@@ -162,6 +170,12 @@ jobs:
name: "ubuntu-${{ matrix.os }}-${{ matrix.arch }} (CLI,Desktop), GHC: ${{ matrix.ghc }}"
needs: [maybe-release, variables]
runs-on: ${{ matrix.runner }}
permissions:
contents: write
packages: write
env:
image_cache: ghcr.io/simplex-chat/simplex-chat-build-cache:${{ matrix.os }}-${{ matrix.arch }}-ghc${{ matrix.ghc }}
source_hashes: dist-newstyle/sources.sha256
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-linux-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.ghc }}-${{ needs.maybe-release.outputs.libs_tag }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/v') && !needs.maybe-release.outputs.libs_tag }}
@@ -231,19 +245,22 @@ jobs:
shell: bash
run: ./scripts/ci/linux_util_free_space.sh
- name: Restore cached build
if: matrix.should_run == true
uses: actions/cache@v4
with:
path: |
~/.cabal/store
dist-newstyle
key: ubuntu-${{ matrix.os }}-${{ matrix.arch }}-ghc${{ matrix.ghc }}-${{ hashFiles('cabal.project', 'simplex-chat.cabal') }}
- name: Set up Docker Buildx
if: matrix.should_run == true
uses: simplex-chat/docker-setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: matrix.should_run == true && env.release != 'true'
shell: bash
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: echo "$GHCR_TOKEN" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Compute image cache week
id: week
if: matrix.should_run == true && env.release != 'true'
run: echo "week=$(date -u +%G-W%V)" >> "$GITHUB_OUTPUT"
- name: Build and cache Docker image
if: matrix.should_run == true
uses: simplex-chat/docker-build-push-action@v6
@@ -258,6 +275,8 @@ jobs:
GHC=${{ matrix.ghc }}
USER_UID=${{ steps.ids.outputs.uid }}
USER_GID=${{ steps.ids.outputs.gid }}
cache-from: ${{ env.release != 'true' && format('type=registry,ref={0}-{1}', env.image_cache, steps.week.outputs.week) || '' }}
cache-to: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && format('type=registry,ref={0}-{1},mode=max,ignore-error=true', env.image_cache, steps.week.outputs.week) || '' }}
# Docker needs these flags for AppImage build:
# --device /dev/fuse
@@ -267,16 +286,94 @@ jobs:
if: matrix.should_run == true
shell: bash
run: |
mkdir -p ~/.cabal
docker run -t -d \
--device /dev/fuse \
--cap-add SYS_ADMIN \
--security-opt apparmor:unconfined \
--name builder \
-v ~/.cabal:/root/.cabal \
-e CABAL_DIR=/home/builder/.cabal \
-v ~/.cabal:/home/builder/.cabal \
-v /home/runner/work/_temp:/home/runner/work/_temp \
-v ${{ github.workspace }}:/project \
build/${{ matrix.os }}:latest
- name: Compute cache key prefixes
id: keys
if: matrix.should_run == true && env.release != 'true'
run: |
toolchain=$(docker exec builder dpkg-query -W -f '${db:Status-Status} ${binary:Package} ${Version}\n' 'binutils*' 'cpp*' 'gcc*' '*-dev' | grep '^installed ' | sha256sum | cut -c1-16)
target=ubuntu-${{ matrix.os }}-${{ matrix.arch }}-ghc${{ matrix.ghc }}-$toolchain
echo "deps=deps-$target" >> "$GITHUB_OUTPUT"
echo "dist=dist-$target" >> "$GITHUB_OUTPUT"
echo "dist_lib=dist-lib-$target" >> "$GITHUB_OUTPUT"
- name: Restore dependencies from cache
id: restore-deps
if: matrix.should_run == true && env.release != 'true'
uses: actions/cache/restore@v4
with:
path: ~/.cabal/store
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.deps }}-${{ env.branch }}-
${{ steps.keys.outputs.deps }}-
- name: Warn if dependencies not in cache
if: matrix.should_run == true && env.release != 'true' && steps.restore-deps.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.deps }}-${{ env.branch }}"
- name: Restore source repositories from cache
id: restore-src
if: matrix.should_run == true && env.release != 'true'
uses: actions/cache/restore@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
restore-keys: src-${{ runner.os }}-
- name: Warn if source repositories not in cache
if: matrix.should_run == true && env.release != 'true' && steps.restore-src.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::src-${{ runner.os }}"
- name: Restore build directory from cache
id: restore-build
if: matrix.should_run == true && env.release != 'true'
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-${{ env.opt }}-
- name: Warn if build directory not in cache
if: matrix.should_run == true && env.release != 'true' && steps.restore-build.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}"
- name: Restore library build directory from cache
id: restore-build-lib
if: env.release != 'true' && matrix.libs && needs.maybe-release.outputs.core_changed && matrix.arch == 'x86_64'
uses: actions/cache/restore@v4
with:
path: |
dist-lib/*
!dist-lib/src
key: ${{ steps.keys.outputs.dist_lib }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist_lib }}-${{ env.branch }}-
${{ steps.keys.outputs.dist_lib }}-
- name: Warn if library build directory not in cache
if: steps.restore-build-lib.outcome == 'success' && steps.restore-build-lib.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.dist_lib }}-${{ env.branch }}"
- name: Set old timestamps on unchanged sources (GHC 8.10.7)
if: matrix.ghc == '8.10.7' && steps.restore-build.outputs.cache-matched-key != '' && hashFiles(env.source_hashes) != ''
run: scripts/ci/source-timestamps.sh restore ${{ env.source_hashes }}
- name: Prepare cabal.project.local
if: matrix.should_run == true
shell: bash
@@ -285,33 +382,81 @@ jobs:
echo "package direct-sqlcipher" >> cabal.project.local
echo " flags: +openssl" >> cabal.project.local
# chmod/git commands are used to workaround permission issues when cache is restored
- name: Build CLI
id: build-cli
if: matrix.should_run == true
shell: docker exec -t builder sh -eu {0}
run: |
cabal clean
scripts/ci/prune-old-builds.sh dist-newstyle
cabal update
cabal build -j --enable-tests
cabal build -j --enable-tests ${{ env.ghc_options }}
mkdir -p /out
for i in simplex-chat simplex-chat-test; do
bin=$(find /project/dist-newstyle -name "$i" -type f -executable)
chmod +x "$bin"
mv "$bin" /out/
cp "$bin" /out/
done
strip /out/simplex-chat
# Also for pull requests that change the chat core, for the package tests (packages-pr).
- name: Build library
id: build-lib
if: matrix.libs && (needs.maybe-release.outputs.libs_tag || (needs.maybe-release.outputs.core_changed && matrix.arch == 'x86_64'))
shell: docker exec -t builder sh -eu {0}
run: |
SKIP_VLC=1 scripts/desktop/build-lib-linux.sh
scripts/ci/prune-old-builds.sh dist-lib
mkdir -p dist-lib
rm -rf dist-lib/src
ln -s ../dist-newstyle/src dist-lib/src
DIST_DIR=dist-lib SKIP_VLC=1 scripts/desktop/build-lib-linux.sh
name=simplex-chat-libs-linux-${{ matrix.arch }}
mkdir -p release-libs/$name/libs
find apps/multiplatform/common/src/commonMain/cpp/desktop/libs/linux-${{ matrix.arch }} -maxdepth 1 -type f -exec cp {} release-libs/$name/libs/ \;
(cd release-libs/$name && zip -r ../$name.zip libs)
- name: Record source hashes (GHC 8.10.7)
if: matrix.should_run == true && matrix.ghc == '8.10.7'
shell: docker exec -t builder sh -eu {0}
run: scripts/ci/source-timestamps.sh record ${{ env.source_hashes }}
- name: Compute dependency cache key
id: hash-deps
if: matrix.should_run == true && env.release != 'true'
shell: bash
run: echo "hash=$(ls ~/.cabal/store/ghc-*/ | sha256sum | cut -c1-16)" >> "$GITHUB_OUTPUT"
- name: Save dependencies to cache
if: matrix.should_run == true && env.release != 'true' && steps.restore-deps.outputs.cache-matched-key != format('{0}-{1}-{2}', steps.keys.outputs.deps, env.branch, steps.hash-deps.outputs.hash)
uses: actions/cache/save@v4
with:
path: ~/.cabal/store
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ steps.hash-deps.outputs.hash }}
- name: Save source repositories to cache
if: matrix.should_run == true && env.release != 'true' && matrix.libs && matrix.arch == 'x86_64' && steps.restore-src.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
- name: Save build directory to cache
if: matrix.should_run == true && env.release != 'true' && steps.restore-build.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
- name: Save library build directory to cache
if: steps.build-lib.outcome == 'success' && env.release != 'true' && steps.restore-build-lib.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
dist-lib/*
!dist-lib/src
key: ${{ steps.keys.outputs.dist_lib }}-${{ env.branch }}-${{ github.sha }}
- name: Upload library artifact
if: matrix.libs && needs.maybe-release.outputs.core_changed && matrix.arch == 'x86_64'
uses: actions/upload-artifact@v7
@@ -437,13 +582,6 @@ jobs:
github_ref: ${{ github.ref }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Fix permissions for cache
if: matrix.should_run == true
shell: bash
run: |
sudo chmod -R 777 dist-newstyle ~/.cabal
sudo chown -R $(id -u):$(id -g) dist-newstyle ~/.cabal
- name: Mount RAM disk for tests
if: matrix.should_run == true && matrix.arch == 'x86_64'
shell: bash
@@ -474,6 +612,51 @@ jobs:
exit 1
fi
- name: Remove -O2 build directory
id: remove-o2
if: env.cache_o0 == 'true' && !cancelled() && steps.build-cli.outcome == 'success'
shell: docker exec -t builder sh -eu {0}
run: find dist-newstyle -mindepth 1 -maxdepth 1 ! -name src -exec rm -rf {} +
- name: Restore -O0 build directory from cache
id: restore-build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-O0-
- name: Set old timestamps on unchanged sources for -O0 build (GHC 8.10.7)
if: ${{ !cancelled() && matrix.ghc == '8.10.7' && steps.restore-build-o0.outputs.cache-matched-key != '' && hashFiles(env.source_hashes) != '' }}
run: scripts/ci/source-timestamps.sh restore ${{ env.source_hashes }}
- name: Build at -O0 for pull request caches
id: build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
shell: docker exec -t builder sh -eu {0}
run: |
scripts/ci/prune-old-builds.sh dist-newstyle
cabal build -j --enable-tests --ghc-options=-O0
- name: Record source hashes for -O0 build (GHC 8.10.7)
if: ${{ !cancelled() && matrix.ghc == '8.10.7' && steps.build-o0.outcome == 'success' }}
shell: docker exec -t builder sh -eu {0}
run: scripts/ci/source-timestamps.sh record ${{ env.source_hashes }}
- name: Save -O0 build directory to cache
if: ${{ !cancelled() && steps.build-o0.outcome == 'success' && steps.restore-build-o0.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
# =================================
# Linux PostgreSQL Library Build
# =================================
@@ -497,14 +680,6 @@ jobs:
shell: bash
run: ./scripts/ci/linux_util_free_space.sh
- name: Restore cached build
uses: actions/cache@v4
with:
path: |
~/.cabal/store
dist-newstyle
key: ubuntu-22.04-x86_64-postgres-ghc${{ needs.variables.outputs.GHC_VER }}-${{ hashFiles('cabal.project', 'simplex-chat.cabal') }}
- name: Set up Docker Buildx
uses: simplex-chat/docker-setup-buildx-action@v3
@@ -525,13 +700,35 @@ jobs:
- name: Start container
shell: bash
run: |
mkdir -p ~/.cabal
docker run -t -d \
--name builder \
-v ~/.cabal:/root/.cabal \
-e CABAL_DIR=/home/builder/.cabal \
-v ~/.cabal:/home/builder/.cabal \
-v /home/runner/work/_temp:/home/runner/work/_temp \
-v ${{ github.workspace }}:/project \
build/22.04:latest
- name: Compute cache key prefix
id: keys
run: |
toolchain=$(docker exec builder dpkg-query -W -f '${db:Status-Status} ${binary:Package} ${Version}\n' 'binutils*' 'cpp*' 'gcc*' '*-dev' | grep '^installed ' | sha256sum | cut -c1-16)
echo "deps=deps-ubuntu-22.04-x86_64-postgres-ghc${{ needs.variables.outputs.GHC_VER }}-$toolchain" >> "$GITHUB_OUTPUT"
- name: Restore dependencies from cache
id: restore-deps
uses: actions/cache/restore@v4
with:
path: ~/.cabal/store
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.deps }}-${{ env.branch }}-
${{ steps.keys.outputs.deps }}-
- name: Warn if dependencies not in cache
if: steps.restore-deps.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.deps }}-${{ env.branch }}"
- name: Prepare cabal.project.local
shell: bash
run: |
@@ -542,10 +739,21 @@ jobs:
- name: Build postgres library
shell: docker exec -t builder sh -eu {0}
run: |
cabal clean
cabal update
scripts/desktop/build-lib-linux.sh postgres
- name: Compute dependency cache key
id: hash-deps
shell: bash
run: echo "hash=$(ls ~/.cabal/store/ghc-*/ | sha256sum | cut -c1-16)" >> "$GITHUB_OUTPUT"
- name: Save dependencies to cache
if: steps.restore-deps.outputs.cache-matched-key != format('{0}-{1}-{2}', steps.keys.outputs.deps, env.branch, steps.hash-deps.outputs.hash)
uses: actions/cache/save@v4
with:
path: ~/.cabal/store
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ steps.hash-deps.outputs.hash }}
- name: Copy libs from container
shell: bash
run: |
@@ -565,12 +773,6 @@ jobs:
files: postgres-libs/*.zip
token: ${{ secrets.NODEJS_REPO_TOKEN }}
- name: Fix permissions for cache
shell: bash
run: |
sudo chmod -R 777 dist-newstyle ~/.cabal
sudo chown -R $(id -u):$(id -g) dist-newstyle ~/.cabal
# =========================
# MacOS Build
# =========================
@@ -604,14 +806,49 @@ jobs:
with:
submodules: recursive
- name: Point Command Line Tools SDK to Xcode SDK
shell: bash
run: sudo ln -sfn "$(xcrun --sdk macosx --show-sdk-path)" /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
- name: Compute toolchain cache key
id: toolchain-key
if: env.release != 'true'
shell: bash
run: echo "key=ghcup-${{ matrix.os }}-${{ matrix.arch }}-ghc${{ matrix.ghc }}-cabal3.10.2.0-$({ sw_vers -productVersion; clang --version; } | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT"
- name: Restore toolchain from cache
id: restore-toolchain
if: env.release != 'true'
uses: actions/cache/restore@v4
with:
path: |
~/.ghcup/ghc/${{ matrix.ghc }}
~/.ghcup/bin/*-${{ matrix.ghc }}
~/.ghcup/bin/cabal-3.10.2.0
key: ${{ steps.toolchain-key.outputs.key }}
- name: Warn if toolchain not in cache
if: env.release != 'true' && steps.restore-toolchain.outputs.cache-hit != 'true'
run: echo "::warning title=Cache miss::${{ steps.toolchain-key.outputs.key }}"
- name: Prepare build
id: prepare
uses: ./.github/actions/prepare-build
with:
java_ver: ${{ needs.variables.outputs.JAVA_VER }}
ghc_ver: ${{ matrix.ghc }}
os: ${{ matrix.os }}
github_ref: ${{ github.ref }}
- name: Save toolchain to cache
if: env.release != 'true' && steps.restore-toolchain.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
~/.ghcup/ghc/${{ matrix.ghc }}
~/.ghcup/bin/*-${{ matrix.ghc }}
~/.ghcup/bin/cabal-3.10.2.0
key: ${{ steps.toolchain-key.outputs.key }}
- name: Install OpenSSL
run: brew install openssl@3.0
@@ -628,15 +865,100 @@ jobs:
echo " extra-lib-dirs: ${{ matrix.openssl_dir }}/openssl@3.0/lib" >> cabal.project.local
echo " flags: +openssl" >> cabal.project.local
- name: Compute cache key prefixes
id: keys
if: env.release != 'true'
shell: bash
run: |
toolchain=$({ sw_vers -productVersion; clang --version; } | shasum -a 256 | cut -c1-16)
target=${{ matrix.os }}-${{ matrix.arch }}-ghc${{ matrix.ghc }}-$toolchain
echo "deps=deps-$target" >> "$GITHUB_OUTPUT"
echo "dist=dist-$target" >> "$GITHUB_OUTPUT"
- name: Restore dependencies from cache
id: restore-deps
if: env.release != 'true'
uses: actions/cache/restore@v4
with:
path: ${{ steps.prepare.outputs.cabal-store }}
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.deps }}-${{ env.branch }}-
${{ steps.keys.outputs.deps }}-
- name: Warn if dependencies not in cache
if: env.release != 'true' && steps.restore-deps.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.deps }}-${{ env.branch }}"
- name: Restore source repositories from cache
id: restore-src
if: env.release != 'true'
uses: actions/cache/restore@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
restore-keys: src-${{ runner.os }}-
- name: Warn if source repositories not in cache
if: env.release != 'true' && steps.restore-src.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::src-${{ runner.os }}"
- name: Restore build directory from cache
id: restore-build
if: env.release != 'true' && !needs.maybe-release.outputs.libs_tag
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-${{ env.opt }}-
- name: Warn if build directory not in cache
if: steps.restore-build.outcome == 'success' && steps.restore-build.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}"
- name: Build CLI
id: mac_cli_build
shell: bash
run: |
cabal build -j --enable-tests
path=$(cabal list-bin simplex-chat)
scripts/ci/prune-old-builds.sh dist-newstyle
cabal build -j --enable-tests ${{ env.ghc_options }}
path=$(cabal list-bin simplex-chat | tail -n 1)
echo "bin_path=$path" >> $GITHUB_OUTPUT
echo "bin_hash=$(echo SHA2-256\(${{ matrix.cli_asset_name }}\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
- name: Compute dependency cache key
id: hash-deps
if: env.release != 'true'
shell: bash
run: echo "hash=$(ls '${{ steps.prepare.outputs.cabal-store }}'/ghc-*/ | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT"
- name: Save dependencies to cache
if: env.release != 'true' && steps.restore-deps.outputs.cache-matched-key != format('{0}-{1}-{2}', steps.keys.outputs.deps, env.branch, steps.hash-deps.outputs.hash)
uses: actions/cache/save@v4
with:
path: ${{ steps.prepare.outputs.cabal-store }}
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ steps.hash-deps.outputs.hash }}
- name: Save source repositories to cache
if: env.release != 'true' && matrix.arch == 'x86_64' && steps.restore-src.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
- name: Save build directory to cache
if: env.release != 'true' && steps.restore-build.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
- name: Upload CLI
if: startsWith(github.ref, 'refs/tags/v')
uses: ./.github/actions/prepare-release
@@ -673,6 +995,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Run tests
if: matrix.arch == 'aarch64'
timeout-minutes: 120
shell: bash
run: |
@@ -680,7 +1003,7 @@ jobs:
attempts=1
${{ (github.ref == 'refs/heads/stable' || startsWith(github.ref, 'refs/tags/v')) }} && attempts=3
while [ "$i" -le "$attempts" ]; do
if cabal test --test-show-details=direct; then
if cabal test --test-show-details=direct ${{ env.ghc_options }}; then
break
else
echo "Attempt $i failed, retrying..."
@@ -713,6 +1036,42 @@ jobs:
files: release-libs/*.zip
token: ${{ secrets.NODEJS_REPO_TOKEN }}
- name: Remove -O2 build directory
id: remove-o2
if: env.cache_o0 == 'true' && !cancelled() && steps.mac_cli_build.outcome == 'success'
shell: bash
run: find dist-newstyle -mindepth 1 -maxdepth 1 ! -name src -exec rm -rf {} +
- name: Restore -O0 build directory from cache
id: restore-build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-O0-
- name: Build at -O0 for pull request caches
id: build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
shell: bash
run: |
scripts/ci/prune-old-builds.sh dist-newstyle
cabal build -j --enable-tests --ghc-options=-O0
- name: Save -O0 build directory to cache
if: ${{ !cancelled() && steps.build-o0.outcome == 'success' && steps.restore-build-o0.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
# =========================
# Windows Build
# =========================
@@ -739,12 +1098,11 @@ jobs:
submodules: recursive
- name: Prepare build
id: prepare
uses: ./.github/actions/prepare-build
with:
java_ver: ${{ needs.variables.outputs.JAVA_VER }}
ghc_ver: ${{ matrix.ghc }}
os: ${{ matrix.os }}
cache_path: "C:/cabal"
github_ref: ${{ github.ref }}
- name: Configure pagefile (Windows)
@@ -768,6 +1126,61 @@ jobs:
toolchain:p
cmake:p
- name: Compute cache key prefixes
id: keys
if: env.release != 'true'
shell: msys2 {0}
run: |
toolchain=$(gcc --version | sha256sum | cut -c1-16)
target=windows-x86_64-ghc${{ matrix.ghc }}-$toolchain
echo "deps=deps-$target" >> "$GITHUB_OUTPUT"
echo "dist=dist-$target" >> "$GITHUB_OUTPUT"
- name: Restore dependencies from cache
id: restore-deps
if: env.release != 'true'
uses: actions/cache/restore@v4
with:
path: ${{ steps.prepare.outputs.cabal-store }}
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.deps }}-${{ env.branch }}-
${{ steps.keys.outputs.deps }}-
- name: Warn if dependencies not in cache
if: env.release != 'true' && steps.restore-deps.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.deps }}-${{ env.branch }}"
- name: Restore source repositories from cache
id: restore-src
if: env.release != 'true'
uses: actions/cache/restore@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
restore-keys: src-${{ runner.os }}-
- name: Warn if source repositories not in cache
if: env.release != 'true' && steps.restore-src.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::src-${{ runner.os }}"
- name: Restore build directory from cache
id: restore-build
if: env.release != 'true' && !needs.maybe-release.outputs.libs_tag
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-${{ env.opt }}-
- name: Warn if build directory not in cache
if: steps.restore-build.outcome == 'success' && steps.restore-build.outputs.cache-matched-key == ''
run: echo "::warning title=Cache miss::${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}"
# rm -rf dist-newstyle/src/{direct-sq,simplexmq}* is here because of the bug in cabal's dependency which prevents second build from finishing
# (simplexmq is removed because cabal cannot delete its read-only git submodule pack files - blst, libbbs - on Windows)
- name: Build CLI
@@ -784,14 +1197,44 @@ jobs:
echo " extra-include-dirs: $openssl_windows_style_path\include" >> cabal.project.local
echo " extra-lib-dirs: $openssl_windows_style_path" >> cabal.project.local
scripts/ci/prune-old-builds.sh dist-newstyle
rm -rf dist-newstyle/src/direct-sq* dist-newstyle/src/simplexmq*
sed -i "s/, unix /--, unix /" simplex-chat.cabal
cabal build -j --enable-tests
cabal build -j --enable-tests ${{ env.ghc_options }}
rm -rf dist-newstyle/src/direct-sq* dist-newstyle/src/simplexmq*
path=$(cabal list-bin simplex-chat | tail -n 1)
echo "bin_path=$path" >> $GITHUB_OUTPUT
echo "bin_hash=$(echo SHA2-256\(${{ matrix.cli_asset_name }}\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
- name: Compute dependency cache key
id: hash-deps
if: env.release != 'true'
shell: msys2 {0}
run: echo "hash=$(ls "$(cygpath -u '${{ steps.prepare.outputs.cabal-store }}')"/ghc-*/ | sha256sum | cut -c1-16)" >> "$GITHUB_OUTPUT"
- name: Save dependencies to cache
if: env.release != 'true' && steps.restore-deps.outputs.cache-matched-key != format('{0}-{1}-{2}', steps.keys.outputs.deps, env.branch, steps.hash-deps.outputs.hash)
uses: actions/cache/save@v4
with:
path: ${{ steps.prepare.outputs.cabal-store }}
key: ${{ steps.keys.outputs.deps }}-${{ env.branch }}-${{ steps.hash-deps.outputs.hash }}
- name: Save source repositories to cache
if: env.release != 'true' && steps.restore-src.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: dist-newstyle/src
key: src-${{ runner.os }}-${{ hashFiles('cabal.project') }}
- name: Save build directory to cache
if: env.release != 'true' && steps.restore-build.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-${{ env.opt }}-${{ env.branch }}-${{ github.sha }}
- name: Build library
if: needs.maybe-release.outputs.libs_tag
shell: msys2 {0}
@@ -848,6 +1291,46 @@ jobs:
github_ref: ${{ github.ref }}
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Remove -O2 build directory
id: remove-o2
if: env.cache_o0 == 'true' && !needs.maybe-release.outputs.libs_tag && !cancelled() && steps.windows_cli_build.outcome == 'success'
shell: msys2 {0}
run: find dist-newstyle -mindepth 1 -maxdepth 1 ! -name src -exec rm -rf {} +
- name: Restore -O0 build directory from cache
id: restore-build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
uses: actions/cache/restore@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
restore-keys: |
${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-
${{ steps.keys.outputs.dist }}-O0-
- name: Build at -O0 for pull request caches
id: build-o0
if: ${{ !cancelled() && steps.remove-o2.outcome == 'success' }}
shell: msys2 {0}
run: |
export PATH=$PATH:/c/ghcup/bin:$(echo /c/tools/ghc-*/bin || echo)
scripts/desktop/prepare-openssl-windows.sh
scripts/ci/prune-old-builds.sh dist-newstyle
rm -rf dist-newstyle/src/direct-sq* dist-newstyle/src/simplexmq*
cabal build -j --enable-tests --ghc-options=-O0
rm -rf dist-newstyle/src/direct-sq* dist-newstyle/src/simplexmq*
- name: Save -O0 build directory to cache
if: ${{ !cancelled() && steps.build-o0.outcome == 'success' && steps.restore-build-o0.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: |
dist-newstyle/*
!dist-newstyle/src
key: ${{ steps.keys.outputs.dist }}-O0-${{ env.branch }}-${{ github.sha }}
# =========================
# Packages release
# =========================