Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 28 additions & 110 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,129 +1,47 @@
name: ci
name: CI

on:
push:
branches:
- "**"
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
matrix:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
build-and-test:
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Zig
shell: bash
env:
ZIG_VERSION: 0.15.2
run: |
set -euo pipefail
python - <<'PY'
import hashlib
import json
import os
import pathlib
import shutil
import tarfile
import urllib.request
import zipfile

version = os.environ["ZIG_VERSION"]
runner_os = os.environ["RUNNER_OS"]
runner_arch = os.environ["RUNNER_ARCH"]

os_map = {
"Linux": "linux",
"macOS": "macos",
"Windows": "windows",
}
arch_map = {
"X64": "x86_64",
"ARM64": "aarch64",
"X86": "x86",
}

os_part = os_map.get(runner_os)
arch_part = arch_map.get(runner_arch.upper())
if os_part is None or arch_part is None:
raise SystemExit(
f"Unsupported runner combination RUNNER_OS={runner_os} RUNNER_ARCH={runner_arch}"
)

artifact_key = f"{arch_part}-{os_part}"
with urllib.request.urlopen("https://ziglang.org/download/index.json") as resp:
index = json.load(resp)

release = index.get(version)
if release is None:
raise SystemExit(f"Zig version {version} is not present in ziglang download index")

artifact = release.get(artifact_key)
if artifact is None:
raise SystemExit(f"No Zig artifact for key {artifact_key} in version {version}")

tarball_url = artifact["tarball"]
expected_sha256 = artifact["shasum"]

out_root = pathlib.Path(os.environ["RUNNER_TEMP"]) / f"zig-{version}-{artifact_key}"
if out_root.exists():
shutil.rmtree(out_root)
out_root.mkdir(parents=True)

archive_path = out_root / pathlib.Path(tarball_url).name
print(f"Downloading {tarball_url}", flush=True)
urllib.request.urlretrieve(tarball_url, archive_path)

digest = hashlib.sha256()
with archive_path.open("rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
digest.update(chunk)
actual_sha256 = digest.hexdigest()
if actual_sha256.lower() != expected_sha256.lower():
raise SystemExit(
f"SHA256 mismatch for {archive_path.name}: {actual_sha256} != {expected_sha256}"
)

extract_dir = out_root / "extract"
extract_dir.mkdir()
lower_name = archive_path.name.lower()
if lower_name.endswith(".zip"):
with zipfile.ZipFile(archive_path) as zf:
zf.extractall(extract_dir)
else:
with tarfile.open(archive_path, "r:*") as tf:
tf.extractall(extract_dir)

dirs = [p for p in extract_dir.iterdir() if p.is_dir()]
if len(dirs) == 1:
zig_root = dirs[0]
else:
candidates = [p for p in extract_dir.rglob("*") if p.is_file() and p.name in ("zig", "zig.exe")]
if not candidates:
raise SystemExit("Unable to locate zig executable after extraction")
exe = candidates[0]
zig_root = exe.parent.parent if exe.parent.name == "bin" else exe.parent

zig_exe_name = "zig.exe" if runner_os == "Windows" else "zig"
zig_path = zig_root / zig_exe_name
if not zig_path.exists():
zig_path = zig_root / "bin" / zig_exe_name
if not zig_path.exists():
raise SystemExit(f"Unable to find zig executable under {zig_root}")

with pathlib.Path(os.environ["GITHUB_PATH"]).open("a", encoding="utf-8") as f:
f.write(str(zig_path.parent) + "\n")

print(f"Installed Zig {version} at {zig_path}", flush=True)
PY
uses: mlugg/setup-zig@v2
with:
version: master
cache-key: ${{ runner.os }}-${{ hashFiles('build.zig', 'build.zig.zon') }}

- name: Zig Version
run: zig version

- name: Format Check
shell: bash
run: |
files=$(find . -type f -name '*.zig' \
-not -path './.zig-cache/*' \
-not -path './.zig-cache-*/*' \
-not -path './.zig-global-cache/*' \
-not -path './zig-out/*')
zig fmt --check $files

- name: Build
run: zig build

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.zig-cache/
.zig-cache-global/
.zig-cache-local/
zig-pkg/
.scratch/
zig-out/
zig-out-clean-dyn/
zig-out-clean-macos-dyn/
Expand Down
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Thanks for contributing to WebUI Zig.

## Development Setup

- Zig `0.15.2+` (see `build.zig.zon`)
- Zig `0.16.0-dev.2984+cb7d2b056` or newer
- CI tracks Zig `master` via `mlugg/setup-zig`
- Linux, macOS, or Windows

Core commands:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Zig-first WebUI runtime with typed RPC, deterministic launch policy, native host launch paths, and browser/web fallbacks.

![Zig](https://img.shields.io/badge/Zig-0.15.2%2B-f7a41d)
![Zig](https://img.shields.io/badge/Zig-0.16--dev%20%2F%20master-f7a41d)
![Platforms](https://img.shields.io/badge/Platforms-Linux%20%7C%20macOS%20%7C%20Windows-2ea44f)
![Mode](https://img.shields.io/badge/Transport-WebView%20%2B%20Browser%20%2B%20Web-0366d6)

Expand Down
Loading
Loading