Skip to content

zig: release packaging on 0.17, with Velopack 1.2.161 - #448

Merged
foxnne merged 7 commits into
zig/0.17from
zig/017-release-packaging
Oct 16, 2026
Merged

foxnne merged 7 commits into
zig/0.17from
zig/017-release-packaging

Conversation

@foxnne

@foxnne foxnne commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Part of fizzyedit/plans#5 (plans/ZIG_0_17_PLAN.md, step 2: the build system). Stacked on #438 (and #437): based on zig/017-build-steps, so this diff is only release packaging.

What changes

Velopack 1.2.161. velopack_zig moves to graphl-tech/velopack-zig#9 (a80b037, its Zig 0.17 port), and with it Velopack's runtime goes from 0.0.1589 to 1.2.161. vpk in .config/dotnet-tools.json goes from 0.0.1298 to 1.2.161; vpk 1.2 targets .NET 10, so release.yml installs 10.0, not 8.0. What users gain is in velopack-zig#9: a code signature that survives updates on macOS, atomic macOS updates, the Linux locator fix, delta fixes, and 64-bit Windows bootstrappers. Velopack.h only gained declarations; fizzy's updater is unchanged.

The rest of the build system's 0.17 stand-ins:

  • Velopack.h as a module. @cImport is gone. velopack.linkVelopack(.c_modules = …) gives each module that calls the C API a velopack_c import (translate-c), once per module: the integration, demo and bench tests share one app module. The updater imports it only when Velopack is enabled.
  • vpk pack runs through velopack-zig's tools/run_env.zig (velopack.addVpkRun), which sets DOTNET_ROLL_FORWARD and puts the bundled mksquashfs on PATH when vpk runs. So does the MSVC setup script. In 0.17, Run.setEnvironmentVariable freezes the configure-time environment into the cached configuration, and Run.addPathDir is gone. MksquashfsBuild.bin_dir is now mksquashfs's own output directory, with no install step.
  • Signing and the macOS SDK are options only. -Dmacos-sign-app, -Dmacos-sign-installer and -Dmacos-notary-profile lose their FIZZY_MACOS_* environment fallbacks, and SDKROOT becomes -Dmacos-sdk: 0.17 caches the configuration without regard to the environment. scripts/release.sh and release.yml's macOS job turn the same variables into the options, and packageall forwards them to its macOS children.
  • No global --libc: -Dwindows-msvc-libc or the managed .velopack-msvc/ only. The managed manifest's existence and an explicit manifest's contents are declared to the configure cache.
  • The MSVC translate-c shim works again. It finds each module's translate-c step through the generated-file index and Step.cast, as std.Build does, in place of the removed Step.id.
  • docs/PITFALLS.md, "The build (Zig 0.17)": the four traps (environment reads, setEnvironmentVariable, undeclared configure-time reads, declared paths in missing directories), each with what fizzy does instead.

After this, 36 ZIG017 markers remain on the branch, none in the build system: the zon stand-ins, the @typeInfo helpers, the example-branch switch.

SDK impact

  • None: no sdk/ file changes here.
  • Core-only or additive: reaches plugins at the next SDK release
  • Fingerprint moved
  • SDK release

Verified

  • macOS (arm64, 0.17.0):
    • zig build package packs a release with vpk 1.2.161: fizzy-arm64-macos-Setup.pkg, -Portable.zip, fizzy-0.2.0-arm64-macos-full.nupkg. The bundle carries Contents/Resources/sq.version, 1.x's signature-preserving layout. Unsigned: no identities on this machine.
    • zig build -Dvelopack=true links Velopack (36 vpkc_ symbols); zig build test-integration -Dvelopack=true (79/79 steps).
    • scripts/check-fmt.sh, zig build, zig build test, zig build test-integration (77/77 steps), zig build check-web, zig build test-sdk-version.
    • scripts/check-examples.sh against the examples' zig-0.17 branches: all 8 builds pass.
    • zig build -Dtarget=x86_64-windows-msvc configures; -Dtarget=x86_64-windows-gnu -Dno-emit builds.
  • Windows: not run. The MSVC path (.velopack-msvc/, the shim) needs a packaging run.
  • Linux: not run. The AppImage path is velopack-zig#9's run_env --path, which its CI passes on ubuntu-latest.
  • A test release. release.yml packaging all six targets, signed, is the real check for this PR. It has no dry-run mode: it releases an existing tag and stops at a draft GitHub release, which nothing auto-updates to until it is published. So the check is a test tag on this branch (e.g. v0.2.0-zig017.1), the workflow's draft release, then deleting both. Tagging is the maintainer's call.
  • An update round trip, from an installed 0.0.1589-runtime release to one packed with this, per OS. It waits for that dry run's artifacts.

