From 39b6a3993d6ec50d74c287db3034960c6594c06c Mon Sep 17 00:00:00 2001 From: Rosy-Glorious Miki Date: Tue, 10 Mar 2026 15:18:05 -0400 Subject: [PATCH] ci: expand Github actions CI to include multi-architecture builds Signed-off-by: Rosy-Glorious Miki --- .github/workflows/ci.yml | 53 +++++++++++++++++++++++++++++++++++----- Makefile | 21 +++++++++++----- tests/test.sh | 46 ++++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad2e3d0..f99ec19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,26 +23,30 @@ jobs: run: make test-fedora: - name: Build and test on Fedora latest - runs-on: ubuntu-latest + name: Build and test Fedora on multiple runners + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, ubuntu-24.04-arm] container: image: quay.io/fedora/fedora:latest options: --user root steps: + - name: Check out repository + uses: actions/checkout@v6 - name: Install dependencies run: | dnf update -y dnf install -y golang make tar diffutils bzip2 gzip curl git which - name: Mark repo as safe for git run: git config --global --add safe.directory $GITHUB_WORKSPACE - - name: Check out repository - uses: actions/checkout@v6 - name: Build and test run: make + version-release: runs-on: ubuntu-latest - needs: [test-makefile, test-fedora] - if: github.event_name == 'push' && github.ref == 'main' + needs: [test-makefile, test-fedora, test-macos, test-windows] + if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Github app installation token uses: actions/create-github-app-token@v2 @@ -60,3 +64,40 @@ jobs: uses: cycjimmy/semantic-release-action@v6 env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + + test-macos: + name: Build and test on macOS + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ macos-latest, macos-26-intel ] + steps: + - name: Check out repository + uses: actions/checkout@v6 + - name: Install dependencies + run: | + brew update + brew install golang make diffutils git grep gnu-tar + - name: Build and test + run: make + + + test-windows: + name: Build and test on Windows + runs-on: ${{ matrix.os }} + env: + CGO_ENABLED: 0 + strategy: + matrix: + os: [ windows-latest, windows-11-arm ] + steps: + - name: Check out repository + uses: actions/checkout@v6 + - uses: actions/setup-go@v6 + with: + go-version: "1.25" + - name: Install dependencies + run: | + choco install -y make diffutils gzip bzip2 git + - name: Build and test + run: bash -c "make" diff --git a/Makefile b/Makefile index a62cbb5..0121bb9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ PROJECT := tar-diff -VERSION := $(shell grep -oP 'VERSION\s*=\s*"\K[^"]+' pkg/common/version.go) +VERSION := $(shell awk -F'"' '/var VERSION =/ {print $$2}' pkg/common/version.go) PROJ_TARBALL := $(PROJECT)_$(VERSION).tar.gz +GOCOVERDIR := $(CURDIR)/test/coverage + .PHONY: all build clean fmt install lint test tools dist unit-test integration-test validate .install.golangci-lint @@ -32,7 +34,9 @@ $(PROJ_TARBALL): git archive --prefix=tar-diff_$(VERSION)/ --format=tar.gz HEAD --output $(PROJ_TARBALL) build: - go build $(GOFLAGS) ./... + mkdir -p $(GOCOVERDIR) + go build $(GOFLAGS) -cover -o tar-diff ./cmd/tar-diff + go build $(GOFLAGS) -cover -o tar-patch ./cmd/tar-patch tar-diff: go build $(GOFLAGS) ./cmd/tar-diff @@ -55,12 +59,17 @@ tools: .install.golangci-lint clean: rm -f tar-diff tar-patch rm -rf $(PROJECT)_$(VERSION) $(PROJ_TARBALL) + rm -rf $(GOCOVERDIR) + +integration-test: build + GOCOVERDIR=$(GOCOVERDIR) tests/test.sh + go tool covdata percent -i=$(GOCOVERDIR) -integration-test: tar-diff tar-patch - tests/test.sh unit-test: - go test $(GOFLAGS) -cover ./... + mkdir -p $(GOCOVERDIR) + go test $(GOFLAGS) -coverprofile=$(GOCOVERDIR)/unit.out ./... + go tool cover -func=$(GOCOVERDIR)/unit.out test: unit-test integration-test @@ -69,7 +78,7 @@ fmt: validate: lint @go vet $(GOFLAGS) ./... - @test -z "$$(gofmt -s -l . | tee /dev/stderr)" + @if [ -n "$$WINDIR" ]; then echo "Skipping gofmt check on Windows"; else output=$$(gofmt -s -l .); test -z "$$output" || (echo "$$output"; exit 1); fi lint: GOFLAGS=$(GOFLAGS) $(GOBIN)/golangci-lint run diff --git a/tests/test.sh b/tests/test.sh index 37ab89d..7749ce0 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -2,6 +2,33 @@ set -e +command -v gtar &>/dev/null && { shopt -s expand_aliases; alias tar=gtar; } + + +ln_soft(){ + local target="$1" + local link="$2" + +# Detect Windows + if [[ -n "$WINDIR" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "msys2" ]]; then + touch "${target}" + powershell -Command "New-Item -ItemType SymbolicLink -Path '${link}' -Target '${target}' -Force" + else + ln -s "${target}" "${link}" + fi +} +ln_hard(){ + local source="$1" + local link="$2" + +#Window detection + if [[ -n "$WINDIR" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "msys2" ]]; then + powershell -Command "New-Item -ItemType HardLink -Path '${link}' -Value '${source}' -Force" + else + ln "${source}" "${link}" + fi +} + TEST_DIR=$(mktemp -d /tmp/test-tardiff-XXXXXX) create_orig () { @@ -16,9 +43,14 @@ create_orig () { echo foo > data/dir1/foo.txt echo bar > data/dir1/bar.txt echo movedata > data/dir1/move.txt - ln -s not-exist data/broken - ln -s foo.txt data/dir1/symlink - ln data/dir1/foo.txt data/dir1/hardlink + + # Skip broken symlink on Windows: tar refuses to archive symlinks with non-existent targets + if [[ -z "$WINDIR" ]] && [[ "$OSTYPE" != "msys" ]] && [[ "$OSTYPE" != "msys2" ]]; then + ln_soft not-exist data/broken + fi + ln_soft foo.txt data/dir1/symlink + ln_hard data/dir1/foo.txt data/dir1/hardlink + echo "PART1" > data/sparse dd of=data/sparse if=/dev/null bs=1024k seek=1 count=1 &> /dev/null @@ -33,7 +65,7 @@ modify_orig () { mkdir -p $DIR # Extract old data - tar xf $SRC -C $DIR + tar xf $SRC -C $DIR pushd $DIR &> /dev/null # Modify it @@ -42,15 +74,15 @@ modify_orig () { echo bar >> data/dir1/bar.txt mv data/dir1/bar.txt data/dir1/bar.TXT # Rename we should pick up - ln data/dir1/foo.txt data/dir1/hardlink2 + ln_hard data/dir1/foo.txt data/dir1/hardlink2 popd &> /dev/null } compress_tar () { FILE=$1 - gzip --keep $FILE - bzip2 --keep $FILE + gzip -k $FILE + bzip2 -k $FILE } create_tar () {