Skip to content

Commit

Permalink
Test cross platform pgroll builds in the CI workflow (#525)
Browse files Browse the repository at this point in the history
Building `pgroll` now requires a functioning C toolchain on each
platform we aim to support, due to taking a dependency on
[pg_query_go](https://github.com/pganalyze/pg_query_go) for the
`sql2pgroll` package:
[pg_query_go](https://github.com/pganalyze/pg_query_go) requires
`CGO_ENABLED` to build.

This PR adds a new `cross-build` job in the CI workflow to build
`pgroll` binaries for each of our supported platforms:

* `linux/amd64`
* `linux/arm64`
* `darwin/amd64`
* `darwin/arm64`
* `windows/amd64`

The job runs in a
[goreleaser/goreleaser-cross](https://github.com/goreleaser/goreleaser-cross)
container in order to have access to a functioning C toolchain for each
of the above platforms. The `builds` section of the`.goreleaser.yaml`
config file is extended with an `overrides` section to configure the C
compiler for each platform build:

```yaml
      - goos: windows
        goarch: amd64
        env:
          - CC=x86_64-w64-mingw32-gcc
          - CGO_LDFLAGS=-lssp -static
      - goos: linux
        goarch: amd64
        env:
          - CC=x86_64-linux-gnu-gcc
      - goos: linux
        goarch: arm64
        env:
          - CC=aarch64-linux-gnu-gcc
      - goos: darwin
        goarch: amd64
        env:
          - CC=o64-clang
      - goos: darwin
        goarch: arm64
        env:
          - CC=oa64-clang
```

The values for the `CC` env var set the C compiler to use for each
OS/Arch target and are taken from the [goreleaser-cross
docs](https://github.com/goreleaser/goreleaser-cross?tab=readme-ov-file#supported-toolchainsplatforms).
The Windows build requires extra linker flags:

```
CGO_LDFLAGS=-lssp -static
```

due to having to link to the libssp stack-protection library and
statically link to avoid the runtime dependency on that library.

The job runs in a `surjection/goreleaser-cross:v1.23-v2.4.8` container,
which is NOT an official
[goreleaser/goreleaser-cross](https://hub.docker.com/r/goreleaser/goreleaser-cross/tags)
image. This image was built with this `Dockerfile`:

```dockerfile
FROM goreleaser/goreleaser-cross:v1.23-v2.4.4

WORKDIR /tmp

RUN wget https://github.com/goreleaser/goreleaser/releases/download/v2.4.8/goreleaser_Linux_x86_64.tar.gz \
  && tar -xvzf goreleaser_Linux_x86_64.tar.gz \
  && mv goreleaser /usr/bin/goreleaser

WORKDIR /
```

ie it installs the latest version Goreleaser `2.4.8` into the most
recent `goreleaser/goreleaser-cross` image. Once a
`goreleaser/goreleaser-cross` image using `goreleaser` `2.4.8` is
released we can switch back to the official images. Version `2.4.8` is
required due to a bug in earlier `goreleaser` versions that prevents the
`overrides` section in the `.goreleaser.yaml` file from working
(goreleaser/goreleaser#5298).

A `.zip` file containing the binaries for each supported platform is
uploaded as an artifact at the end of the job.
  • Loading branch information
andrew-farries authored Dec 11, 2024
1 parent 11b6454 commit ac10ab4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 5 deletions.
23 changes: 23 additions & 0 deletions .github/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# This Dockerfile builds the image in which cross-platform builds are run.
#
# The reason for using a custom image is that the official
# `goreleaser/goreleaser-cross` image at the time of writing used Goreleaser
# v2.4.4, which had a bug breaking the `builds.overrides` section of the
# `.goreleaser.yaml` file (see
# https://github.com/goreleaser/goreleaser/pull/5298). Once a version of
# `goreleaser/goreleaser-cross` is available using Goreleaser >= 2.4.8 we
# should be able to switch back to the official images.
#
# This image was built and pushed to `surjection/goreleaser-cross:v1.23-v2.4.8`
#

FROM goreleaser/goreleaser-cross:v1.23-v2.4.4

WORKDIR /tmp

RUN wget https://github.com/goreleaser/goreleaser/releases/download/v2.4.8/goreleaser_Linux_x86_64.tar.gz \
&& tar -xvzf goreleaser_Linux_x86_64.tar.gz \
&& mv goreleaser /usr/bin/goreleaser

WORKDIR /
35 changes: 32 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@ permissions:
contents: write
packages: write
jobs:
cross-build:
name: cross-platform build
runs-on: ubuntu-24.04
container:
image: surjection/goreleaser-cross:v1.23-v2.4.8
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'

# Mark the checkout as 'safe' despite being owned by `root`
- run: git config --global --add safe.directory $GITHUB_WORKSPACE

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: '~> v2'
args: build --snapshot

- uses: actions/upload-artifact@v4
with:
name: platform-binaries
path: dist/
if-no-files-found: error

test:
name: 'test (pg: ${{ matrix.pgVersion }}, schema: ${{ matrix.testSchema }})'
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -192,7 +221,7 @@ jobs:

release:
runs-on: ubuntu-24.04
needs: [test, lint, examples-schema-validation, examples, license-check, type-generation, dead-code-check, check-ledger]
needs: [test, lint, examples-schema-validation, examples, license-check, type-generation, dead-code-check, check-ledger, cross-build]
if: startsWith(github.ref, 'refs/tags/')
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
Expand All @@ -219,10 +248,10 @@ jobs:
go-version-file: 'go.mod'

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: latest
version: '~> v2'
args: release --clean
env:
# We use two GitHub tokens here:
Expand Down
28 changes: 26 additions & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
version: 2

project_name: pgroll

before:
hooks:
- go mod tidy

builds:
- id: build_noncgo
- id: build_cgo
binary: pgroll
ldflags:
- -X github.com/xataio/pgroll/cmd.Version={{ .Version }}
env:
- CGO_ENABLED=0
- CGO_ENABLED=1
goos:
- linux
- windows
Expand All @@ -21,6 +23,28 @@ builds:
ignore:
- goos: windows
goarch: arm64
overrides:
- goos: windows
goarch: amd64
env:
- CC=x86_64-w64-mingw32-gcc
- CGO_LDFLAGS=-lssp -static
- goos: linux
goarch: amd64
env:
- CC=x86_64-linux-gnu-gcc
- goos: linux
goarch: arm64
env:
- CC=aarch64-linux-gnu-gcc
- goos: darwin
goarch: amd64
env:
- CC=o64-clang
- goos: darwin
goarch: arm64
env:
- CC=oa64-clang

release:
draft: true
Expand Down

0 comments on commit ac10ab4

Please sign in to comment.