🤖 Generated with Claude Code

foxnne and others added 3 commits October 15, 2026 14:58
Opens the zig/0.17 integration branch (plans/ZIG_0_17_PLAN.md) green
on 0.17: the toolchain, the forks' zig-0.17 commits, the mechanical
rewrites from scripts/zig-0.17/rewrite.sh, and hand edits. Where a
migration is still to be done properly, a stand-in marked ZIG017
holds its place; each later PR into zig/0.17 replaces some, and the
merge to main has none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zig 0.17 runs build.zig in a configurer and the graph in a separate
maker, with no custom steps. The plugin dev install and "set aside a
running executable" are now small programs run by Run steps; the stale
`update` step is deleted. Configure-time file reads are declared to
0.17's configure cache, and FIZZY_PLUGIN_USE_LLVM becomes
-Dplugin-use-llvm, because 0.17 caches the configuration without regard
to the environment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Packaging builds and runs on Zig 0.17: velopack-zig moves to its 0.17
branch, and Velopack's runtime and vpk to 1.2.161 (.NET 10). Velopack.h
is a translate-c module; commands that need their environment changed
run through velopack-zig's run_env; signing and the macOS SDK are -D
options, which scripts/release.sh and release.yml pass; the MSVC
translate-c shim finds its steps by tag. docs/PITFALLS.md records the
four build traps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from zig/017-build-steps to zig/0.17 October 16, 2026 13:10
@foxnne
foxnne marked this pull request as ready for review October 16, 2026 13:47
foxnne and others added 3 commits October 16, 2026 09:28
…c file

On Zig 0.17 dvui translates its headers with the translate-c package's
tool, a Run step, not Step.TranslateC, so the MSVC fix-up never reached
them and `string.h` was not found. The fix-up now finds both kinds
through the module graph: a tool gets `--libc=<ini>` (before its `--`)
and the stdint shim and SIZE_MAX. velopack-zig writes the libc file's
0.17 fields (cc_dir, darwin_sdk_dir). Found by the test release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… out

Two more *-windows-msvc failures the test release found, each checked
by packaging x86_64 and aarch64 Windows locally against the real MSVC
SDK (msvcup). Zig 0.17 no longer links oldnames.lib, which supplies
getcwd/chdir (dvui's tinyfiledialogs, fizzy's startup). And fizzy's
sdl_zig compiled SDL's Linux core for every target; SDL_dbus.c needs
<unistd.h>, which MSVC lacks. That one predates 0.17: the current SDL
setup never went through a Windows MSVC release, and CI's Windows
build is windows-gnu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of fizzyedit/plans#5 (`plans/ZIG_0_17_PLAN.md`, step 2:
`std.zon.parse`). **Stacked on #448**: based on
`zig/017-release-packaging`, so this diff is only the zon work.

## What changes

