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
57 changes: 51 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,31 @@ on:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
- cron: '17 6 * * 1'
workflow_dispatch:

jobs:
test:
name: Test on ${{ matrix.os }} with Zig ${{ matrix.zig-version }}
name: Test on ${{ matrix.os }} with supported Zig
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
zig-version: ['0.17.0-dev']
fail-fast: false

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Read supported Zig version
id: zig-version
run: echo "version=$(cat .zig-version)" >> "$GITHUB_OUTPUT"

- name: Setup Zig
uses: pantry-pm/pantry/packages/action@main
with:
packages: zig@0.17.0-dev
packages: zig@${{ steps.zig-version.outputs.version }}

- name: Verify Zig installation
run: zig version
Expand All @@ -45,10 +51,14 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Read supported Zig version
id: zig-version
run: echo "version=$(cat .zig-version)" >> "$GITHUB_OUTPUT"

- name: Setup Zig
uses: pantry-pm/pantry/packages/action@main
with:
packages: zig@0.17.0-dev
packages: zig@${{ steps.zig-version.outputs.version }}

- name: Check formatting
run: zig fmt --check .
Expand All @@ -61,10 +71,14 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Read supported Zig version
id: zig-version
run: echo "version=$(cat .zig-version)" >> "$GITHUB_OUTPUT"

- name: Setup Zig
uses: pantry-pm/pantry/packages/action@main
with:
packages: zig@0.17.0-dev
packages: zig@${{ steps.zig-version.outputs.version }}

- name: Generate docs
run: zig build-lib -femit-docs src/lib.zig
Expand All @@ -83,10 +97,14 @@ jobs:
- name: Checkout code
uses: actions/checkout@v6

- name: Read supported Zig version
id: zig-version
run: echo "version=$(cat .zig-version)" >> "$GITHUB_OUTPUT"

- name: Setup Zig
uses: pantry-pm/pantry/packages/action@main
with:
packages: zig@0.17.0-dev
packages: zig@${{ steps.zig-version.outputs.version }}

- name: Install kcov
continue-on-error: true
Expand Down Expand Up @@ -121,3 +139,30 @@ jobs:
- name: Coverage skipped
if: steps.install-kcov.outcome != 'success'
run: echo "kcov not available on this platform, skipping coverage"

latest-zig:
name: Compatibility with latest Zig 0.17.0-dev
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
continue-on-error: true
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Setup latest Zig development build
uses: pantry-pm/pantry/packages/action@main
with:
packages: zig@0.17.0-dev

- name: Verify Zig installation
run: zig version

- name: Build framework
run: zig build

- name: Run tests
run: zig build test

- name: Run examples
run: zig build examples
1 change: 1 addition & 0 deletions .zig-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.17.0-dev.2163+89ff10d56
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Thank you for your interest in contributing to the Zig Test Framework! This docu

### Prerequisites

- Zig 0.15.1 or later
- The exact Zig development build recorded in [`.zig-version`](.zig-version)
- Git
- Basic understanding of testing frameworks (Jest, Vitest, or similar)

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,10 @@ zig build examples

## Requirements

- Zig 0.15.1 or later
- The exact Zig development build recorded in [`.zig-version`](.zig-version)

See [TOOLCHAIN.md](TOOLCHAIN.md) for the compatibility policy and upgrade
process.

## Documentation

Expand Down
23 changes: 23 additions & 0 deletions TOOLCHAIN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Zig toolchain policy

The Zig Test Framework supports the exact Zig development build recorded in
`.zig-version`. Required CI jobs use that version so pull requests are tested
against a reproducible toolchain.

Because the project follows Zig development builds, CI also runs a scheduled
compatibility check against the latest `0.17.0-dev` build. That check is
informational: an upstream API change should produce an intentional toolchain
update rather than unexpectedly blocking unrelated pull requests.

## Updating Zig

1. Replace the version in `.zig-version` with the full output of `zig version`.
2. Run `zig fmt --check .`.
3. Run `zig build`, `zig build test`, and `zig build examples`.
4. Run `zig build-lib -femit-docs src/lib.zig` and remove the generated local
artifacts after verifying the command succeeds.
5. Summarize required compatibility changes in the pull request and, for a
release, in the changelog.

The compatibility job can also be run manually from GitHub Actions before
updating the pinned version.
4 changes: 1 addition & 3 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ pub fn build(b: *std.Build) void {
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());

if (b.args) |args| {
run_cmd.addArgs(args);
}
run_cmd.addPassthruArgs();

