mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-11-11 11:47:44 +00:00
Build existing Haskell targets through one pinned Nix checkout
This commit is contained in:
9 files changed
+295
-15
No files matched your search
@@ -0,0 +1,94 @@
|
||||
name: Nix Haskell builds
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, stable, build/stable-ghc-9.14]
|
||||
paths:
|
||||
- 'flake.*'
|
||||
- '*.cabal'
|
||||
- 'cabal.project*'
|
||||
- 'src/**'
|
||||
- 'apps/simplex-*/**'
|
||||
- 'bots/**'
|
||||
- 'scripts/nix/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/nix.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'flake.*'
|
||||
- '*.cabal'
|
||||
- 'cabal.project*'
|
||||
- 'src/**'
|
||||
- 'apps/simplex-*/**'
|
||||
- 'bots/**'
|
||||
- 'scripts/nix/**'
|
||||
- 'Makefile'
|
||||
- '.github/workflows/nix.yml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: nix-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.system }} / pinned Haskell compiler
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 360
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- system: x86_64-linux
|
||||
runner: ubuntu-24.04
|
||||
- system: aarch64-linux
|
||||
runner: ubuntu-24.04-arm
|
||||
- system: aarch64-darwin
|
||||
runner: macos-15
|
||||
- system: x86_64-darwin
|
||||
runner: macos-15-intel
|
||||
env:
|
||||
NIX_SYSTEM: ${{ matrix.system }}
|
||||
NIX_BUILD_TIMEOUT: 7200
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
extra_nix_config: |
|
||||
extra-substituters = https://cache.iog.io https://cache.zw3rk.com
|
||||
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= loony-tools:pr9m4BkM/5/eSTZlkQyRt57Jz7OMBxNSUiMC4FkcNfk=
|
||||
|
||||
- name: Show outputs from this checkout
|
||||
run: make nix-list
|
||||
|
||||
# Use the compiler fork in flake.lock, including both Android ABIs.
|
||||
# Stock GHC installed by ghcup is not interchangeable with this compiler.
|
||||
- name: Build existing Haskell outputs
|
||||
run: make nix-build
|
||||
|
||||
- name: Collect library ZIPs and CLIs
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p artifacts
|
||||
for output in result-nix/"$NIX_SYSTEM"/*; do
|
||||
[ -d "$output" ] || continue
|
||||
destination="artifacts/$(basename "$output")"
|
||||
mkdir -p "$destination"
|
||||
find -L "$output" -maxdepth 1 -type f -name '*.zip' -exec cp {} "$destination/" \;
|
||||
if [ -f "$output/bin/simplex-chat" ]; then
|
||||
cp "$output/bin/simplex-chat" "$destination/"
|
||||
fi
|
||||
done
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nix-${{ matrix.system }}-${{ github.sha }}
|
||||
path: artifacts/
|
||||
if-no-files-found: error
|
||||
@@ -69,6 +69,7 @@ website/package/generated*
|
||||
website/.nyc_output/
|
||||
website/coverage/
|
||||
result
|
||||
result-nix/
|
||||
|
||||
# Ignore API documentation
|
||||
website/api-docs/
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
NIX_TARGET ?= all
|
||||
NIX_ARGS ?=
|
||||
export NIX_SYSTEM
|
||||
export NIX_OUT_DIR
|
||||
export NIX_BUILD_TIMEOUT
|
||||
|
||||
.PHONY: help nix-list nix-build nix-native nix-android nix-windows nix-linux-static nix-ios nix-darwin-libs
|
||||
|
||||
help: ## Show build commands.
|
||||
@awk 'BEGIN { FS = ":.*## " } /^[a-zA-Z_-]+:.*## / { printf " %-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
|
||||
|
||||
# The flake lock selects the compiler; these targets never install a stock GHC.
|
||||
nix-list: ## List selected Hydra outputs without building (NIX_TARGET=all).
|
||||
@./scripts/nix/build.sh --list $(NIX_TARGET)
|
||||
|
||||
nix-build: ## Build the host's existing Hydra outputs (NIX_TARGET=all, NIX_ARGS=...).
|
||||
./scripts/nix/build.sh $(NIX_TARGET) $(NIX_ARGS)
|
||||
|
||||
nix-native: ## Build the native Haskell library and CLI.
|
||||
./scripts/nix/build.sh native $(NIX_ARGS)
|
||||
|
||||
nix-android: ## Build both Android ABIs and their support libraries on x86_64-linux.
|
||||
./scripts/nix/build.sh android $(NIX_ARGS)
|
||||
|
||||
nix-windows: ## Cross-build the Windows library and CLI on x86_64-linux.
|
||||
./scripts/nix/build.sh windows $(NIX_ARGS)
|
||||
|
||||
nix-linux-static: ## Cross-build the x86_64, i686, and aarch64 Linux static CLIs.
|
||||
./scripts/nix/build.sh linux-static $(NIX_ARGS)
|
||||
|
||||
nix-ios: ## Build the iOS Haskell library ZIP on the selected Darwin host.
|
||||
./scripts/nix/build.sh ios $(NIX_ARGS)
|
||||
|
||||
nix-darwin-libs: ## Build Swift JSON and tagged JSON library ZIPs on Darwin.
|
||||
./scripts/nix/build.sh darwin-libs $(NIX_ARGS)
|
||||
@@ -5,7 +5,7 @@ set -eu
|
||||
repo="https://github.com/simplex-chat/simplex-chat"
|
||||
|
||||
u="$USER"
|
||||
tmp="$(mktemp -d -t)"
|
||||
tmp="$(mktemp -d)"
|
||||
folder="$tmp/simplex-chat"
|
||||
|
||||
nix_ver="nix-2.22.0"
|
||||
@@ -105,13 +105,9 @@ build() {
|
||||
sed -i.bak "s/android.version_code=.*/android.version_code=${vercode}/" "$folder/apps/multiplatform/gradle.properties"
|
||||
|
||||
for arch in $arches; do
|
||||
if [ "$arch" = "armv7a" ]; then
|
||||
android_simplex_lib="${folder}#hydraJobs.${arch}-android:lib:simplex-chat.x86_64-linux"
|
||||
android_support_lib="${folder}#hydraJobs.${arch}-android:lib:support.x86_64-linux"
|
||||
else
|
||||
android_simplex_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:simplex-chat"
|
||||
android_support_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:support"
|
||||
fi
|
||||
# Both ABIs use this checkout and the same compiler selected by flake.lock.
|
||||
android_simplex_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:simplex-chat"
|
||||
android_support_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:support"
|
||||
|
||||
android_simplex_lib_output="${PWD}/result/pkg-${arch}-android-libsimplex.zip"
|
||||
android_support_lib_output="${PWD}/result/pkg-${arch}-android-libsupport.zip"
|
||||
|
||||
@@ -9,7 +9,7 @@ function readlink() {
|
||||
OS=linux
|
||||
ARCH="$(uname -m)"
|
||||
DATABASE_BACKEND="${1:-sqlite}"
|
||||
GHC_VERSION=9.6.3
|
||||
GHC_VERSION=$(ghc --numeric-version)
|
||||
|
||||
if [ "$ARCH" == "aarch64" ]; then
|
||||
COMPOSE_ARCH=arm64
|
||||
|
||||
@@ -5,7 +5,7 @@ set -e
|
||||
OS=mac
|
||||
ARCH="${1:-$(uname -m)}"
|
||||
COMPOSE_ARCH=$ARCH
|
||||
GHC_VERSION=9.6.3
|
||||
GHC_VERSION=$(ghc --numeric-version)
|
||||
DATABASE_BACKEND="${2:-sqlite}"
|
||||
|
||||
if [ "$ARCH" == "arm64" ]; then
|
||||
|
||||
+71
-1
@@ -1,4 +1,74 @@
|
||||
# Updating nix package config
|
||||
# Haskell builds with Nix
|
||||
|
||||
The compiler and all cross-compilers come from the haskell.nix input pinned in
|
||||
`flake.lock`. The `ghc914-sh` compiler is the stable-haskell fork, not the stock
|
||||
GHC 9.14 release from GHCup. Use the same source checkout and lock file for every
|
||||
platform; Android ARMv7 does not require a separate branch or tag.
|
||||
|
||||
Run these commands from the repository root:
|
||||
|
||||
```sh
|
||||
make help
|
||||
make nix-list # list this host's existing Hydra outputs
|
||||
make nix-native # native library and CLI
|
||||
make nix-android # ARM64 + ARMv7 libraries, on x86_64-linux
|
||||
make nix-windows # Windows library and CLI, on x86_64-linux
|
||||
make nix-linux-static # x86_64, i686, and ARM64 static Linux CLIs
|
||||
make nix-build # all existing outputs for this build host
|
||||
```
|
||||
|
||||
Each command builds this checkout, without cloning another branch. Output links
|
||||
are placed under `result-nix/<build-system>/<package>`. ZIP filenames inside the
|
||||
outputs retain the existing Hydra names. For example, the ARMv7 client library is
|
||||
`result-nix/x86_64-linux/armv7a-android:lib:simplex-chat/pkg-armv7a-android-libsimplex.zip`.
|
||||
Nix includes tracked working-tree changes; add new source files to Git before
|
||||
building so they are included.
|
||||
|
||||
For a remote builder, select its build system explicitly. Nix must already have
|
||||
that builder configured:
|
||||
|
||||
```sh
|
||||
make nix-ios NIX_SYSTEM=aarch64-darwin
|
||||
make nix-darwin-libs NIX_SYSTEM=x86_64-darwin
|
||||
make nix-build NIX_SYSTEM=aarch64-linux
|
||||
```
|
||||
|
||||
`nix-ios` produces the Haskell static-library ZIP. It does not run Xcode, sign an
|
||||
iOS application, or upload to TestFlight. ARM64 device libraries and Intel
|
||||
simulator libraries retain their separate outputs. The existing iOS preparation
|
||||
scripts retag ARM64 archives with `mac2ios -s` when an Apple Silicon simulator is
|
||||
needed.
|
||||
|
||||
`NIX_ARGS` passes additional options to `nix build`, and `NIX_OUT_DIR` changes the
|
||||
output-link directory. Each derivation has a two-hour timeout by default; set
|
||||
`NIX_BUILD_TIMEOUT` in seconds to change it. For a wall-clock limit on a local
|
||||
batch, use `timeout` from the Nix development environment:
|
||||
|
||||
```sh
|
||||
nix develop -c timeout 6h make nix-build
|
||||
make nix-native NIX_ARGS=--dry-run
|
||||
```
|
||||
|
||||
`.github/workflows/nix.yml` runs these same outputs on Linux ARM64/x86_64 and
|
||||
Darwin ARM64/x86_64, with a six-hour job limit. It uploads the existing library ZIPs
|
||||
and CLIs under an artifact named for the source SHA. Hydra continues to consume
|
||||
the same `hydraJobs` attributes. The older application release workflow still
|
||||
uses its existing GHCup/Docker compiler settings; migrating that packaging and
|
||||
release path is separate from this Nix build lane.
|
||||
|
||||
To build both Android APK ABIs from the current checkout, preserving the same
|
||||
compiler and source, use the existing builder's source/skip-checkout flags:
|
||||
|
||||
```sh
|
||||
scripts/android/build-android.sh -sg VERSION_CODE
|
||||
```
|
||||
|
||||
This command also needs the Android SDK, Gradle, and its other existing tools.
|
||||
The APK reproduction script now checks out the supplied tag for both ABIs.
|
||||
Historical releases that used a separate `-armv7a` tag must be reproduced with
|
||||
their historical build scripts.
|
||||
|
||||
## Updating package hashes
|
||||
|
||||
1. Install `nix`, `gawk` and `jq`.
|
||||
|
||||
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
# Use this checkout and its lock file for every target, including cross builds.
|
||||
repo_dir=$(CDPATH='' cd -- "$(dirname -- "$0")/../.." && pwd)
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: scripts/nix/build.sh [--list] TARGET [nix build options...]
|
||||
|
||||
Targets: all, native, android, windows, linux-static, ios, darwin-libs
|
||||
NIX_SYSTEM selects the build host (defaults to this machine's Nix system).
|
||||
NIX_OUT_DIR selects the output links (defaults to result-nix in this checkout).
|
||||
NIX_BUILD_TIMEOUT bounds each derivation in seconds (defaults to 7200).
|
||||
--list prints the selected Hydra attributes without evaluating or building them.
|
||||
EOF
|
||||
}
|
||||
|
||||
list_only=false
|
||||
if [ "${1:-}" = "--list" ]; then
|
||||
list_only=true
|
||||
shift
|
||||
fi
|
||||
case "${1:-}" in
|
||||
''|-h|--help) usage; exit 0 ;;
|
||||
esac
|
||||
target=$1
|
||||
shift
|
||||
|
||||
system=${NIX_SYSTEM:-}
|
||||
if [ -z "$system" ]; then
|
||||
case "$(uname -s):$(uname -m)" in
|
||||
Linux:x86_64) system=x86_64-linux ;;
|
||||
Linux:aarch64|Linux:arm64) system=aarch64-linux ;;
|
||||
Darwin:x86_64) system=x86_64-darwin ;;
|
||||
Darwin:arm64|Darwin:aarch64) system=aarch64-darwin ;;
|
||||
*) echo 'Unsupported build host; set NIX_SYSTEM explicitly.' >&2; exit 1 ;;
|
||||
esac
|
||||
fi
|
||||
case "$system" in
|
||||
x86_64-linux|aarch64-linux|x86_64-darwin|aarch64-darwin) ;;
|
||||
*) printf 'Unsupported NIX_SYSTEM: %s\n' "$system" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
packages=
|
||||
add_native() {
|
||||
packages="$packages lib:simplex-chat exe:simplex-chat"
|
||||
}
|
||||
add_android() {
|
||||
packages="$packages aarch64-android:lib:simplex-chat aarch64-android:lib:support armv7a-android:lib:simplex-chat armv7a-android:lib:support"
|
||||
}
|
||||
add_windows() {
|
||||
packages="$packages x86_64-windows:exe:simplex-chat x86_64-windows:lib:simplex-chat"
|
||||
}
|
||||
add_linux_static() {
|
||||
packages="$packages x86_64-linux-static:exe:simplex-chat i686-linux-static:exe:simplex-chat aarch64-linux-static:exe:simplex-chat"
|
||||
}
|
||||
add_darwin_libs() {
|
||||
packages="$packages $system-ios:lib:simplex-chat $system:lib:simplex-chat"
|
||||
}
|
||||
|
||||
case "$target:$system" in
|
||||
all:x86_64-linux) add_native; add_android; add_windows; add_linux_static ;;
|
||||
all:aarch64-linux|native:*) add_native ;;
|
||||
all:*-darwin) add_native; add_darwin_libs ;;
|
||||
android:x86_64-linux) add_android ;;
|
||||
windows:x86_64-linux) add_windows ;;
|
||||
linux-static:x86_64-linux) add_linux_static ;;
|
||||
ios:*-darwin) packages="$system-ios:lib:simplex-chat" ;;
|
||||
darwin-libs:*-darwin) add_darwin_libs ;;
|
||||
*) printf 'Target %s is not available on build host %s.\n' "$target" "$system" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
out_dir=${NIX_OUT_DIR:-$repo_dir/result-nix}
|
||||
for package in $packages; do
|
||||
attribute="hydraJobs.$system.$package"
|
||||
if "$list_only"; then
|
||||
printf '%s\n' "$attribute"
|
||||
else
|
||||
mkdir -p "$out_dir/$system"
|
||||
nix build --print-build-logs --timeout "${NIX_BUILD_TIMEOUT:-7200}" \
|
||||
--out-link "$out_dir/$system/$package" \
|
||||
"$repo_dir#$attribute" "$@"
|
||||
fi
|
||||
done
|
||||
@@ -245,10 +245,7 @@ Continue?'
|
||||
# Build phase
|
||||
for arch in $ARCHES; do
|
||||
case "$arch" in
|
||||
armv7a)
|
||||
build_tag="${tag}-armv7a"
|
||||
;;
|
||||
aarch64)
|
||||
aarch64|armv7a)
|
||||
build_tag="${tag}"
|
||||
;;
|
||||
*)
|
||||
|
||||
Reference in new issue
Block a user