From c4a2ea8cac9cb39ff5ce19dd816c87130133b529 Mon Sep 17 00:00:00 2001 From: ItsMeSamey Date: Sun, 4 Oct 2026 08:20:33 +1000 Subject: [PATCH 1/2] fix: migrate to Zig 0.17.0 --- .github/workflows/ci.yml | 2 +- CONTRIBUTING.md | 2 +- DOCUMENTATION.md | 2 +- README.md | 4 ++-- build.zig | 8 ++------ build.zig.zon | 2 +- src/core/network.zig | 12 ++++++------ src/core/session.zig | 2 +- src/runtime.zig | 2 +- src/session_cache/store.zig | 18 +++++++++--------- src/tools/dispatch.zig | 4 ++-- src/util/compat.zig | 8 ++++---- 12 files changed, 31 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3b67c3..0a765ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: - name: Setup Zig uses: mlugg/setup-zig@v2 with: - version: master + version: 0.17.0 - name: Zig Version run: zig version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a91b56..c8b3665 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -Use Zig **0.16.0**, Git, and an installed Brave browser for the required Chromium integration gate. +Use Zig **0.17.0**, Git, and an installed Brave browser for the required Chromium integration gate. ```sh zig build diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 88ca46a..4f2c1ec 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1,6 +1,6 @@ # alldriver API -`alldriver` requires Zig 0.16.0. The supported browser scope is Chromium over CDP. The required real-browser suite targets Brave; Chrome and Edge use the same Chromium protocol surface, but a Brave run does not independently certify every browser/version/OS combination. +`alldriver` requires Zig 0.17.0. The supported browser scope is Chromium over CDP. The required real-browser suite targets Brave; Chrome and Edge use the same Chromium protocol surface, but a Brave run does not independently certify every browser/version/OS combination. Firefox and other Gecko browsers, BiDi, Safari/WebKit, Lightpanda, and platform-specific webviews are outside the currently validated scope. Their discovery entries or existing APIs are not support guarantees. diff --git a/README.md b/README.md index 469d735..2ed7a08 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # alldriver -Chromium browser automation for Zig 0.16, using the Chrome DevTools Protocol (CDP). +Chromium browser automation for Zig 0.17, using the Chrome DevTools Protocol (CDP). Launch or attach to a browser, navigate pages, send trusted input, inspect network traffic, and collect screenshots, traces, logs, and downloads. The public API lives under `driver.modern`. @@ -33,7 +33,7 @@ Install with `zig fetch --save git+https://github.com/SmallThingz/alldriver`, th ## Validation -Use Zig **0.16.0** and an installed Brave browser: +Use Zig **0.17.0** and an installed Brave browser: ```sh zig build diff --git a/build.zig b/build.zig index 40a2500..dc2e5a1 100644 --- a/build.zig +++ b/build.zig @@ -146,16 +146,12 @@ pub fn build(b: *std.Build) void { // This allows the user to pass arguments to the application in the build // command itself, like this: `zig build run -- arg1 arg2 etc` - if (b.args) |args| { - run_cmd.addArgs(args); - } + run_cmd.addPassthruArgs(); const tools_step = b.step("tools", "Run alldriver_tools commands (pass args after --)"); const run_tools_cmd = b.addRunArtifact(tools_exe); tools_step.dependOn(&run_tools_cmd.step); - if (b.args) |args| { - run_tools_cmd.addArgs(args); - } + run_tools_cmd.addPassthruArgs(); const example_specs = [_]struct { name: []const u8, path: []const u8 }{ .{ .name = "example-01-discover", .path = "examples/01_discover.zig" }, diff --git a/build.zig.zon b/build.zig.zon index 39b1eef..2d50295 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -25,7 +25,7 @@ .fingerprint = 0xc6e7cf56a1c47921, // Changing this has security and trust implications. // Tracks the earliest Zig version that the package considers to be a // supported use case. - .minimum_zig_version = "0.16.0", + .minimum_zig_version = "0.17.0", // This field is optional. // Each dependency must either provide a `url` and `hash`, or a `path`. // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. diff --git a/src/core/network.zig b/src/core/network.zig index 514bc02..a8d9e2a 100644 --- a/src/core/network.zig +++ b/src/core/network.zig @@ -1050,11 +1050,11 @@ fn cloneOwned(comptime T: type, allocator: std.mem.Allocator, source: T) !T { .@"struct" => |info| { var out: T = undefined; var initialized: usize = 0; - errdefer inline for (info.fields, 0..) |field, i| { - if (i < initialized) freeOwned(field.type, allocator, @field(out, field.name)); + errdefer inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + if (i < initialized) freeOwned(field_type, allocator, @field(out, field_name)); }; - inline for (info.fields) |field| { - @field(out, field.name) = try cloneOwned(field.type, allocator, @field(source, field.name)); + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(out, field_name) = try cloneOwned(field_type, allocator, @field(source, field_name)); initialized += 1; } return out; @@ -1073,8 +1073,8 @@ fn freeOwned(comptime T: type, allocator: std.mem.Allocator, value: T) void { for (value) |item| freeOwned(ptr.child, allocator, item); allocator.free(value); }, - .@"struct" => |info| inline for (info.fields) |field| { - freeOwned(field.type, allocator, @field(value, field.name)); + .@"struct" => |info| inline for (info.field_names, info.field_types) |field_name, field_type| { + freeOwned(field_type, allocator, @field(value, field_name)); }, .@"union" => switch (value) { inline else => |payload| freeOwned(@TypeOf(payload), allocator, payload), diff --git a/src/core/session.zig b/src/core/session.zig index 96ade67..a4667e5 100644 --- a/src/core/session.zig +++ b/src/core/session.zig @@ -1028,7 +1028,7 @@ const SessionEventCapture = struct { last_navigation_completed_cause: ?types.NavigationCause = null, last_navigation_failed_error: ?[]const u8 = null, last_navigation_failed_cause: ?types.NavigationCause = null, - reload_url_buf: [512]u8 = [_]u8{0} ** 512, + reload_url_buf: [512]u8 = @splat(0), last_reload_url: ?[]const u8 = null, last_reload_failed_error: ?[]const u8 = null, last_wait_target: ?types.WaitTargetTag = null, diff --git a/src/runtime.zig b/src/runtime.zig index c6a4ed2..57f7f1a 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -684,7 +684,7 @@ fn waitForDebugEndpointReady( fn childExitedPosixNoHang(child: *std.process.Child) bool { if (@import("builtin").os.tag == .windows or @import("builtin").os.tag == .wasi) return false; const pid = child.id orelse return true; - var status: if (@import("builtin").link_libc) c_int else u32 = undefined; + var status: i32 = undefined; const result = std.posix.system.waitpid(pid, &status, std.posix.W.NOHANG); switch (std.posix.errno(result)) { .SUCCESS => { diff --git a/src/session_cache/store.zig b/src/session_cache/store.zig index b0ec724..c0e4289 100644 --- a/src/session_cache/store.zig +++ b/src/session_cache/store.zig @@ -412,7 +412,7 @@ fn cookiesToJson(allocator: std.mem.Allocator, cookies: []const types.Cookie) !s try obj.put(allocator, "sameSite", .{ .string = @tagName(cookie.same_site) }); try arr.append(allocator, .{ .object = obj }); } - return .{ .array = .{ .items = try arr.toOwnedSlice(allocator), .capacity = arr.items.len, .allocator = allocator } }; + return .{ .array = .fromOwnedSlice(allocator, try arr.toOwnedSlice(allocator)) }; } fn storageToJson(allocator: std.mem.Allocator, values: []const types.StorageValue) !std.json.Value { @@ -424,7 +424,7 @@ fn storageToJson(allocator: std.mem.Allocator, values: []const types.StorageValu try obj.put(allocator, "value", .{ .string = item.value }); try arr.append(allocator, .{ .object = obj }); } - return .{ .array = .{ .items = try arr.toOwnedSlice(allocator), .capacity = arr.items.len, .allocator = allocator } }; + return .{ .array = .fromOwnedSlice(allocator, try arr.toOwnedSlice(allocator)) }; } fn headersToJson(allocator: std.mem.Allocator, headers: []const types.Header) !std.json.Value { @@ -436,7 +436,7 @@ fn headersToJson(allocator: std.mem.Allocator, headers: []const types.Header) !s try obj.put(allocator, "value", .{ .string = h.value }); try arr.append(allocator, .{ .object = obj }); } - return .{ .array = .{ .items = try arr.toOwnedSlice(allocator), .capacity = arr.items.len, .allocator = allocator } }; + return .{ .array = .fromOwnedSlice(allocator, try arr.toOwnedSlice(allocator)) }; } fn parseCookies(allocator: std.mem.Allocator, value: std.json.Value) ![]types.Cookie { @@ -538,11 +538,11 @@ fn cloneOwned(comptime T: type, allocator: std.mem.Allocator, source: T) !T { .@"struct" => |info| { var out: T = undefined; var initialized: usize = 0; - errdefer inline for (info.fields, 0..) |field, i| { - if (i < initialized) freeOwned(field.type, allocator, @field(out, field.name)); + errdefer inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + if (i < initialized) freeOwned(field_type, allocator, @field(out, field_name)); }; - inline for (info.fields) |field| { - @field(out, field.name) = try cloneOwned(field.type, allocator, @field(source, field.name)); + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(out, field_name) = try cloneOwned(field_type, allocator, @field(source, field_name)); initialized += 1; } return out; @@ -558,8 +558,8 @@ fn freeOwned(comptime T: type, allocator: std.mem.Allocator, value: T) void { for (value) |item| freeOwned(ptr.child, allocator, item); allocator.free(value); }, - .@"struct" => |info| inline for (info.fields) |field| { - freeOwned(field.type, allocator, @field(value, field.name)); + .@"struct" => |info| inline for (info.field_names, info.field_types) |field_name, field_type| { + freeOwned(field_type, allocator, @field(value, field_name)); }, .optional => |info| if (value) |item| { freeOwned(info.child, allocator, item); diff --git a/src/tools/dispatch.zig b/src/tools/dispatch.zig index 125922b..27fbf10 100644 --- a/src/tools/dispatch.zig +++ b/src/tools/dispatch.zig @@ -805,8 +805,8 @@ const DetectionSignals = struct { fn signalCount(self: DetectionSignals) usize { var count: usize = 0; - inline for (std.meta.fields(DetectionSignals)) |field| { - if (@field(self, field.name)) count += 1; + inline for (@typeInfo(DetectionSignals).@"struct".field_names) |field_name| { + if (@field(self, field_name)) count += 1; } return count; } diff --git a/src/util/compat.zig b/src/util/compat.zig index ba2cd41..b8f2e76 100644 --- a/src/util/compat.zig +++ b/src/util/compat.zig @@ -128,7 +128,7 @@ pub const CwdDir = struct { pub fn createFile( self: CwdDir, sub_path: []const u8, - flags: std.Io.File.CreateFlags, + flags: std.Io.Dir.CreateFileOptions, ) std.Io.File.OpenError!std.Io.File { return self.inner.createFile(io(), sub_path, flags); } @@ -136,7 +136,7 @@ pub const CwdDir = struct { pub fn openFile( self: CwdDir, sub_path: []const u8, - flags: std.Io.File.OpenFlags, + flags: std.Io.Dir.OpenFileOptions, ) std.Io.File.OpenError!std.Io.File { return self.inner.openFile(io(), sub_path, flags); } @@ -190,11 +190,11 @@ pub fn openDirAbsolute(path: []const u8, options: std.Io.Dir.OpenOptions) std.Io return std.Io.Dir.openDirAbsolute(io(), path, options); } -pub fn openFileAbsolute(path: []const u8, flags: std.Io.File.OpenFlags) std.Io.File.OpenError!std.Io.File { +pub fn openFileAbsolute(path: []const u8, flags: std.Io.Dir.OpenFileOptions) std.Io.File.OpenError!std.Io.File { return std.Io.Dir.openFileAbsolute(io(), path, flags); } -pub fn createFileAbsolute(path: []const u8, flags: std.Io.File.CreateFlags) std.Io.File.OpenError!std.Io.File { +pub fn createFileAbsolute(path: []const u8, flags: std.Io.Dir.CreateFileOptions) std.Io.File.OpenError!std.Io.File { return std.Io.Dir.createFileAbsolute(io(), path, flags); } From d5a7f2535c8f1516888eb1b7bd155bc77646dd62 Mon Sep 17 00:00:00 2001 From: ItsMeSamey Date: Sun, 4 Oct 2026 09:08:55 +1000 Subject: [PATCH 2/2] chore: refresh Zig release build guidance --- examples/README.md | 2 +- src/tools/dispatch.zig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/README.md b/examples/README.md index cb3faf3..69fe688 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,6 @@ # Examples -These examples target Zig 0.16.0. Desktop launch examples select Chromium browsers; compilation alone does not validate their runtime behavior. +These examples target Zig 0.17.0. Desktop launch examples select Chromium browsers; compilation alone does not validate their runtime behavior. ## Build All Examples diff --git a/src/tools/dispatch.zig b/src/tools/dispatch.zig index 27fbf10..98456b6 100644 --- a/src/tools/dispatch.zig +++ b/src/tools/dispatch.zig @@ -2248,7 +2248,7 @@ fn cmdReleaseBundle(allocator: Allocator, root: []const u8, args: []const []cons try cmdMatrixCollect(allocator, root, &.{ "--strict-ga", "--matrix-root", matrix_root, "--out", summary_path }); } - try runInherit(allocator, &.{ "zig", "build", "-Doptimize=ReleaseSafe" }, root, &env); + try runInherit(allocator, &.{ "zig", "build", "-Doptimize=safe" }, root, &env); const bundle_dir = try path_util.pathJoin(allocator, &.{ root, "artifacts", "release", release_id.? }); defer allocator.free(bundle_dir);