diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..77787b5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,91 @@ +name: Release + +on: + workflow_dispatch: + push: + tags: + +jobs: + upload-binaries: + name: Upload Binaries + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set release version + run: echo "RELEASE_VERSION=$GITHUB_REF_NAME" >> $GITHUB_ENV + + - name: Install Zig + uses: goto-bus-stop/setup-zig@v2 + with: + version: 0.12.0 + + - name: Print Zig meta + run: | + zig version + zig env + + # Build binaries for target queries in `build.zig`, contents + # will be saved in `zig-out` + - name: Build release binaries + run: | + rm -rf zig-out # sanity + zig build release --summary all + + # Rename binary folders with name-version prefix, and copy + # other assets into individual release folders. + - name: Collect assets + shell: bash + run: | + version_prefix="fex-${{ env.RELEASE_VERSION }}-" + for build_path in "zig-out"/*; do + echo "Collecting $build_path" + + # Rename folder + new_folder_name=$version_prefix$(basename $build_path) + new_build_path="zig-out/$new_folder_name" + mv "$build_path" "$new_build_path" + + # Copy assets into release folders + cp {LICENSE,README.md} "$new_build_path" + cp -r shell/. "$new_build_path" + done + + # Create tar.gz of release folders, and calculate their + # checksums. Output is stored in `release`. + - name: Prepare artifacts + shell: bash + run: | + mkdir -p release && cd release + for asset in "../zig-out"/*; do + echo "Preparing $asset" + asset_name=$(basename $asset) + tar_name=${asset_name}.tar.gz + tar -C ../zig-out -czvf $tar_name $asset_name + shasum -a 512 $tar_name > ${tar_name}.sha512 + done + + # Creates a new release and uploads artifacts to it. + - name: Upload for release + uses: svenstaro/upload-release-action@v2 + with: + file: release/* + file_glob: true + overwrite: true + tag: ${{ github.ref }} + release_name: 'Release v${{ env.RELEASE_VERSION }}' + repo_token: ${{ secrets.GITHUB_TOKEN }} + draft: true + + # Upload artifacts to GHA for inspection incase something + # goes wrong. + - name: Upload for inspection + uses: actions/upload-artifact@v4 + with: + name: release-artifact + path: release/ + retention-days: 3 + overwrite: true + if-no-files-found: error diff --git a/build.zig b/build.zig index dabbb07..9030130 100644 --- a/build.zig +++ b/build.zig @@ -1,24 +1,50 @@ const std = @import("std"); +const builtin = @import("builtin"); +const Build = std.Build; const release_queries: []const std.Target.Query = &.{ .{ .cpu_arch = .x86_64, .os_tag = .linux, - .abi = .gnu, }, + // Does NOT compile + // `no field named 'lstat' in enum 'os.linux.syscalls.Arm64'` + // .{ + // .cpu_arch = .aarch64, + // .os_tag = .linux, + // .abi = .gnu, + // }, + // DOES NOT compile on aarch64-macos + // Compiles on x86_64-linux .{ - // FIXME: macos doesn't compile with these - // .cpu_arch = .aarch64, - // .os_tag = .macos, - // .abi = .none, + .cpu_arch = .aarch64, + .os_tag = .macos, + }, + .{ + .cpu_arch = .x86_64, + .os_tag = .macos, }, }; +const is_running_on_macos = builtin.target.os.tag == .macos; -pub fn build(b: *std.Build) !void { +pub fn build(b: *Build) !void { + // zig build | zig build install + const exe = try addInstallCommand(b); + + // zig build run + try addRunCommand(b, exe); + + // zig build release + try addReleaseCommand(b); + + // zig build test + try addTestCommand(b); +} + +fn addInstallCommand(b: *Build) !*Build.Step.Compile { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - // zig build install const exe = b.addExecutable(.{ .name = "fex", .root_source_file = b.path("main.zig"), @@ -27,8 +53,10 @@ pub fn build(b: *std.Build) !void { }); b.installArtifact(exe); exe.linkLibC(); + return exe; +} - // zig build run +fn addRunCommand(b: *Build, exe: *Build.Step.Compile) !void { const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| { @@ -36,37 +64,47 @@ pub fn build(b: *std.Build) !void { } const run_step = b.step("run", "Run the app"); run_step.dependOn(&run_cmd.step); +} - // TODO: Add release step - // zig build test - // const exe_unit_tests = b.addTest(.{ - // .root_source_file = b.path("fs/Manager.zig"), - // .target = target, - // .optimize = optimize, - // }); - // const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); - // const test_step = b.step("test", "Run unit tests"); - // test_step.dependOn(&run_exe_unit_tests.step); - - // zig build release +/// Will build ReleaseSafe binaries for target queries +/// in `release_queries`. +/// +/// Path to build artefacts will be: +/// zig-out/{arch}-{os}/fex +fn addReleaseCommand(b: *Build) !void { const release_step = b.step("release", "Build release binaries"); for (release_queries) |query| { + // macOS cannot build macOS targets. + // Native build (i.e. with empty query) has to be run . + if (is_running_on_macos and query.os_tag == .macos) continue; + + const target = b.resolveTargetQuery(query); const release_exe = b.addExecutable(.{ .name = "fex", .root_source_file = b.path("main.zig"), - .target = b.resolveTargetQuery(query), + .target = target, .optimize = .ReleaseSafe, .single_threaded = true, }); - release_exe.linkLibC(); - const custom_dest_dir = try query.zigTriple(b.allocator); const install_step = b.addInstallArtifact(release_exe, .{ .dest_dir = .{ .override = .{ .custom = custom_dest_dir }, }, }); + release_exe.linkLibC(); release_step.dependOn(&install_step.step); } } + +fn addTestCommand(b: *Build) !void { + _ = b; + // TODO: Add tests, make them work + // const exe_unit_tests = b.addTest(.{ + // .root_source_file = b.path("main.zig"), + // }); + // const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + // const test_step = b.step("test", "Run unit tests"); + // test_step.dependOn(&run_exe_unit_tests.step); +} diff --git a/tui/terminal.zig b/tui/terminal.zig index e7d09cc..c87fb48 100644 --- a/tui/terminal.zig +++ b/tui/terminal.zig @@ -90,8 +90,6 @@ pub fn enableRawMode(bak: *posix.termios) !void { termios.lflag.IEXTEN = false; termios.lflag.ISIG = true; - // termios.iflag &= ~(posix.system.IXON | posix.system.ICRNL); - // termios.lflag &= ~(posix.system.ECHO | posix.system.ICANON | posix.system.IEXTEN) | posix.system.ISIG; try posix.tcsetattr( posix.STDIN_FILENO, posix.TCSA.FLUSH, @@ -106,5 +104,4 @@ pub fn disableRawMode(bak: *posix.termios) !void { posix.TCSA.FLUSH, bak.*, ); - return; }