docs: document reproducible builds and fix Windows publish command
README.md: add "Reproducible builds (Docker)" section at the top of Building, explaining why it matters for a wallet (auditable toolchain, no drift between releases, anyone can verify binaries from source). Fix the manual Windows publish command to include IncludeNativeLibrariesForSelfExtract=true — the previous command produced an exe that silently failed to start because Avalonia's native DLLs were left outside it. CLAUDE.md: document docker/ in the project tree, promote ./docker/build.sh as the primary release path, record the two non-obvious gotchas (native libs flag for single-file desktop; XA5207 / API level coupling for Android).
This commit is contained in:
@@ -29,6 +29,7 @@ src/App/ shared Avalonia UI library (App, Views, ViewModels, Loc, Asset
|
|||||||
src/App.Desktop/ desktop head (WinExe): Program.cs, app.manifest, .ico → runnable
|
src/App.Desktop/ desktop head (WinExe): Program.cs, app.manifest, .ico → runnable
|
||||||
src/App.Android/ Android head (net10.0-android): MainApplication/MainActivity → apk
|
src/App.Android/ Android head (net10.0-android): MainApplication/MainActivity → apk
|
||||||
src/Cli/ CLI on the same Core tests/ xUnit
|
src/Cli/ CLI on the same Core tests/ xUnit
|
||||||
|
docker/ reproducible release builds (build.sh + pinned Dockerfiles) → dist/
|
||||||
```
|
```
|
||||||
|
|
||||||
The Avalonia UI lives **once** in `src/App` (a library); the two heads only carry the
|
The Avalonia UI lives **once** in `src/App` (a library); the two heads only carry the
|
||||||
@@ -46,8 +47,9 @@ by `MainWindow` on desktop and as the single-view root on Android.
|
|||||||
- Tests (headless, the primary verification layer): `dotnet test` — single: `dotnet test --filter "FullyQualifiedName~TestName"`; property-based tests (CsCheck, `PropertyTests.cs`) run in the same command and take ~30 s
|
- Tests (headless, the primary verification layer): `dotnet test` — single: `dotnet test --filter "FullyQualifiedName~TestName"`; property-based tests (CsCheck, `PropertyTests.cs`) run in the same command and take ~30 s
|
||||||
- GUI hot reload: `dotnet watch --project src/App.Desktop` (on WSL2/WSLg the window shows on the Windows desktop, no graphics dependencies to install)
|
- GUI hot reload: `dotnet watch --project src/App.Desktop` (on WSL2/WSLg the window shows on the Windows desktop, no graphics dependencies to install)
|
||||||
- CLI: `dotnet run --project src/Cli -- <command>` (no args → usage)
|
- CLI: `dotnet run --project src/Cli -- <command>` (no args → usage)
|
||||||
- Windows publish: `dotnet publish src/App.Desktop -r win-x64 -p:PublishSingleFile=true --self-contained`
|
- **Release binaries (all 3 targets): `./docker/build.sh [windows|linux|android|all]`** — reproducible builds in Docker (toolchain pinned in `docker/Dockerfile.*`, no SDK needed on host), artifacts in `dist/`, version taken from the App csproj. See `docker/README.md`. Gotchas already encoded there: single-file desktop publishes need `-p:IncludeNativeLibrariesForSelfExtract=true` (without it Avalonia's native libs — Skia/HarfBuzz/ANGLE — stay outside the exe, which then silently fails to start); the android workload dictates the SDK API level (error XA5207 → bump `ANDROID_SDK_PLATFORM` in `Dockerfile.android`).
|
||||||
- Linux publish: `dotnet publish src/App.Desktop -r linux-x64 --self-contained` (then AppImage via PupNet Deploy)
|
- Manual Windows publish: `dotnet publish src/App.Desktop -r win-x64 -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true --self-contained`
|
||||||
|
- Manual Linux publish: same with `-r linux-x64` (single-file binary; AppImage via PupNet Deploy is a future step, no pupnet.conf yet)
|
||||||
|
|
||||||
**Android (apk).** Needs the `android` workload (`dotnet workload install android`), a JDK
|
**Android (apk).** Needs the `android` workload (`dotnet workload install android`), a JDK
|
||||||
(`JAVA_HOME`), and the Android SDK. To provision the SDK once:
|
(`JAVA_HOME`), and the Android SDK. To provision the SDK once:
|
||||||
|
|||||||
@@ -147,6 +147,26 @@ The suite includes **property-based tests** ([CsCheck](https://github.com/Anthon
|
|||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
### Reproducible builds (Docker) — recommended for release binaries
|
||||||
|
|
||||||
|
All three distribution targets (Windows exe, Linux binary, Android apk) can be
|
||||||
|
built with one command inside Docker, with **no SDK installed on the host**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./docker/build.sh # interactive menu, or: ./docker/build.sh all
|
||||||
|
```
|
||||||
|
|
||||||
|
Why build this way: the whole toolchain is pinned in the Dockerfiles, so every
|
||||||
|
build uses exactly the same SDK versions regardless of the host machine — no
|
||||||
|
toolchain drift between releases — and the build environment itself is
|
||||||
|
reviewable in the repo. For a wallet this is a trust property, not a
|
||||||
|
convenience: anyone can rebuild the published binaries from source and check
|
||||||
|
they were produced by the process the repository declares.
|
||||||
|
|
||||||
|
See [docker/README.md](docker/README.md) for prerequisites, usage, how to run
|
||||||
|
each produced artifact, and troubleshooting. The sections below cover manual
|
||||||
|
builds with a locally installed SDK (the normal path during development).
|
||||||
|
|
||||||
### Development build
|
### Development build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -162,7 +182,10 @@ dotnet build src/App.Desktop # desktop head only
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Windows — single self-contained .exe (output: src/App.Desktop/bin/Release/net10.0/win-x64/publish/PalladiumWallet.exe)
|
# Windows — single self-contained .exe (output: src/App.Desktop/bin/Release/net10.0/win-x64/publish/PalladiumWallet.exe)
|
||||||
dotnet publish src/App.Desktop -c Release -r win-x64 -p:PublishSingleFile=true --self-contained
|
# IncludeNativeLibrariesForSelfExtract embeds Avalonia's native libs (Skia, HarfBuzz, ANGLE):
|
||||||
|
# without it they stay as separate DLLs and the .exe alone silently fails to start.
|
||||||
|
dotnet publish src/App.Desktop -c Release -r win-x64 -p:PublishSingleFile=true \
|
||||||
|
-p:IncludeNativeLibrariesForSelfExtract=true --self-contained
|
||||||
|
|
||||||
# Linux — self-contained; AppImage then produced with PupNet Deploy
|
# Linux — self-contained; AppImage then produced with PupNet Deploy
|
||||||
# (output: src/App.Desktop/bin/Release/net10.0/linux-x64/publish/PalladiumWallet)
|
# (output: src/App.Desktop/bin/Release/net10.0/linux-x64/publish/PalladiumWallet)
|
||||||
|
|||||||
Reference in New Issue
Block a user