From 20c6c18079c9dab46e3446ad1dd08142ec1c4c61 Mon Sep 17 00:00:00 2001 From: geemili Date: Wed, 29 May 2024 22:08:57 -0600 Subject: [PATCH] feat: add version info and upload built artifacts --- .forgejo/workflows/demo.yaml | 8 +++- build.zig | 72 +++++++++++++++++++++++++++++++++++- src/main.zig | 11 ++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/demo.yaml b/.forgejo/workflows/demo.yaml index 98f2f1d..980cd8c 100644 --- a/.forgejo/workflows/demo.yaml +++ b/.forgejo/workflows/demo.yaml @@ -1,6 +1,6 @@ on: [push] jobs: - test: + build-x86_64-linux-gnu: runs-on: docker steps: - name: Setup Zig @@ -9,4 +9,8 @@ jobs: version: 0.12.0 cache: false - uses: actions/checkout@v4 - - run: zig build + - run: zig build install --summary all -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSmall + - uses: actions/upload-artifact@v4 + with: + name: seizer-solitaire + path: zig-out/bin/seizer-solitaire diff --git a/build.zig b/build.zig index e8c793b..d9208f4 100644 --- a/build.zig +++ b/build.zig @@ -1,9 +1,12 @@ const std = @import("std"); +const mem = std.mem; + +const seizer_solitaire_version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 }; // Although this function looks imperative, note that its job is to // declaratively construct a build graph that will be executed by an external // runner. -pub fn build(b: *std.Build) void { +pub fn build(b: *std.Build) !void { // Standard target options allows the person running `zig build` to choose // what target to build for. Here we do not override the defaults, which // means any target is allowed, and the default is native. Other options @@ -66,4 +69,71 @@ pub fn build(b: *std.Build) void { // running the unit tests. const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&run_exe_unit_tests.step); + + // code to add version to binary, stolen from the zig language's build.zig + const exe_options = b.addOptions(); + exe.root_module.addOptions("build_options", exe_options); + + const opt_version_string = b.option([]const u8, "version-string", "Override version string. Default is to find out with git."); + const version_slice = if (opt_version_string) |version| version else v: { + if (!std.process.can_spawn) { + std.debug.print("error: version info cannot be retrieved from git. Zig version must be provided using -Dversion-string\n", .{}); + std.process.exit(1); + } + const version_string = b.fmt("{d}.{d}.{d}", .{ seizer_solitaire_version.major, seizer_solitaire_version.minor, seizer_solitaire_version.patch }); + + var code: u8 = undefined; + const git_describe_untrimmed = b.runAllowFail(&[_][]const u8{ + "git", + "-C", + b.build_root.path orelse ".", + "describe", + "--match", + "*.*.*", + "--tags", + "--abbrev=9", + }, &code, .Ignore) catch { + break :v version_string; + }; + const git_describe = mem.trim(u8, git_describe_untrimmed, " \n\r"); + + switch (mem.count(u8, git_describe, "-")) { + 0 => { + // Tagged release version (e.g. 0.10.0). + if (!mem.eql(u8, git_describe, version_string)) { + std.debug.print("Zig version '{s}' does not match Git tag '{s}'\n", .{ version_string, git_describe }); + std.process.exit(1); + } + break :v version_string; + }, + 2 => { + // Untagged development build (e.g. 0.10.0-dev.2025+ecf0050a9). + var it = mem.splitScalar(u8, git_describe, '-'); + const tagged_ancestor = it.first(); + const commit_height = it.next().?; + const commit_id = it.next().?; + + const ancestor_ver = try std.SemanticVersion.parse(tagged_ancestor); + if (seizer_solitaire_version.order(ancestor_ver) != .gt) { + std.debug.print("version '{}' must be greater than tagged ancestor '{}'\n", .{ seizer_solitaire_version, ancestor_ver }); + std.process.exit(1); + } + + // Check that the commit hash is prefixed with a 'g' (a Git convention). + if (commit_id.len < 1 or commit_id[0] != 'g') { + std.debug.print("Unexpected `git describe` output: {s}\n", .{git_describe}); + break :v version_string; + } + + // The version is reformatted in accordance with the https://semver.org specification. + break :v b.fmt("{s}-dev.{s}+{s}", .{ version_string, commit_height, commit_id[1..] }); + }, + else => { + std.debug.print("Unexpected `git describe` output: {s}\n", .{git_describe}); + break :v version_string; + }, + } + }; + const version = try b.allocator.dupeZ(u8, version_slice); + exe_options.addOption([:0]const u8, "version", version); } diff --git a/src/main.zig b/src/main.zig index 9135371..c9ad5aa 100644 --- a/src/main.zig +++ b/src/main.zig @@ -259,6 +259,16 @@ fn render(window: seizer.Window) !void { @floor((canvas.window_size[1] - space_taken_by_board[1]) / 2), }; + _ = canvas.printText( + .{ + 0, + canvas.window_size[1], + }, + "{s}", + .{build_options.version}, + .{ .@"align" = .left, .baseline = .bottom, .scale = scalef }, + ); + if (win_count) |w| { _ = canvas.printText( .{ @@ -898,6 +908,7 @@ const Snapshot = struct { const DeckSprites = assets.DeckSprites; const Card = assets.Card; +const build_options = @import("build_options"); const assets = @import("./assets.zig"); const builtin = @import("builtin"); const seizer = @import("seizer");