mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-22 10:32:27 +00:00
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
1406 lines
57 KiB
YAML
1406 lines
57 KiB
YAML
name: build
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- master
|
|
- stable
|
|
tags:
|
|
- "v*"
|
|
- "!*-fdroid"
|
|
- "!*-armv7a"
|
|
pull_request:
|
|
paths:
|
|
- "src/**"
|
|
- "apps/simplex-chat/**"
|
|
- "apps/simplex-bot/**"
|
|
- "apps/simplex-bot-advanced/**"
|
|
- "apps/simplex-badge-service/**"
|
|
- "apps/simplex-broadcast-bot/**"
|
|
- "apps/simplex-directory-service/**"
|
|
- "tests/**"
|
|
- "bots/src/**"
|
|
- "simplex-chat.cabal"
|
|
- "cabal.project"
|
|
- "Dockerfile*"
|
|
- "scripts/ci/**"
|
|
- "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/
|
|
# ├── prepare-build
|
|
# │ └── action.yml
|
|
# └── prepare-release
|
|
# └── action.yml
|
|
|
|
# Important!
|
|
# Do not use always(), it makes build unskippable.
|
|
# See: https://github.com/actions/runner/issues/1846#issuecomment-1246102753
|
|
|
|
jobs:
|
|
|
|
# =============================
|
|
# Global variables
|
|
# =============================
|
|
|
|
# That is the only and less hacky way to setup global variables
|
|
# to use in strategy matrix (env:/YAML anchors doesn't work).
|
|
# See: https://github.com/orgs/community/discussions/56787#discussioncomment-6041789
|
|
# https://github.com/actions/runner/issues/1182
|
|
# https://stackoverflow.com/a/77549656
|
|
|
|
variables:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
GHC_VER: 9.6.3
|
|
JAVA_VER: 17
|
|
steps:
|
|
- name: Dummy job when we have just simple variables
|
|
if: false
|
|
run: echo
|
|
|
|
# =============================
|
|
# Create release
|
|
# =============================
|
|
|
|
# Create release, but only if it's triggered by tag push.
|
|
# Create simplex-chat-libs release core-<version>, but only if the head commit of a push to master or stable changes the version in simplex-chat.cabal.
|
|
# On pull requests and other pushes, this job will always complete.
|
|
|
|
# Secrets:
|
|
# -------
|
|
# NODEJS_REPO_TOKEN
|
|
# Only select repositories: simplex-chat-libs
|
|
# Permissions:
|
|
# * Contents (Read and Write)
|
|
|
|
maybe-release:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
libs_tag: ${{ steps.libs_commit.outputs.tag }}
|
|
core_changed: ${{ steps.core.outputs.core }}
|
|
steps:
|
|
- name: Clone project
|
|
if: github.event_name == 'push' || github.event_name == 'pull_request'
|
|
uses: actions/checkout@v3
|
|
with:
|
|
fetch-depth: 2
|
|
|
|
- name: Check chat core change
|
|
id: core
|
|
if: github.event_name == 'pull_request'
|
|
env:
|
|
BASE: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
git fetch -q --depth=1 origin "$BASE"
|
|
python3 scripts/ci/packages_release.py changes "$BASE" | grep '^core=' >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Build changelog
|
|
id: build_changelog
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: simplex-chat/release-changelog-builder-action@v5
|
|
with:
|
|
configuration: .github/changelog_conf.json
|
|
failOnError: true
|
|
ignorePreReleases: true
|
|
commitMode: true
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Create release
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: simplex-chat/action-gh-release@v2
|
|
with:
|
|
body: ${{ steps.build_changelog.outputs.changelog }}
|
|
prerelease: true
|
|
files: |
|
|
LICENSE
|
|
fail_on_unmatched_files: true
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Check version change
|
|
id: check_version
|
|
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/stable'
|
|
shell: bash
|
|
run: |
|
|
version=$(sed -n 's/^version: *//p' simplex-chat.cabal)
|
|
prev_version=$(git show HEAD^1:simplex-chat.cabal | sed -n 's/^version: *//p')
|
|
if [ "$version" != "$prev_version" ]; then
|
|
echo "version=$version" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Record libs release
|
|
id: libs_commit
|
|
if: steps.check_version.outputs.version
|
|
env:
|
|
GH_TOKEN: ${{ secrets.NODEJS_REPO_TOKEN }}
|
|
LIBS_REPOSITORY: ${{ github.repository }}-libs
|
|
VERSION: ${{ steps.check_version.outputs.version }}
|
|
run: |
|
|
commit=$(python3 scripts/ci/packages_release.py record --core "$VERSION" --commit "$GITHUB_SHA")
|
|
echo "tag=core-$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "commit=$commit" >> "$GITHUB_OUTPUT"
|
|
|
|
# creates the tag on the commit that recorded the release
|
|
- name: Create libs release
|
|
if: steps.check_version.outputs.version
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
repository: ${{ github.repository }}-libs
|
|
tag_name: ${{ steps.libs_commit.outputs.tag }}
|
|
target_commitish: ${{ steps.libs_commit.outputs.commit }}
|
|
token: ${{ secrets.NODEJS_REPO_TOKEN }}
|
|
|
|
# =========================
|
|
# Linux Build
|
|
# =========================
|
|
|
|
build-linux:
|
|
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: &linux-concurrency
|
|
group: ${{ github.workflow }}-${{ github.ref }}-linux-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.ghc }}-${{ needs.maybe-release.outputs.libs_tag }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: 22.04
|
|
os_underscore: 22_04
|
|
arch: x86_64
|
|
runner: "ubuntu-22.04"
|
|
ghc: "8.10.7"
|
|
hash: 'sha256:5c8b2c0a6c745bc177669abfaa716b4bc57d58e2ea3882fb5da67f4d59e3dda5'
|
|
should_run: ${{ !(github.ref == 'refs/heads/stable' || startsWith(github.ref, 'refs/tags/v')) }}
|
|
- os: 22.04
|
|
os_underscore: 22_04
|
|
arch: x86_64
|
|
runner: "ubuntu-22.04"
|
|
should_run: true
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
hash: 'sha256:5c8b2c0a6c745bc177669abfaa716b4bc57d58e2ea3882fb5da67f4d59e3dda5'
|
|
libs: true
|
|
- os: 24.04
|
|
os_underscore: 24_04
|
|
arch: x86_64
|
|
runner: "ubuntu-24.04"
|
|
should_run: true
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
hash: 'sha256:98ff7968124952e719a8a69bb3cccdd217f5fe758108ac4f21ad22e1df44d237'
|
|
steps: &linux-steps
|
|
- name: Checkout Code
|
|
if: matrix.should_run == true
|
|
uses: actions/checkout@v3
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Setup swap
|
|
if: matrix.ghc == '8.10.7' && matrix.should_run == true
|
|
uses: ./.github/actions/swap
|
|
with:
|
|
swap-size-gb: 30
|
|
|
|
- name: Get UID and GID
|
|
id: ids
|
|
run: |
|
|
echo "uid=$(id -u)" >> $GITHUB_OUTPUT
|
|
echo "gid=$(id -g)" >> $GITHUB_OUTPUT
|
|
|
|
# Otherwise we run out of disk space with Docker build
|
|
- name: Free disk space
|
|
if: matrix.should_run == true
|
|
shell: bash
|
|
run: ./scripts/ci/linux_util_free_space.sh
|
|
|
|
- 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
|
|
with:
|
|
context: .
|
|
load: true
|
|
file: Dockerfile.build
|
|
tags: build/${{ matrix.os }}:latest
|
|
build-args: |
|
|
TAG=${{ matrix.os }}
|
|
HASH=${{ matrix.hash }}
|
|
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
|
|
# --cap-add SYS_ADMIN
|
|
# --security-opt apparmor:unconfined
|
|
- name: Start container
|
|
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 \
|
|
-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
|
|
run: |
|
|
echo "ignore-project: False" >> cabal.project.local
|
|
echo "package direct-sqlcipher" >> cabal.project.local
|
|
echo " flags: +openssl" >> cabal.project.local
|
|
|
|
- name: Build CLI
|
|
id: build-cli
|
|
if: matrix.should_run == true
|
|
shell: docker exec -t builder sh -eu {0}
|
|
run: |
|
|
scripts/ci/prune-old-builds.sh dist-newstyle
|
|
cabal update
|
|
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"
|
|
cp "$bin" /out/
|
|
done
|
|
strip /out/simplex-chat
|
|
|
|
# Also for pull requests that change the chat core, for the package tests.
|
|
- 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: |
|
|
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
|
|
if: needs.maybe-release.outputs.libs_tag && matrix.libs
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
repository: ${{ github.repository }}-libs
|
|
tag_name: ${{ needs.maybe-release.outputs.libs_tag }}
|
|
files: release-libs/*.zip
|
|
token: ${{ secrets.NODEJS_REPO_TOKEN }}
|
|
|
|
- name: Build CLI deb
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
shell: docker exec -t builder sh -eu {0}
|
|
run: |
|
|
version=${{ github.ref }}
|
|
version=${version#refs/tags/v}
|
|
version=${version%-*}
|
|
|
|
./scripts/desktop/build-cli-deb.sh "$version"
|
|
|
|
- name: Copy tests from container
|
|
if: matrix.should_run == true
|
|
shell: bash
|
|
run: |
|
|
docker cp builder:/out/simplex-chat-test .
|
|
|
|
- name: Copy CLI from container and prepare it
|
|
id: linux_cli_prepare
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
shell: bash
|
|
run: |
|
|
cli_name="simplex-chat-ubuntu-${{ matrix.os_underscore }}-${{ matrix.arch }}"
|
|
cli_deb_name="${cli_name}.deb"
|
|
cli_path="${{ github.workspace }}"
|
|
|
|
docker cp builder:/out/simplex-chat "./${cli_name}"
|
|
docker cp builder:/out/deb-build/simplex-chat.deb "./${cli_deb_name}"
|
|
|
|
echo "bin_name=${cli_name}" >> $GITHUB_OUTPUT
|
|
echo "bin_path=${cli_path}/${cli_name}" >> $GITHUB_OUTPUT
|
|
echo "bin_hash=$(echo SHA2-256\(${cli_name}\)= $(openssl sha256 "${cli_path}/${cli_name}" | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
echo "deb_name=${cli_deb_name}" >> $GITHUB_OUTPUT
|
|
echo "deb_path=${cli_path}/${cli_deb_name}" >> $GITHUB_OUTPUT
|
|
echo "deb_hash=$(echo SHA2-256\(${cli_deb_name}\)= $(openssl sha256 "${cli_path}/${cli_deb_name}" | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload CLI
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_name: ${{ steps.linux_cli_prepare.outputs.bin_name }}
|
|
bin_path: ${{ steps.linux_cli_prepare.outputs.bin_path }}
|
|
bin_hash: ${{ steps.linux_cli_prepare.outputs.bin_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Upload CLI deb
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_name: ${{ steps.linux_cli_prepare.outputs.deb_name }}
|
|
bin_path: ${{ steps.linux_cli_prepare.outputs.deb_path }}
|
|
bin_hash: ${{ steps.linux_cli_prepare.outputs.deb_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build Desktop
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
shell: docker exec -t builder sh -eu {0}
|
|
run: |
|
|
export ASSETS_DIR='../../assets'
|
|
scripts/desktop/make-deb-linux.sh
|
|
|
|
- name: Prepare Desktop
|
|
id: linux_desktop_build
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
shell: bash
|
|
run: |
|
|
path=$(echo ${{ github.workspace }}/apps/multiplatform/release/main/deb/simplex_${{ matrix.arch }}.deb )
|
|
echo "package_path=$path" >> $GITHUB_OUTPUT
|
|
echo "package_hash=$(echo SHA2-256\(simplex-desktop-ubuntu-${{ matrix.os_underscore }}-${{ matrix.arch }}.deb\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload Desktop
|
|
uses: ./.github/actions/prepare-release
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.should_run == true
|
|
with:
|
|
bin_path: ${{ steps.linux_desktop_build.outputs.package_path }}
|
|
bin_name: simplex-desktop-ubuntu-${{ matrix.os_underscore }}-${{ matrix.arch }}.deb
|
|
bin_hash: ${{ steps.linux_desktop_build.outputs.package_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build AppImage
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == '22.04' && matrix.should_run == true
|
|
shell: docker exec -t builder sh -eu {0}
|
|
run: |
|
|
export ASSETS_DIR='../../assets'
|
|
scripts/desktop/make-appimage-linux.sh
|
|
|
|
- name: Prepare AppImage
|
|
id: linux_appimage_build
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == '22.04' && matrix.should_run == true
|
|
shell: bash
|
|
run: |
|
|
path=$(echo ${{ github.workspace }}/apps/multiplatform/release/main/*imple*.AppImage)
|
|
echo "appimage_path=$path" >> $GITHUB_OUTPUT
|
|
echo "appimage_hash=$(echo SHA2-256\(simplex-desktop-${{ matrix.arch }}.AppImage\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload AppImage
|
|
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == '22.04' && matrix.should_run == true
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_path: ${{ steps.linux_appimage_build.outputs.appimage_path }}
|
|
bin_name: "simplex-desktop-${{ matrix.arch }}.AppImage"
|
|
bin_hash: ${{ steps.linux_appimage_build.outputs.appimage_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Mount RAM disk for tests
|
|
if: matrix.should_run == true && matrix.arch == 'x86_64'
|
|
shell: bash
|
|
run: |
|
|
mkdir -p tests/tmp
|
|
sudo mount -t tmpfs -o size=512M tmpfs tests/tmp
|
|
sudo chown $(id -u):$(id -g) tests/tmp
|
|
|
|
- name: Run tests
|
|
if: matrix.should_run == true && matrix.arch == 'x86_64'
|
|
timeout-minutes: 120
|
|
shell: bash
|
|
run: |
|
|
i=1
|
|
attempts=1
|
|
${{ (github.ref == 'refs/heads/stable' || startsWith(github.ref, 'refs/tags/v')) }} && attempts=3
|
|
while [ "$i" -le "$attempts" ]; do
|
|
if ./simplex-chat-test; then
|
|
break
|
|
else
|
|
echo "Attempt $i failed, retrying..."
|
|
i=$((i + 1))
|
|
sleep 1
|
|
fi
|
|
done
|
|
if [ "$i" -gt "$attempts" ]; then
|
|
echo "All "$attempts" attempts failed."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Setup Node.js
|
|
id: setup-node
|
|
if: ${{ !cancelled() && needs.maybe-release.outputs.core_changed && steps.build-lib.outcome == 'success' }}
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 22
|
|
|
|
- name: Setup Python
|
|
id: setup-python
|
|
if: ${{ !cancelled() && steps.setup-node.outcome == 'success' }}
|
|
uses: actions/setup-python@v7
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Build simplex-chat (npm) and add-on
|
|
id: build-nodejs
|
|
if: ${{ !cancelled() && steps.setup-python.outcome == 'success' }}
|
|
shell: bash
|
|
working-directory: packages/simplex-chat-nodejs
|
|
run: |
|
|
(cd ../simplex-chat-client/types/typescript && npm install --no-audit --no-fund && npx tsc)
|
|
npm install --ignore-scripts --no-save --no-audit --no-fund ../simplex-chat-client/types/typescript
|
|
npx --yes node-gyp rebuild
|
|
npx tsc && cp src/simplex.* dist
|
|
|
|
- name: Test simplex-chat (npm)
|
|
id: test-nodejs
|
|
if: ${{ !cancelled() && steps.build-nodejs.outcome == 'success' }}
|
|
timeout-minutes: 30
|
|
shell: bash
|
|
working-directory: packages/simplex-chat-nodejs
|
|
env:
|
|
SIMPLEX_LIBS_DIR: ${{ github.workspace }}/release-libs/simplex-chat-libs-linux-${{ matrix.arch }}/libs
|
|
run: npx jest --forceExit --testNamePattern '^(?!.*use preset servers)'
|
|
|
|
- name: Test simplex-chat (PyPI)
|
|
if: ${{ !cancelled() && steps.test-nodejs.outcome == 'success' }}
|
|
timeout-minutes: 30
|
|
shell: bash
|
|
working-directory: packages/simplex-chat-python
|
|
run: |
|
|
python -m pip install -e ".[test]"
|
|
python -m pytest -q
|
|
|
|
- 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 }}
|
|
|
|
build-linux-push:
|
|
name: "ubuntu-${{ matrix.os }}-${{ matrix.arch }} (CLI,Desktop), GHC: ${{ matrix.ghc }}"
|
|
needs: [maybe-release, variables]
|
|
if: github.event_name != 'pull_request'
|
|
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
|
|
cache_o0: false
|
|
concurrency: *linux-concurrency
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: 22.04
|
|
os_underscore: 22_04
|
|
arch: aarch64
|
|
runner: "ubuntu-22.04-arm"
|
|
should_run: true
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
hash: 'sha256:6a62a4157b8775eaf4959cb629e757d32d39d1f4c8ac1b0ddc2510b555cf72f3'
|
|
libs: true
|
|
- os: 24.04
|
|
os_underscore: 24_04
|
|
arch: aarch64
|
|
runner: "ubuntu-24.04-arm"
|
|
should_run: true
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
hash: 'sha256:68434214381cb38287104e629fe8ee720167dd98cbb36ab1cbbab342515fa6ab'
|
|
steps: *linux-steps
|
|
|
|
# =================================
|
|
# Linux PostgreSQL Library Build
|
|
# =================================
|
|
|
|
build-linux-postgres:
|
|
name: "ubuntu-22.04-x86_64 (Postgres lib), GHC: ${{ needs.variables.outputs.GHC_VER }}"
|
|
needs: [maybe-release, variables]
|
|
runs-on: ubuntu-22.04
|
|
if: needs.maybe-release.outputs.libs_tag
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Get UID and GID
|
|
id: ids
|
|
run: |
|
|
echo "uid=$(id -u)" >> $GITHUB_OUTPUT
|
|
echo "gid=$(id -g)" >> $GITHUB_OUTPUT
|
|
|
|
- name: Free disk space
|
|
shell: bash
|
|
run: ./scripts/ci/linux_util_free_space.sh
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: simplex-chat/docker-setup-buildx-action@v3
|
|
|
|
- name: Build and cache Docker image
|
|
uses: simplex-chat/docker-build-push-action@v6
|
|
with:
|
|
context: .
|
|
load: true
|
|
file: Dockerfile.build
|
|
tags: build/22.04:latest
|
|
build-args: |
|
|
TAG=22.04
|
|
HASH=sha256:5c8b2c0a6c745bc177669abfaa716b4bc57d58e2ea3882fb5da67f4d59e3dda5
|
|
GHC=${{ needs.variables.outputs.GHC_VER }}
|
|
USER_UID=${{ steps.ids.outputs.uid }}
|
|
USER_GID=${{ steps.ids.outputs.gid }}
|
|
|
|
- name: Start container
|
|
shell: bash
|
|
run: |
|
|
mkdir -p ~/.cabal
|
|
docker run -t -d \
|
|
--name builder \
|
|
-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: |
|
|
echo "ignore-project: False" >> cabal.project.local
|
|
echo "package direct-sqlcipher" >> cabal.project.local
|
|
echo " flags: +openssl" >> cabal.project.local
|
|
|
|
- name: Build postgres library
|
|
shell: docker exec -t builder sh -eu {0}
|
|
run: |
|
|
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: |
|
|
ARCH=x86_64
|
|
GHC_VER=${{ needs.variables.outputs.GHC_VER }}
|
|
BUILD_DIR=$(echo dist-newstyle/build/${ARCH}-linux/ghc-${GHC_VER}/simplex-chat-*)
|
|
mkdir -p postgres-libs/libs
|
|
cp ${BUILD_DIR}/build/libsimplex.so postgres-libs/libs/
|
|
cp ${BUILD_DIR}/build/deps/* postgres-libs/libs/
|
|
(cd postgres-libs && zip -r simplex-chat-libs-linux-x86_64-postgres.zip libs)
|
|
|
|
- name: Upload postgres library
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
repository: ${{ github.repository }}-libs
|
|
tag_name: ${{ needs.maybe-release.outputs.libs_tag }}
|
|
files: postgres-libs/*.zip
|
|
token: ${{ secrets.NODEJS_REPO_TOKEN }}
|
|
|
|
# =========================
|
|
# MacOS Build
|
|
# =========================
|
|
|
|
build-macos:
|
|
name: "${{ matrix.os }} (CLI,Desktop), GHC: ${{ matrix.ghc }}"
|
|
needs: [maybe-release, variables]
|
|
runs-on: ${{ matrix.os }}
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}-macos-${{ matrix.os }}-${{ needs.maybe-release.outputs.libs_tag }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: macos-latest
|
|
arch: aarch64
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
cli_asset_name: simplex-chat-macos-aarch64
|
|
desktop_asset_name: simplex-desktop-macos-aarch64.dmg
|
|
openssl_dir: "/opt/homebrew/opt"
|
|
- os: macos-15-intel
|
|
arch: x86_64
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
cli_asset_name: simplex-chat-macos-x86-64
|
|
desktop_asset_name: simplex-desktop-macos-x86_64.dmg
|
|
openssl_dir: "/usr/local/opt"
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v3
|
|
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 }}
|
|
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
|
|
|
|
- name: Prepare cabal.project.local
|
|
shell: bash
|
|
run: |
|
|
echo "ignore-project: False" >> cabal.project.local
|
|
echo "package simplexmq" >> cabal.project.local
|
|
echo " extra-include-dirs: ${{ matrix.openssl_dir }}/openssl@3.0/include" >> cabal.project.local
|
|
echo " extra-lib-dirs: ${{ matrix.openssl_dir}}/openssl@3.0/lib" >> cabal.project.local
|
|
echo "" >> cabal.project.local
|
|
echo "package direct-sqlcipher" >> cabal.project.local
|
|
echo " extra-include-dirs: ${{ matrix.openssl_dir }}/openssl@3.0/include" >> cabal.project.local
|
|
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: |
|
|
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
|
|
with:
|
|
bin_path: ${{ steps.mac_cli_build.outputs.bin_path }}
|
|
bin_name: ${{ matrix.cli_asset_name }}
|
|
bin_hash: ${{ steps.mac_cli_build.outputs.bin_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build Desktop
|
|
id: mac_desktop_build
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
shell: bash
|
|
env:
|
|
APPLE_SIMPLEX_SIGNING_KEYCHAIN: ${{ secrets.APPLE_SIMPLEX_SIGNING_KEYCHAIN }}
|
|
APPLE_SIMPLEX_NOTARIZATION_APPLE_ID: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_APPLE_ID }}
|
|
APPLE_SIMPLEX_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_SIMPLEX_NOTARIZATION_PASSWORD }}
|
|
run: |
|
|
export ASSETS_DIR='../../assets'
|
|
scripts/ci/build-desktop-mac.sh
|
|
path=$(echo $PWD/apps/multiplatform/release/main/dmg/SimpleX-*.dmg)
|
|
echo "package_path=$path" >> $GITHUB_OUTPUT
|
|
echo "package_hash=$(echo SHA2-256\(${{ matrix.desktop_asset_name }}\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload Desktop
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_path: ${{ steps.mac_desktop_build.outputs.package_path }}
|
|
bin_name: ${{ matrix.desktop_asset_name }}
|
|
bin_hash: ${{ steps.mac_desktop_build.outputs.package_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Run tests
|
|
if: matrix.arch == 'aarch64'
|
|
timeout-minutes: 120
|
|
shell: bash
|
|
run: |
|
|
i=1
|
|
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 ${{ env.ghc_options }}; then
|
|
break
|
|
else
|
|
echo "Attempt $i failed, retrying..."
|
|
i=$((i + 1))
|
|
sleep 1
|
|
fi
|
|
done
|
|
if [ "$i" -gt "$attempts" ]; then
|
|
echo "All "$attempts" attempts failed."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Build library
|
|
id: mac_lib_build
|
|
if: ${{ !cancelled() && needs.maybe-release.outputs.libs_tag && steps.mac_cli_build.outcome == 'success' }}
|
|
shell: bash
|
|
run: |
|
|
SKIP_VLC=1 scripts/desktop/build-lib-mac.sh
|
|
name=simplex-chat-libs-macos-${{ matrix.arch }}
|
|
mkdir -p release-libs/$name/libs
|
|
find apps/multiplatform/common/src/commonMain/cpp/desktop/libs/mac-${{ matrix.arch }} -maxdepth 1 -type f -exec cp {} release-libs/$name/libs/ \;
|
|
(cd release-libs/$name && zip -r ../$name.zip libs)
|
|
|
|
- name: Upload library
|
|
if: ${{ !cancelled() && steps.mac_lib_build.outcome == 'success' }}
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
repository: ${{ github.repository }}-libs
|
|
tag_name: ${{ needs.maybe-release.outputs.libs_tag }}
|
|
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
|
|
# =========================
|
|
|
|
build-windows:
|
|
name: "${{ matrix.os }} (CLI,Desktop), GHC: ${{ matrix.ghc }}"
|
|
needs: [maybe-release, variables]
|
|
runs-on: ${{ matrix.os }}
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}-windows-${{ matrix.os }}-${{ needs.maybe-release.outputs.libs_tag }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: windows-latest
|
|
ghc: ${{ needs.variables.outputs.GHC_VER }}
|
|
cli_asset_name: simplex-chat-windows-x86-64
|
|
desktop_asset_name: simplex-desktop-windows-x86_64.msi
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v3
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Prepare build
|
|
id: prepare
|
|
uses: ./.github/actions/prepare-build
|
|
with:
|
|
java_ver: ${{ needs.variables.outputs.JAVA_VER }}
|
|
ghc_ver: ${{ matrix.ghc }}
|
|
github_ref: ${{ github.ref }}
|
|
|
|
- name: Configure pagefile (Windows)
|
|
uses: simplex-chat/configure-pagefile-action@v1.4
|
|
with:
|
|
minimum-size: 16GB
|
|
maximum-size: 16GB
|
|
disk-root: "C:"
|
|
|
|
- name: 'Setup MSYS2'
|
|
uses: simplex-chat/setup-msys2@v2
|
|
with:
|
|
msystem: ucrt64
|
|
update: true
|
|
install: >-
|
|
git
|
|
perl
|
|
make
|
|
zip
|
|
pacboy: >-
|
|
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
|
|
id: windows_cli_build
|
|
shell: msys2 {0}
|
|
run: |
|
|
export PATH=$PATH:/c/ghcup/bin:$(echo /c/tools/ghc-*/bin || echo)
|
|
scripts/desktop/prepare-openssl-windows.sh
|
|
openssl_windows_style_path=$(echo `pwd`/dist-newstyle/openssl-3.0.15 | sed 's#/\([a-zA-Z]\)#\1:#' | sed 's#/#\\#g')
|
|
rm cabal.project.local 2>/dev/null || true
|
|
echo "ignore-project: False" >> cabal.project.local
|
|
echo "package direct-sqlcipher" >> cabal.project.local
|
|
echo " flags: +openssl" >> cabal.project.local
|
|
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 ${{ 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}
|
|
run: |
|
|
export PATH=$PATH:/c/ghcup/bin:$(echo /c/tools/ghc-*/bin || echo)
|
|
SKIP_VLC=1 scripts/desktop/build-lib-windows.sh
|
|
dlltool -d libsimplex.dll.def -l libsimplex.lib -D libsimplex.dll
|
|
name=simplex-chat-libs-windows-x86_64
|
|
mkdir -p release-libs/$name/libs
|
|
find apps/multiplatform/common/src/commonMain/cpp/desktop/libs/windows-x86_64 -maxdepth 1 -type f -exec cp {} release-libs/$name/libs/ \;
|
|
cp libsimplex.lib release-libs/$name/libs/
|
|
(cd release-libs/$name && zip -r ../$name.zip libs)
|
|
|
|
- name: Upload library
|
|
if: needs.maybe-release.outputs.libs_tag
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
repository: ${{ github.repository }}-libs
|
|
tag_name: ${{ needs.maybe-release.outputs.libs_tag }}
|
|
files: release-libs/*.zip
|
|
token: ${{ secrets.NODEJS_REPO_TOKEN }}
|
|
|
|
- name: Upload CLI
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_path: ${{ steps.windows_cli_build.outputs.bin_path }}
|
|
bin_name: ${{ matrix.cli_asset_name }}
|
|
bin_hash: ${{ steps.windows_cli_build.outputs.bin_hash }}
|
|
github_ref: ${{ github.ref }}
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Build Desktop
|
|
id: windows_desktop_build
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
shell: msys2 {0}
|
|
run: |
|
|
export PATH=$PATH:/c/ghcup/bin:$(echo /c/tools/ghc-*/bin || echo)
|
|
scripts/desktop/build-lib-windows.sh
|
|
cd apps/multiplatform
|
|
./gradlew -Psimplex.assets.dir=../../assets packageMsi
|
|
rm -rf dist-newstyle/src/direct-sq* dist-newstyle/src/simplexmq*
|
|
path=$(echo $PWD/release/main/msi/*imple*.msi | sed 's#/\([a-z]\)#\1:#' | sed 's#/#\\#g')
|
|
echo "package_path=$path" >> $GITHUB_OUTPUT
|
|
echo "package_hash=$(echo SHA2-256\(${{ matrix.desktop_asset_name }}\)= $(openssl sha256 $path | cut -d' ' -f 2))" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload Desktop
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: ./.github/actions/prepare-release
|
|
with:
|
|
bin_path: ${{ steps.windows_desktop_build.outputs.package_path }}
|
|
bin_name: ${{ matrix.desktop_asset_name }}
|
|
bin_hash: ${{ steps.windows_desktop_build.outputs.package_hash }}
|
|
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
|
|
# =========================
|
|
|
|
# A new library release is tested with the Node.js and Python packages and updates them in a release PR.
|
|
|
|
packages:
|
|
needs: [maybe-release, build-linux, build-linux-push, build-linux-postgres, build-macos, build-windows]
|
|
if: ${{ !cancelled() && needs.maybe-release.outputs.libs_tag }}
|
|
# the called workflow can't be granted more than its caller, and its publish job needs these
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
uses: ./.github/workflows/packages.yml
|
|
with:
|
|
libs_release: ${{ needs.maybe-release.outputs.libs_tag }}
|
|
secrets: inherit
|