Use ubuntu-24.04-arm runner for linux/arm64 cross-compile tests
instead of QEMU emulation. This should reduce build time from ~20min
to ~3min.
- Remove QEMU and Buildx setup (not needed with native runner)
- Remove --platform flag from Docker commands
- Each matrix entry now specifies its runner
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(icons): implement Mac asset (.car) generation with actool
- Check actool version >= 26 requirement
- Generate asset.car from Icon Composer input
- Validate compilation output and cleanup temp files
* Wails Icon as Icon Composer file
* a generated assets.car from the wails icon
* handle absolute paths correctly in actool command
- Check if paths are absolute before prepending "./"
- Use filepath.Join for temp.plist path construction
* add test for Assets.car generation
* Skipping Asset.car generation and test on non mac-systems
* add CFBundleIconName generation to plist, if Assets.car exists
* also create .icns from .icon-File and use always absolut path
Use absolut path, because otherwise we got strange behavior from actool.
* update to use appicon as CFBundleIconName and optionally use the name from config
* update the Taskfiles
* remove log prints
* the awesome new LiquidGlass icon files
* update doc
* Update UNRELEASED_CHANGELOG.md
* Update UNRELEASED_CHANGELOG.md
* fix security bug
* Skip icon generation test with actool on CI
* fix error from coderabbitai
* solved the coderabbitai nitpicks
* fix coderabbitai findings
* Update changelog
---------
Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
For Linux ARM64 builds on x86_64 hosts, use Docker's QEMU emulation
instead of trying to cross-compile with Zig or install multi-arch packages.
Changes:
- Workflow: Set up QEMU and Docker Buildx for Linux cross-arch builds
- Workflow: Build Docker image with --platform for target architecture
- Dockerfile: Simplify to use native GCC (QEMU handles arch translation)
- Taskfile: Add --platform flag to docker run for Linux builds
This approach is slower but reliable and doesn't require complex
cross-compilation toolchain setup.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of trying to use Zig for Linux cross-compilation (which has
glibc header compatibility issues), install the proper aarch64-linux-gnu
cross-compilation toolchain and ARM64 GTK/WebKit libraries.
Changes:
- Enable multi-arch and install gcc-aarch64-linux-gnu toolchain
- Install ARM64 versions of libgtk-3-dev and libwebkit2gtk-4.1-dev
- Set PKG_CONFIG_PATH for ARM64 libraries when cross-compiling
- Use aarch64-linux-gnu-gcc as the cross-compiler
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Zig CC wrappers for Linux ARM64 and AMD64 targets. The build script
now detects if host architecture matches target architecture:
- If match: use native GCC (faster, better optimization)
- If different: use Zig for cross-compilation
This allows building Linux ARM64 binaries from an x86_64 Docker host
without requiring multi-arch images or QEMU emulation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wails-cross image is an x86_64 image that uses Zig for cross-compilation.
It doesn't need to run ON the target platform - it cross-compiles TO it.
Remove the --platform flag that was causing Docker to try pulling a
non-existent arm64 version of the image.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When building Linux binaries with a different target architecture than
the host (e.g., arm64 on x86_64), use Docker-based cross-compilation
instead of native build. The native GCC cannot compile ARM64 assembly
on an x86_64 host.
Adds a third condition to the build task selection: target architecture
must match host architecture to use native build.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Docker mounts v3 at the same absolute path, so change the replace
directive to use the absolute workspace path instead of removing it.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The project created by wails3 init has a replace directive pointing
to the local v3 source. This doesn't work inside Docker containers.
Remove it before running the cross-compile tasks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- common:setup:docker instead of setup:docker
- darwin:build, linux:build, windows:build instead of build:darwin, etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wails3 CLI requires webkit2gtk, gtk, and other Linux libraries
to compile due to CGO dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of building Docker images from scratch, the workflow now:
- Installs wails3 CLI
- Creates a test project with wails3 init
- Runs setup:docker to build the cross-compile image
- Uses task build:<platform> for cross-compilation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Dockerfiles use heredoc syntax which requires BuildKit's
dockerfile:1 syntax directive to parse correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds registry-based cache alongside GHA cache to improve build times
when GHA cache is evicted (7-day retention limit).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Always use linux:build:docker for Linux targets to properly test
the Docker image for both amd64 and arm64 architectures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Intel Macs are EOL (last released 2020, support ending ~2027).
Focus testing on darwin/arm64 which is the current/future platform.
The Dockerfile still supports amd64 if needed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The task uses --platform flag which requires the matching architecture
variant. Pull arm64 variant explicitly for Linux arm64 test.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The linux:build task chooses native build when gcc is available,
but native x86_64 gcc can't cross-compile to arm64 (assembly errors).
Explicitly call linux:build:docker for Linux arm64 target.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wails3 task system expects a locally tagged 'wails-cross' image.
Pull from ghcr.io and tag it appropriately before running tasks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
wails3 init already adds a replace directive with relative path.
Use sed to update it to absolute path instead of adding a duplicate.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use `wails3 task {os}:build` instead of manual Docker commands
- Test actual cross-compilation only (skip host-to-host):
- darwin/arm64 from Linux/amd64
- windows/arm64 from Linux/amd64
- linux/arm64 from Linux/amd64
- Let task system handle frontend build, bindings, etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The frontend build requires Go bindings to be generated first.
Run `wails3 generate bindings` on the host before building frontend.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use 3 parallel jobs (darwin, linux, windows) instead of 6
- Each job builds both amd64 and arm64 architectures
- Use real wails3 projects via `wails3 init` instead of fake test programs
- Remove pointless non-CGO tests
- Keep library dependency verification for Linux binaries
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds workflow to build and test the wails-cross Docker image:
- Builds multi-arch image (amd64/arm64)
- Tests cross-compilation for all 6 platform/arch combinations
- Tests both CGO and non-CGO builds
- Verifies Linux binary library dependencies with readelf
- Publishes to ghcr.io/wailsapp/wails-cross
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch from Alpine to Debian (golang:1.25-bookworm)
- Install GTK3/GTK4 and WebKit2GTK 4.1/6.0 dev packages
- Use native GCC for Linux targets instead of Zig
- Add --platform flag to Docker run for architecture matching
- Remove unused zcc-linux-* wrappers (Zig had glibc header issues)
- Keep Zig for Darwin (macOS SDK) and Windows (bundled mingw)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add TARGETARCH detection to download the correct Zig binary for
the host architecture (aarch64 vs x86_64). This enables native
performance on Apple Silicon Macs instead of requiring emulation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(v3): add server mode for headless HTTP deployment
Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.
Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks
Build and run:
wails3 task build:server
wails3 task run:server
wails3 task build:docker
wails3 task run:docker
Documentation at docs/guides/server-build.mdx
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(v3): add server mode for headless HTTP deployment
Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.
Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks
Build and run:
wails3 task build:server
wails3 task run:server
wails3 task build:docker
wails3 task run:docker
Documentation at docs/guides/server-build.mdx
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review comments
- Fix corrupted test file with embedded terminal output
- Fix module name mismatch in gin-routing (was gin-example)
- Fix replace directive version mismatch in gin-service
- Fix placeholder module name in ios example (was changeme)
- Fix Dockerfile COPY path to work from both build contexts
- Fix bare URL in README (MD034 compliance)
- Fix comment accuracy in getScreens (returns error, not empty slice)
- Remove deprecated docker-compose version field
- Add port documentation in Taskfile template
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review comments
- Add note about healthcheck wget not being available in distroless images
- Add !server build constraint to menu_windows.go and menu_darwin.go
- Downgrade window-visibility-test go.mod from 1.25 to 1.24 to match CI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(darwin): make Position() and SetPosition() use consistent coordinate systems
On macOS, windowGetPosition() was returning raw Cocoa coordinates (Y=0 at
bottom of screen) while windowSetPosition() expected coordinates with Y=0
at the top of the screen. This caused window positions to drift when saving
and restoring window state across application sessions.
The fix updates windowGetPosition() to:
1. Convert Y coordinates to top-origin (matching windowSetPosition)
2. Apply DPI scale factor (matching windowSetPosition)
This ensures Position() returns values that can be directly passed back to
SetPosition() for consistent round-trip behavior.
Fixes#4816🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(darwin): make Position() and SetPosition() use consistent coordinate systems
On macOS, windowGetPosition() was returning raw Cocoa coordinates (Y=0 at
bottom of screen) while windowSetPosition() expected coordinates with Y=0
at the top of the screen. This caused window positions to drift when saving
and restoring window state across application sessions.
The fix updates windowGetPosition() to:
1. Convert Y coordinates to top-origin (matching windowSetPosition)
2. Apply DPI scale factor (matching windowSetPosition)
This ensures Position() returns values that can be directly passed back to
SetPosition() for consistent round-trip behavior.
Fixes#4816🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Check current DPI awareness before calling SetProcessDpiAwarenessContext.
Windows only allows setting DPI awareness once per process - either via
manifest or API, not both. If already set (e.g., via application manifest
in built binaries), skip the API call to avoid "Access is denied" errors.
Fixes#4803🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
* fix: change window type from WebviewWindow to Window
* docs: update `UNRELEASED_CHANGELOG`
---------
Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
* docs: fixed incorrect tag in Custom Output Directory of Bindings
After some usage of wails I found out that
```bash
wails3 generate bindings -o ./src/bindings
```
does not work and according to
```bash
$ wails3 generate bindings --help
```
it uses the `-d string` tag instead
* Update UNRELEASED_CHANGELOG.md
---------
Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
* fix(v3/linux): fix crash on panic in JS-bound Go methods
WebKit2GTK installs signal handlers after gtk_main() starts, overriding
our SA_ONSTACK fix. This causes Go panics (e.g., nil pointer dereference)
in JS-bound methods to crash with 'non-Go code set up signal handler
without SA_ONSTACK flag'.
Fix by deferring signal handler installation via g_idle_add() to run
after GTK main loop starts, ensuring we fix handlers AFTER WebKit
has installed its own.
Fixes#3965
* test(v3/linux): add test case for signal handler fix
Adds a test application that can trigger panics from JS-bound Go methods
to verify the signal handler fix for issue #3965 works correctly.
The test app has buttons to:
- Trigger a panic in a goroutine
- Trigger an immediate panic
- Call a safe method
Before the fix, clicking 'Trigger Panic' would crash the app.
After the fix, panics are recovered and logged.
* chore: remove test case from PR
* fix(linux): call signal handler fix after WebKit init, not in idle callback
Move install_signal_handlers() call to after webkit_web_view_new_with_user_content_manager()
to ensure WebKit has finished setting up its signal handlers before we add SA_ONSTACK.
The previous g_idle_add approach was still too early - WebKit initialization continues
after GTK init. This matches the v2 approach which waits for actual webview creation.
Also add documentation about the known Go limitation (golang/go#7227) where signals
may still be delivered on the wrong stack in some C interop scenarios.