Zig 0.17's `std.zon.parse.fromSlice` takes a `gpa` for scratch and an
`arena` that owns the result and any diagnostics, and there is no
`free`. The scaffold (#437) bridged it with a stand-in: parse into a
throwaway arena, deep-copy into the old allocator, plus a file-local
copy of 0.16's `free`, in 20 files. This replaces every call with the
arena that actually owns its result. The diff is −1,298/+200: the
generated copy-and-free helpers go.

- **Parsed, used and freed in one scope** (recents, the settings
migrations, the workbench layout snapshot, the window-layout reads and
saves, tests): a local arena that dies where the free used to run.
Lifetimes are unchanged.
- **Parsing into an arena already** (`sdk.events.parse`, `Tape.parse`,
the restart session, `Command.Call.parse`, the replay and profile
tests): that arena, passed as `.arena`.
- **Types that hold no pointers** (the saved window geometry, SDL's
saved window, the demo verdict's expectations): `fromSliceNoAlloc`. It
checks at compile time that the type holds no pointers, and its result
outlives the arena.
- **API changes, each with every caller updated:**
- `Settings.parseOnly(allocator, arena, data)`. `freeParsed` is gone,
and with it the workaround for freeing a default string literal; `load`
still copies `theme`, the one string it keeps.
- `sdk.Manifest.parse(gpa, arena, source)`. `Manifest.free` is gone. All
of `PluginLoader`'s calls already parsed and freed in one scope.
  - `layout_file.loadWindowFile(gpa, arena, dir)`.
- **Plugin settings** (`sdk.settings.Schema`, `applyZon` and setting one
field from ZON text) parse into a short-lived arena, then copy a
non-default string out into the schema's allocator. `freeOwned`'s rule
still holds: a field is the schema's to free unless it is the declared
default.
- **Build scripts** reading a plugin's `plugin.zig.zon` read it into the
build's allocator, which lives as long as the build.
- **`scripts/zig-0.17/rewrite.sh` no longer converts zon calls.** A 0.16
call that a merge from `main` brings now fails to compile and gets
ported by hand.

After this, 4 `ZIG017` markers remain on the branch: the two per-pointer
capture sites (dvui#1014), the examples' branch in `check-examples.sh`,
and the `@typeInfo` field helper.

## SDK impact

- [ ] None
- [x] Core-only or additive: reaches plugins at the next SDK release.
`sdk.Manifest.parse` takes an arena and `sdk.Manifest.free` is gone.
That is SDK API, but not the plugin boundary: no fingerprint move (`zig
build test-sdk-version` passes), and no store plugin calls either.
- [ ] Fingerprint moved
- [ ] SDK release

## Verified

- [x] macOS (arm64, 0.17.0):
- `scripts/check-fmt.sh`, `zig build`, `zig build test` (91/91 steps),
`zig build test-integration` (77/77 steps, 523/523 tests, no leak
reports), `zig build check-web`, `zig build test-sdk-version`, `zig
build check-tests-reached`, `zig build -Dvelopack=true`.
- `scripts/check-examples.sh` against the examples' `zig-0.17` branches:
all 8 builds pass.
- The app, in a sandbox profile with an existing `layout.zon` and
`recents.zon`: starts without a parse warning. With a `settings.zon`
naming a non-default theme, the theme name survives the arena (fizzy's
"did not match any known theme" warning names it), and the settings
migration rewrites the file keeping `theme` and `font_body_size`.
- [ ] Windows: CI.
- [ ] Linux: CI.
- [x] Web: `zig build check-web`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne merged commit 2491f4e into zig/0.17 Oct 16, 2026
13 checks passed
@foxnne
foxnne deleted the zig/017-release-packaging branch October 16, 2026 16:34
@foxnne foxnne mentioned this pull request Oct 17, 2026
2 tasks done
foxnne added a commit that referenced this pull request Oct 18, 2026
Part of fizzyedit/plans#5 (`plans/ZIG_0_17_PLAN.md`, step 2). Writes
down the three Windows traps the 0.17 release work (#448) cost time on,
so they cost the next person a minute.

## What changes

`docs/PITFALLS.md`, under "The build (Zig 0.17)", gets a "Windows, on
0.17" subsection:

- **An MSVC exe must link `oldnames` itself.** 0.16 did it for every
`*-windows-msvc` exe and 0.17 doesn't, so `getcwd`/`chdir` stop
resolving. Now in `build/exe.zig`.
- **`translate-c` takes `--libc=<ini>` before its `--`.** After the
`--`, the flag goes to the C front end and is lost. Now in
`build/msvc.zig`.
- **sdl_zig must filter SDL's `core/linux/` for Windows.** `SDL_dbus.c`
includes `<unistd.h>` before its guard. Done in fizzyedit/sdl_zig
`ef7eb36`; a move to upstream sdl_zig must keep the filter.

## SDK impact

- [x] None. Docs only.

## Verified

- [x] Docs only: checked each entry against the code it names
(`build/exe.zig`, `build/msvc.zig`, sdl_zig `build.zig` at `ef7eb36`).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne foxnne mentioned this pull request Oct 18, 2026
3 of 4 tasks
foxnne added a commit that referenced this pull request Oct 18, 2026
Part of fizzyedit/plans#5 (`plans/ZIG_0_17_PLAN.md`, step 2): fizzy, its
backend and its bundled plugins move to Zig 0.17. Every piece was
reviewed as its own PR into `zig/0.17`, and this PR lands that branch.
`main` is already merged in (through #555), so it carries no conflicts.

## What changes

**The move to 0.17** (`minimum_zig_version = "0.17.0"` everywhere), as
reviewed in:
- #437: the switch, scaffolded with marked stand-ins
- #438: the build's custom steps become helper programs
- #448: release packaging on 0.17, with Velopack 1.2.161 (+ #452's zon
arenas)
- #488: settings and command schemas read 0.17's `@typeInfo`, with a
test that the SDK fingerprint hashes the same facts as on 0.16
- #489: per-pointer capture through `captureMouseGet`
- #494: the Windows traps in `docs/PITFALLS.md`
- #496: `blitData` without an `extern struct` `@bitCast`
- #498: `fizzy.plugin.installBeside`, for a plugin's helper program
- #505: the 0.16 inflate workaround goes; the docs say 0.17
- #561: review fixes. A settings payload with pointers is a compile
error, and build reads go through `b.root`.
- #573: the plugin install helper compiles once, in Debug
- the catch-ups with `main` (#486, #503, #558, #574, and the last merge
here), each with `scripts/zig-0.17/rewrite.sh` re-run. That script is
deleted in the last commit.

Most of the diff is mechanical: `zig fmt`'s upgrades (`@backingInt`,
`std.lang`, …) and one-answer renames. The hand migrations are the build
(configure/make split, no custom steps), the zon arenas, `@typeInfo`,
translate-c for `@cImport`, and the `@bitCast` audit. A high-effort
review of the whole `main`…`zig/0.17` diff found five things; the three
correctness ones are fixed in #561, and one efficiency one in #573.

**Also on the branch, merged there by the maintainer:** the windowing
work.
- #480–#483: plain dvui apps on macOS
- #492, #501, #504, #510: OS windows for floating windows, full screen,
pointer routing
- #546: window materials

**Forks:** dvui-dev at its `zig-0.17` head `1b29a16`, which carries
fizzy-dev's patches on upstream's 0.17 `main`, including #540, #544 and
#563's dvui commits. Also assetpack, md4zig, sdl_zig and zig-objc on
their `zig-0.17` branches, and velopack-zig `3d553b7` (tagged
`fizzy-zig0.17`).

## Measured

macOS arm64, under load from other sessions, each step alternated
between the two. 0.16 is `main` #509; 0.17 is `zig/0.17` with #561.

| | Zig 0.16 | Zig 0.17 |
|---|---|---|
| App, cold Debug build | 94.4 s | 78.6 s |
| App, warm no-op rebuild | 0.7 s | 0.4 s |
| `test-integration` (compile + run) | 108.9 s | 90.4 s |
| App, ReleaseFast build | 142.8 s | 131.5 s |
| Image plugin, cold standalone build | 11.6 s | 14.0 s (with #573) |
| Startup, Debug (median of 5) | 565 ms | 466 ms |
| Startup, ReleaseFast (median of 5) | 175 ms | 177 ms |
| Text, ReleaseFast, µs/frame: idle / mid / scroll / typing | 305 / 424
/ 435 / 403 | 240 / 306 / 286 / 290 |
| Markdown, ReleaseFast, 4 docs, median of 5, µs/frame: idle top / mid /
scroll / resize | 1177 / 1735 / 2104 / 1319 | 1270 / 1699 / 1833 / 1192
|

The one slowdown is markdown idle at the top of a document, +8%. The
rest of the plugin build's gap is dvui's own translate-c on 0.17.

## The plan's gate

- **ZLS:** no 0.17 release yet (latest 0.16.0). zigtools/zls#3270 is on
ZLS's master. Completions across `fizzy_sdk` from a plugin are not
checked.
- **Minimum OS:** 0.17 needs Darwin 15+ (OS X 10.11); fizzy's macOS
minimum is 11.0, so no change. Windows 10+ and Linux 5.10+ are not
stated by fizzy.
- **Debug leak reports:** still print (`DebugAllocator`, deprecated,
unchanged). The move to `SafeAllocator` is a follow-up with its own
Debug frame-time check.
- **Velopack:** packaging proven by a test release on macOS (signed and
notarized), Windows and Linux. An update in place was not tested.
- **Every target builds:** in CI. Windows and Linux were not run by hand
on the VMs.

## SDK impact

- [x] Fingerprint moved (`0x5f9c818a6972efd4`, recorded in
`sdk/src/version.zig`); `sdk_version` untouched. `sdk: release 0.2.30`
follows this at once. Plugins need Zig 0.17 to build against it: there's
no overlap window.
- Plugin authors see `minimum_zig_version = "0.17.0"` and
`fizzy.plugin.installBeside`. A settings payload holding pointers other
than a string is now a compile error. `docs/PLUGINS.md` says 0.17.0.

## Right after this merges

1. fizzyedit/example-app#8 and fizzyedit/example-plugin#13 merge. Then a
one-line PR points `scripts/check-examples.sh` back at `main` (it pins
the examples' `zig-0.17` branches until then, so `main`'s CI is never
red).
2. `sdk: release 0.2.30`.
3. The store plugins' 0.17 PRs repin and release: fizzyedit/pixi#51,
zig#15, atlas#16, drive#13, ghostty#14, agent#23, chat#16.

## Verified

- [x] macOS (arm64, Zig 0.17.0), on this tree:
  - `scripts/check-fmt.sh`
  - `zig build`: 71/71
  - `zig build test`: 109/109 steps, 637/638 (1 skipped)
  - `zig build check-tests-reached`: 998 tests in 122 files
  - `zig build check-web`: 42/42
  - `zig build test-sdk-version`: 35/35
  - `zig build test-integration`: 78/78 steps, 608/608
- [x] All seven store plugins built against `zig/0.17`'s `sdk/` and
loaded together in a 0.17 fizzy (Debug, sandbox profile).
- [ ] Windows, Linux, the example repos: CI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant