Zig 0.15.x Migration Checklist
This plan captures every known change required to move the codebase and tooling from Zig 0.14.x to Zig 0.15.x. Work through the sections in order; each bullet calls out the exact files and symbols to touch so we can execute without additional clarification.
1. Toolchain & Automation
- Update
flake.nix:19to pinzig-0.15.x(remove thezig-0.14.0fallback logic) and ensureshell.nix:3selects the same package sonix developexposes the new compiler. - Bump both Zig installs in
.github/workflows/ci.ymltoversion: 0.15.x(jobschecksandrelease-artifacts). Keep the current target matrix, just validate the new runner can build them. - After the bump, clear cached hooks (
pre-commit clean) sopre-commit run --all-filespulls the 0.15 binary. No config change needed. - Revise onboarding docs that mention the Zig pin (
AGENTS.mdor any other references) so contributors install the correct release.
2. Std I/O Accessors
- Replace
std.io.getStdIn()/getStdErr()usages with the new file helpers:src/sydra/server.zig:85→ usevar stdin_file = std.fs.File.stdin();thenvar reader_state = stdin_file.reader(&buf); const reader = reader_state.interface();.examples/loadgen.zig:7andsrc/sydra/compat/log.zig:20→ usestd.fs.File.{stdout,stderr}().writer(&buf)(keep the writer state alive and grab.interface()when needed).
- Audit for any other direct
std.io.get*calls and convert them tostd.fs.File.*.
3. HTTP Server Plumbing
- In
src/sydra/http.zigallocate read/write buffers per connection, then call:var reader_state = connection.stream.reader(&in_buf);
var writer_state = connection.stream.writer(&out_buf);
var http_server = std.http.Server.init(reader_state.interface(), writer_state.interface()); - For request bodies switch to the new reader constructors:
- Use
var body_reader = try req.readerExpectContinue(&buf);when honoringExpect: 100-continue, orreq.readerExpectNone(&buf)when no expectation is present. - The returned value is
*std.http.Server.Readerwhich already satisfiesstd.Io.Reader, so callbody_reader.readNoEof(...)directly.
- Use
respondStreamingnow expects the buffer argument first; update calls atsrc/sydra/http.zig:426andsrc/sydra/http.zig:472.- Ensure the writer state lives as long as the connection loop (don’t let it go out of scope).
4. Pgwire Server & Protocol
- Wrap connections with explicit buffer states before the handshake (
src/sydra/compat/wire/server.zig:24-66) and passreader_state.interface()/writer_state.interface()intosession.performHandshake. - Update
messageLoopto accept*std.Io.Reader/*std.Io.Writerand replacereader.*.readNoEofwithreader.readNoEof. - Adjust
protocol.zighelpers (readStartup, writers, tests) to operate on interfaces rather than the legacy reader struct. - Fix tests in
session.zigto build interface wrappers fromstd.io.fixedBufferStreamvia.reader()/.writer()→.interface().
5. Storage & Codec Reads/Writes
- For every
file.reader(&buf)call (WAL, segments, tags, manifests) hold on to the state and interact through its.interface():var reader_state = f.reader(&buf);
const reader = reader_state.interface();
try reader.readNoEof(...); - Update helper functions such as
readExact(src/sydra/storage/wal.zig) and the Gorilla codec readers to take*std.Io.Readerand use the new method names. - When using
file.writer(&buf)grab the interface viawriter_state.interface()instead of the deprecated pointer hack.
6. Error Handling & API Tightening
- Replace the
_ = err;pattern insrc/sydra/engine.zig:189-193with explicit error handling (e.g., acatch |err| { std.log.warn(...); continue; }block) because Zig 0.15 no longer allows silent discards. - Review any
catchblocks that mentionerror.EndOfStream; the new reader error set differs. Either handle it explicitly or map it to your own error type. - Run
zig fmtafter all code edits; the formatter will catch lingering layout issues (e.g.,src/sydra/codec/zstd.zig,src/sydra/config.zigwere cited by pre-commit).
7. Verification Checklist
zig fmt(root)zig buildzig build testpre-commit run --all-files --show-diff-on-failure- Manual smoke tests:
- Start HTTP server, hit
/metrics, POST/api/v1/ingest, and query/api/v1/query/range. - Run
sydradb pgwireand confirm apsqlstartup handshake succeeds (seelogs/logs_47733482709/2_Checks (ubuntu-latest).txtfor prior failures).
- Start HTTP server, hit
- When everything passes locally, push to a branch and verify the GitHub Actions matrix completes; expect cache misses on the first run due to the compiler upgrade.
Tip: keep the migration in a dedicated branch. Once CI is green, update release notes for v0.15 adoption and retag the workflow if necessary.