diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1f6c25f..be55b72 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -16,6 +16,27 @@ jobs: strategy: fail-fast: false matrix: + include: + # Cross-compilation became possible in go1.5 with the removal of C + # code from the compiler. See https://go.dev/doc/go1.5#c. + # + # Cross-compilation isn't supported in gccgo. + - arch: x64 + go: '1.3' + - arch: x64 + go: '1.4' + - arch: x64 + go: gccgo-9 + - arch: x64 + go: gccgo-10 + - arch: x64 + go: gccgo-11 + - arch: x64 + go: gccgo-12 + # NB: gccgo-13 and gccgo-14 are not available in the Ubuntu 22.04. + # + # TODO(https://github.com/actions/runner-images/issues/9848): Add gccgo-13 and gccgo-14 + # when Ubuntu 24.04 is GA on GitHub Actions. arch: - armv6 - armv7 @@ -48,163 +69,7 @@ jobs: go: '1.5' - arch: s390x go: '1.6' - # Race detector binaries crash with: - # - # FATAL: ThreadSanitizer: unsupported VMA range - # - # See https://github.com/golang/go/issues/29948. - arm64_unsupported_vma_range: - - true - # Race detector binaries crash with: - # - # ==17==ERROR: ThreadSanitizer failed to allocate 0x7f0000 (8323072) bytes at address 9000001a0000 (errno: 12) - # - # See https://github.com/golang/go/issues/67881. - s390x_thread_sanitizer_failed_to_allocate: - - true - include: - # Race builds are pretty much busted on Go 1.4 and below on systems - # with newer C compilers. A number of fixes were backported to - # go1.4-bootstrap but not any released version. See - # https://github.com/golang/go/compare/go1.4.3...release-branch.go1.4. - # - # Race builds aren't supported on linux/386. - # - # Cross-compilation became possible in go1.5 with the removal of C - # code from the compiler. See https://go.dev/doc/go1.5#c. - # - # Race builds aren't supported in gccgo. - # - # Cross-compilation isn't supported in gccgo. - - arch: x64 - go: '1.3' - x64_race_broken: true - - arch: x64 - go: '1.4' - x64_race_broken: true - - arch: x64 - go: gccgo-9 - x64_race_broken: true - - arch: x64 - go: gccgo-10 - x64_race_broken: true - - arch: x64 - go: gccgo-11 - x64_race_broken: true - - arch: x64 - go: gccgo-12 - x64_race_broken: true - # NB: gccgo-13 and gccgo-14 are not available in the Ubuntu 22.04. - # - # TODO(https://github.com/actions/runner-images/issues/9848): Add gccgo-13 and gccgo-14 - # when Ubuntu 24.04 is GA on GitHub Actions. - # Go binaries built with Go 1.8 and below are incompatible with QEMU - # user-level emulation. See - # https://github.com/golang/go/commit/2673f9e. - - arch: armv6 - go: '1.5' - qemu_emulation_broken: true - - arch: armv6 - go: '1.6' - qemu_emulation_broken: true - - arch: armv6 - go: '1.7' - qemu_emulation_broken: true - - arch: armv6 - go: '1.8' - qemu_emulation_broken: true - - arch: armv7 - go: '1.5' - qemu_emulation_broken: true - - arch: armv7 - go: '1.6' - qemu_emulation_broken: true - - arch: armv7 - go: '1.7' - qemu_emulation_broken: true - - arch: armv7 - go: '1.8' - qemu_emulation_broken: true - - arch: aarch64 - go: '1.5' - qemu_emulation_broken: true - - arch: aarch64 - go: '1.6' - qemu_emulation_broken: true - - arch: aarch64 - go: '1.7' - qemu_emulation_broken: true - - arch: aarch64 - go: '1.8' - qemu_emulation_broken: true - - arch: s390x - go: '1.7' - qemu_emulation_broken: true - - arch: s390x - go: '1.8' - qemu_emulation_broken: true - # Race detector support on linux/arm64 was added in go1.12. See - # https://go.dev/doc/go1.12. - - arch: aarch64 - go: '1.5' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.6' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.7' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.8' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.9' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.10' - arm64_race_unsupported: true - - arch: aarch64 - go: '1.11' - arm64_race_unsupported: true - # Race detector support on linux/s390x was added in go1.19. See - # https://go.dev/doc/go1.19. - - arch: s390x - go: '1.7' - s390x_race_unsupported: true - - arch: s390x - go: '1.8' - s390x_race_unsupported: true - - arch: s390x - go: '1.9' - s390x_race_unsupported: true - - arch: s390x - go: '1.10' - s390x_race_unsupported: true - - arch: s390x - go: '1.11' - s390x_race_unsupported: true - - arch: s390x - go: '1.12' - s390x_race_unsupported: true - - arch: s390x - go: '1.13' - s390x_race_unsupported: true - - arch: s390x - go: '1.14' - s390x_race_unsupported: true - - arch: s390x - go: '1.15' - s390x_race_unsupported: true - - arch: s390x - go: '1.16' - s390x_race_unsupported: true - - arch: s390x - go: '1.17' - s390x_race_unsupported: true - - arch: s390x - go: '1.18' - s390x_race_unsupported: true steps: - uses: actions/checkout@v4 - name: Set up Go @@ -223,7 +88,8 @@ jobs: echo ${{ matrix.go }} | sed 's/^gcc//' | xargs -I % ln -s /usr/bin/% /usr/local/bin/go go version - - name: 'Set environment' + - name: Configure environment + id: configure_environment shell: bash run: | set -euxo pipefail @@ -254,30 +120,90 @@ jobs: exit 1 ;; esac - - run: go build -v ./... - - name: 'Check that Get is inlined' - if: ${{ !startsWith(matrix.go, 'gccgo-') }} + + version_ge() { + version=$1 + + printf "$version\n%s\n" ${{ matrix.go }} | sort -V | head -n1 | xargs test "$version" = + } + + # Race builds are pretty much busted on Go 1.4 and below on systems with newer C + # compilers. A number of fixes were backported to go1.4-bootstrap but not any released + # version. See https://github.com/golang/go/compare/go1.4.3...release-branch.go1.4. + if ! version_ge 1.5; then + echo "RACE_BUILDS_BROKEN=1" >> "$GITHUB_OUTPUT" + fi + + # Go binaries built with Go 1.8 and below are incompatible with QEMU user-level emulation. + # See https://github.com/golang/go/commit/2673f9e. + if version_ge 1.9; then + echo "QEMU_EMULATION_WORKS=1" >> "$GITHUB_OUTPUT" + fi + + if version_ge 1.12; then + # Better inlining in Go 1.12. See https://go.dev/doc/go1.12#compiler. + echo "BETTER_INLINING_AVAILABLE=1" >> "$GITHUB_OUTPUT" + + # Race detector support on linux/arm64 was added in go1.12. See + # https://go.dev/doc/go1.12. + echo "ARM64_RACE_SUPPORTED=1" >> "$GITHUB_OUTPUT" + fi + + if version_ge 1.19; then + # Race detector support on linux/s390x was added in go1.19. See + # https://go.dev/doc/go1.19. + echo "S390X_RACE_SUPPORTED=1" >> "$GITHUB_OUTPUT" + fi + + # Race detector binaries crash with: + # + # FATAL: ThreadSanitizer: unsupported VMA range + # + # See https://github.com/golang/go/issues/29948. + echo "ARM64_UNSUPPORTED_VMA_RANGE=1" >> "$GITHUB_OUTPUT" + + # Race detector binaries crash with: + # + # ==17==ERROR: ThreadSanitizer failed to allocate 0x7f0000 (8323072) bytes at address 9000001a0000 (errno: 12) + # + # See https://github.com/golang/go/issues/67881. + echo "S390X_THREAD_SANITIZER_FAILED_TO_ALLOCATE=1" >> "$GITHUB_OUTPUT" + - name: Check that Get is inlined + if: | + !startsWith(matrix.go, 'gccgo-') && + steps.configure_environment.outputs.BETTER_INLINING_AVAILABLE shell: bash run: | set -euxo pipefail - if echo -e '${{ matrix.go }}\n1.12' | sort -V | head -n1 | xargs test 1.12 = ; then - go build -gcflags='-m' 2>&1 | grep 'can inline Get$' > /dev/null - fi - - run: go build -race -v ./... - if: ${{ matrix.arch == 'x64' && !matrix.x64_race_broken }} - - run: go test -v ./... - if: ${{ matrix.arch == 'x64' || matrix.arch == '386'}} - - run: go test -race -v ./... - if: ${{ matrix.arch == 'x64' && !matrix.x64_race_broken }} - - run: go test -bench=. -benchmem -v ./... - if: ${{ matrix.arch == 'x64' || matrix.arch == '386'}} - - run: go test -bench=. -benchmem -race -v ./... - if: ${{ matrix.arch == 'x64' && !matrix.x64_race_broken }} - - run: go test -c ./... - if: ${{ matrix.arch != 'x64' && matrix.arch != '386'}} - - name: 'BuildTestRace with ${{ matrix.go }} for ${{ matrix.arch }}' - if: ${{ matrix.arch == 'aarch64' && !matrix.arm64_race_unsupported || matrix.arch == 's390x' && !matrix.s390x_race_unsupported }} + go build -gcflags='-m' 2>&1 | grep 'can inline Get$' > /dev/null + - name: go build & go test -c + shell: bash + run: | + set -euxo pipefail + + go build -v ./... + go test -c -o goid.test ./... + - name: go build & go test -c (race) + # Race builds aren't supported on linux/386. + # + # Race builds aren't supported in gccgo. + if: | + matrix.arch == 'x64' && + !startsWith(matrix.go, 'gccgo-') && + !steps.configure_environment.outputs.RACE_BUILDS_BROKEN + shell: bash + run: | + set -euxo pipefail + + go build -v -race ./... + go test -c -race -o goid.race.test ./... + - name: go build & go test -c (race) + if: | + matrix.arch == 'aarch64' && + steps.configure_environment.outputs.ARM64_RACE_SUPPORTED || + matrix.arch == 's390x' && + steps.configure_environment.outputs.S390X_RACE_SUPPORTED env: CGO_ENABLED: 1 shell: bash @@ -292,12 +218,31 @@ jobs: sudo apt update sudo apt install -y gcc-${{ matrix.arch }}-linux-gnu - CC=${{ matrix.arch }}-linux-gnu-gcc CC_FOR_TARGET=gcc-${{ matrix.arch }}-linux-gnu go test -c -race -o goid.race.test ./... - - name: 'DeleteTestRace with $${{ matrix.go }} for ${{ matrix.arch }}' - if: ${{ matrix.arch == 'aarch64' && !matrix.arm64_race_unsupported && matrix.arm64_unsupported_vma_range || matrix.arch == 's390x' && !matrix.s390x_race_unsupported && matrix.s390x_thread_sanitizer_failed_to_allocate }} - run: rm goid.race.test - - name: 'Test and Bench with ${{ matrix.go }} on ${{ matrix.arch }}' - if: ${{ matrix.arch != '386' && matrix.arch != 'x64' && !matrix.qemu_emulation_broken }} + export CC=${{ matrix.arch }}-linux-gnu-gcc + export CC_FOR_TARGET=gcc-${{ matrix.arch }}-linux-gnu + + go build -v -race ./... + go test -c -race -o goid.race.test ./... + - run: rm goid.race.test + if: | + matrix.arch == 'aarch64' && + steps.configure_environment.outputs.ARM64_RACE_SUPPORTED && + steps.configure_environment.outputs.ARM64_UNSUPPORTED_VMA_RANGE || + matrix.arch == 's390x' && + steps.configure_environment.outputs.S390X_RACE_SUPPORTED && + steps.configure_environment.outputs.S390X_THREAD_SANITIZER_FAILED_TO_ALLOCATE + - name: Run tests + if: ${{ matrix.arch == '386' || matrix.arch == 'x64' }} + shell: bash + run: | + set -euxo pipefail + find . -name '*.test' -type f -executable -print0 | \ + xargs -t -0 -I '{}' sh -c '{} -test.v && {} -test.bench=. -test.benchmem -test.v' + - name: Run tests + if: | + matrix.arch != '386' && + matrix.arch != 'x64' && + steps.configure_environment.outputs.QEMU_EMULATION_WORKS uses: uraimo/run-on-arch-action@v2 with: arch: ${{ matrix.arch }}