const run_step = b.step("run", "Run the test framework");
run_step.dependOn(&run_cmd.step);
Expand Down
2 changes: 2 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
.paths = .{
"build.zig",
"build.zig.zon",
".zig-version",
"src",
"tests",
"examples",
"TOOLCHAIN.md",
"README.md",
"LICENSE",
},
Expand Down
12 changes: 6 additions & 6 deletions src/compat.zig
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fn closeFd(fd: std.posix.fd_t) void {
/// Read entire file contents using POSIX APIs.
/// Replaces std.fs.cwd().openFile() + file.readToEndAlloc().
pub fn readFileAlloc(allocator: std.mem.Allocator, path: []const u8) ![]const u8 {
const path_z = try allocator.dupeZ(u8, path);
const path_z = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(path_z);

const fd = std.posix.openatZ(std.posix.AT.FDCWD, path_z, .{}, 0) catch |err| {
Expand All @@ -139,7 +139,7 @@ pub fn readFileAlloc(allocator: std.mem.Allocator, path: []const u8) ![]const u8
/// Write content to a file using POSIX APIs.
/// Replaces std.fs.cwd().createFile() + file.writeAll().
pub fn writeFile(allocator: std.mem.Allocator, path: []const u8, content: []const u8) !void {
const path_z = try allocator.dupeZ(u8, path);
const path_z = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(path_z);

const fd = std.posix.openatZ(std.posix.AT.FDCWD, path_z, .{
Expand All @@ -161,7 +161,7 @@ pub fn writeFile(allocator: std.mem.Allocator, path: []const u8, content: []cons
/// Delete a file using POSIX APIs.
/// Replaces std.fs.cwd().deleteFile().
pub fn deleteFile(allocator: std.mem.Allocator, path: []const u8) !void {
const path_z = try allocator.dupeZ(u8, path);
const path_z = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(path_z);
const rc = std.c.unlink(path_z);
if (rc != 0) {
Expand All @@ -175,7 +175,7 @@ pub fn deleteFile(allocator: std.mem.Allocator, path: []const u8) !void {
/// Create directories recursively using POSIX APIs.
/// Replaces std.fs.cwd().makePath().
pub fn makePath(allocator: std.mem.Allocator, path: []const u8) !void {
const path_z = try allocator.dupeZ(u8, path);
const path_z = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(path_z);

const rc = std.c.mkdir(path_z, 0o755);
Expand All @@ -189,7 +189,7 @@ pub fn makePath(allocator: std.mem.Allocator, path: []const u8) !void {
if (sep > 0) {
try makePath(allocator, path[0..sep]);
// Retry creating the directory
const retry_z = try allocator.dupeZ(u8, path);
const retry_z = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(retry_z);
const rc2 = std.c.mkdir(retry_z, 0o755);
if (rc2 != 0 and std.c.errno(rc2) != .EXIST) {
Expand Down Expand Up @@ -298,7 +298,7 @@ pub fn spawnAndWait(
defer allocator.free(c_argv);

for (argv, 0..) |arg, i| {
const z = try allocator.dupeZ(u8, arg);
const z = try allocator.dupeSentinel(u8, arg, 0);
c_argv[i] = z.ptr;
}
c_argv[argv.len] = null;
Expand Down
16 changes: 8 additions & 8 deletions src/snapshot.zig
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,16 @@ pub const Snapshot = struct {
},
.@"struct" => {
try writer.writeAll("{\n");
inline for (type_info.@"struct".fields, 0..) |field, i| {
inline for (type_info.@"struct".field_names, 0..) |field_name, i| {
if (self.options.pretty_print) {
try writer.writeAll(" ");
}
try writer.print("\"{s}\": ", .{field.name});
try writer.print("\"{s}\": ", .{field_name});

const field_value = @field(value, field.name);
const field_value = @field(value, field_name);
try self.formatJsonValue(writer, field_value);

if (i < type_info.@"struct".fields.len - 1) {
if (i < type_info.@"struct".field_names.len - 1) {
try writer.writeAll(",");
}
if (self.options.pretty_print) {
Expand Down Expand Up @@ -307,10 +307,10 @@ pub const Snapshot = struct {

try writer.writeAll("{\n");

inline for (type_info.@"struct".fields, 0..) |field, i| {
try writer.print(" \"{s}\": ", .{field.name});
inline for (type_info.@"struct".field_names, 0..) |field_name, i| {
try writer.print(" \"{s}\": ", .{field_name});

const field_value = @field(value, field.name);
const field_value = @field(value, field_name);
const FieldType = @TypeOf(field_value);
const field_info = @typeInfo(FieldType);

Expand All @@ -328,7 +328,7 @@ pub const Snapshot = struct {
else => try writer.print("{any}", .{field_value}),
}

if (i < type_info.@"struct".fields.len - 1) {
if (i < type_info.@"struct".field_names.len - 1) {
try writer.writeAll(",\n");
} else {
try writer.writeAll("\n");
Expand Down
Loading