diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml new file mode 100644 index 00000000..c6478611 --- /dev/null +++ b/.github/workflows/build-binaries.yml @@ -0,0 +1,197 @@ +name: Build Binaries +on: + workflow_dispatch: + workflow_call: +env: + CGO_ENABLED: 1 +jobs: + build-linux-intel: + runs-on: ubuntu-latest + strategy: + matrix: + tag: [linux-amd64, linux-i386] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Pull docker image + run: docker pull ghcr.io/${{ github.actor }}/zk-xcompile:${{ matrix.tag }} + - name: Build + run: | + docker run --rm \ + -v $(pwd):/usr/src/zk \ + -w /usr/src/zk \ + -u root \ + ghcr.io/${{ github.actor }}/zk-xcompile:${{ matrix.tag }} \ + /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-${{ matrix.tag }}.tar.gz + path: zk + + build-linux-arm: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Pull docker image + run: docker pull ghcr.io/${{ github.actor }}/zk-xcompile:linux-arm64 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + - name: Build + run: | + docker run --rm \ + -v $(pwd):/usr/src/zk \ + -w /usr/src/zk \ + --platform=linux/arm64 \ + -u root \ + ghcr.io/${{ github.actor }}/zk-xcompile:linux-arm64 \ + /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-linux-arm64.tar.gz + path: zk + + build-alpine-intel: + runs-on: ubuntu-latest + strategy: + matrix: + tag: [alpine-amd64, alpine-i386] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Pull docker image + run: docker pull ghcr.io/${{ github.actor }}/zk-xcompile:${{ matrix.tag }} + - name: build + run: | + docker run --rm \ + -v $(pwd):/usr/src/zk \ + -w /usr/src/zk \ + -u root \ + ghcr.io/${{ github.actor }}/zk-xcompile:${{ matrix.tag }} \ + /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-extldflags=-static -X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-${{ matrix.tag }}.tar.gz + path: zk + + build-alpine-arm: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Pull dockedr image + run: docker pull ghcr.io/${{ github.actor }}/zk-xcompile:alpine-arm64 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + - name: build + run: | + docker run --rm \ + -v $(pwd):/usr/src/zk \ + -w /usr/src/zk \ + --platform=linux/arm64 \ + -u root \ + ghcr.io/${{ github.actor }}/zk-xcompile:alpine-arm64 \ + /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-extldflags=-static -X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-alpine-arm64.tar.gz + path: zk + + build-mac-intel: + runs-on: macos-13 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version: 1.23 + - name: build + run: /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-macos-x86_64.tar.gz + path: zk + + build-mac-arm: + runs-on: macos-latest + env: + GOARCH: arm64 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version: 1.23 + - name: Build + env: + GOARCH: arm64 + run: /bin/bash -c 'go build -buildvcs=false -tags "fts5" -ldflags "-X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}"' + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-macos_arm64.tar.gz + path: zk + + build-win: + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> $null)" >> $env:GITHUB_OUTPUT + shell: pwsh + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version: 1.23 + - name: Build + run: go build -buildvcs=false -tags "fts5" -ldflags "-X=main.Version=${{ steps.vars.outputs.version }} -X=main.Build=${{ steps.vars.outputs.version }}" + - name: upload artifact + uses: actions/upload-artifact@v4 + with: + name: zk-${{ steps.vars.outputs.version }}-windows_x64_86.tar.gz + path: zk.exe diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f2a1f44..b685dee2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,19 +1,35 @@ name: Release - on: - workflow_dispatch: push: tags: - - 'v*' - + - 'v*.*.*' jobs: - homebrew: - runs-on: macos-latest + build-binaries: + uses: ./.github/workflows/build-binaries.yml + + create-release: + runs-on: ubuntu-latest + needs: [build-binaries] steps: - - name: Checkout repo - uses: actions/checkout@v4 - - name: Update Homebrew formula + - name: Update Homebrew Formula uses: dawidd6/action-homebrew-bump-formula@v4 with: token: ${{secrets.HOMEBREW_GITHUB_TOKEN}} formula: zk + - name: Set vars + id: vars + run: echo "version=$(git describe --tags --match v[0-9]* 2> /dev/null)" >> $GITHUB_OUTPUT + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + files: | + zk-${{ needs.vars.outputs.version }}-linux-amd64.tar.gz + zk-${{ needs.vars.outputs.version }}-linux-i386.tar.gz + zk-${{ needs.vars.outputs.version }}-linux-arm64.tar.gz + zk-${{ needs.vars.outputs.version }}-alpine-amd64.tar.gz + zk-${{ needs.vars.outputs.version }}-alpine-i386.tar.gz + zk-${{ needs.vars.outputs.version }}-macos-x86_64.tar.gz + zk-${{ needs.vars.outputs.version }}-macos_arm64.tar.gz + zk-${{ needs.vars.outputs.version }}-windows_x64_86.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0bd2c406..f646ff89 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -57,6 +57,8 @@ created. - `.github/workflows/build.yml` checks that the project can be built and the tests still pass. +- `.github/workflows/build-binaries.yml` builds zk binaries for all platforms and uplaods + artifacts. - `.github/workflows/codeql.yml` runs static analysis to vet code quality. - `.github/workflows/gh-pages.yml` deploy the documentation files to GitHub Pages. - `.github/workflows/release.yml` submits a new version to Homebrew when a Git version tag @@ -70,20 +72,18 @@ When `zk` is ready to be released, you can update the `CHANGELOG.md` and create a new Git version tag (for example `v0.13.0`). Make sure you follow the [Semantic Versioning](https://semver.org) scheme. -Then, create [a new GitHub release](https://github.com/zk-org/zk/releases) with a copy of -the latest `CHANGELOG.md` entries and the binaries for all supported platforms. +If you create the git tag via the command line, and push it, then the +[release action](.github/workflows/release.yml) will be triggered. This in turn +calls the [build-binaries action](.github/workflows/build-binaries.yml), creates a +release on GitHub and attaches the built binaries. -Binaries can be created automatically using `make dist-linux` and `make dist-macos`. +Alternatively, you can manually create a release via the GitHub interface, also +creating a release tag. Then you would run the [build-binaries +action](.github/workflows/build-binaries.yml) manually, and download and +attach the binaries manually. -Unfortunately, `make dist-macos` must be run manually on both an Apple Silicon and Intel -chips. The Linux builds are created using Docker and -[these custom images](https://github.com/zk-org/zk-xcompile), which are hosted via -[ghcr.io within zk-org](https://github.com/orgs/zk-org/packages/container/package/zk-xcompile). - -This process is convoluted because `zk` requires CGO with `mattn/go-sqlite3`, which -prevents using Go's native cross-compilation. Transitioning to a CGO-free SQLite driver -such as [cznic/sqlite](https://gitlab.com/cznic/sqlite) could simplify the distribution -process significantly. +In both cases the description of the release can be edited after the release is +created (i.e, adding or editing the changelog). ## Documentation diff --git a/Makefile b/Makefile index 5c9d3e4e..9fe5283b 100644 --- a/Makefile +++ b/Makefile @@ -25,41 +25,6 @@ tesh-update: build alpine: $(call alpine,build) -# Produce a release bundle for all platforms. -dist: dist-macos dist-linux - rm -f zk - -# Produce a release bundle for macOS. -dist-macos: - rm -f zk && make && zip -r "zk-${VERSION}-macos-`uname -m`.zip" zk - -# Produce a release bundle for Linux. -dist-linux: dist-linux-amd64 dist-linux-arm64 dist-linux-i386 dist-alpine-amd64 dist-alpine-arm64 dist-alpine-i386 -dist-linux-amd64: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:linux-amd64 /bin/bash -c 'make' \ - && tar -zcvf "zk-${VERSION}-linux-amd64.tar.gz" zk -dist-linux-arm64: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:linux-arm64 /bin/bash -c 'make' \ - && tar -zcvf "zk-${VERSION}-linux-arm64.tar.gz" zk -dist-linux-i386: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:linux-i386 /bin/bash -c 'make' \ - && tar -zcvf "zk-${VERSION}-linux-i386.tar.gz" zk -dist-alpine-amd64: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:alpine-amd64 /bin/bash -c 'make alpine' \ - && tar -zcvf "zk-${VERSION}-alpine-amd64.tar.gz" zk -dist-alpine-arm64: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:alpine-arm64 /bin/bash -c 'make alpine' \ - && tar -zcvf "zk-${VERSION}-alpine-arm64.tar.gz" zk -dist-alpine-i386: - rm -f zk \ - && docker run --rm -v "${PWD}":/usr/src/zk -w /usr/src/zk ghcr.io/zk-org/zk-xcompile:alpine-i386 /bin/bash -c 'make alpine' \ - && tar -zcvf "zk-${VERSION}-alpine-i386.tar.gz" zk - # Clean build and docs products. clean: rm -rf zk*