nativeaudio

audio playback for Go
Log | Files | Refs | README | LICENSE

ci.yml (6857B)


      1 name: CI
      2 
      3 on:
      4   push:
      5   pull_request:
      6 
      7 permissions:
      8   contents: read
      9 
     10 jobs:
     11   test:
     12     name: test (${{ matrix.os }})
     13     runs-on: ${{ matrix.os }}
     14     strategy:
     15       fail-fast: false
     16       matrix:
     17         os: [ubuntu-latest, windows-latest, macos-latest]
     18     steps:
     19       - uses: actions/checkout@v4
     20 
     21       - uses: actions/setup-go@v5
     22         with:
     23           go-version-file: go.mod
     24 
     25       # ffmpeg is the decode backend on Linux, so it is required rather than
     26       # optional there. The libav headers are what the linked backend builds
     27       # against; the binary is still needed, both for the no-cgo fallback and
     28       # for the tests that generate fixtures with it. The ALSA headers are for
     29       # the play subpackage, whose audio backend reaches them through
     30       # pkg-config.
     31       - name: Install Linux dependencies
     32         if: runner.os == 'Linux'
     33         run: >-
     34           sudo apt-get update && sudo apt-get install -y
     35           ffmpeg pkg-config libasound2-dev
     36           libavcodec-dev libavformat-dev libavutil-dev libswresample-dev
     37 
     38       - name: Install ffmpeg (macOS)
     39         if: runner.os == 'macOS'
     40         run: brew install ffmpeg
     41 
     42       - name: Install ffmpeg (Windows)
     43         if: runner.os == 'Windows'
     44         run: choco install ffmpeg -y --no-progress
     45 
     46       - name: gofmt
     47         shell: bash
     48         run: |
     49           unformatted=$(gofmt -l .)
     50           if [ -n "$unformatted" ]; then
     51             echo "These files are not gofmt'd:"
     52             echo "$unformatted"
     53             exit 1
     54           fi
     55 
     56       - name: go vet
     57         run: go vet ./...
     58 
     59       - name: Build
     60         run: go build ./...
     61 
     62       # Failures are copied into the job summary, which is readable without
     63       # signing in. Raw logs are not, and a red run nobody can diagnose is
     64       # barely better than no run at all.
     65       #
     66       # The race detector needs a C toolchain, which is not guaranteed on
     67       # the Windows runner, so it is skipped there.
     68       - name: Test
     69         shell: bash
     70         run: |
     71           race=-race
     72           if [ "$RUNNER_OS" = "Windows" ]; then race=""; fi
     73           set -o pipefail
     74           if go test $race -count=1 -timeout 5m ./... 2>&1 | tee test.log; then
     75             exit 0
     76           fi
     77           {
     78             echo "### Test failures on $RUNNER_OS"
     79             echo '```'
     80             grep -E '^(--- |=== RUN|FAIL|panic|\s+--- )|_test\.go:' test.log | head -100
     81             echo '```'
     82           } >> "$GITHUB_STEP_SUMMARY"
     83 
     84           # Also emit them as annotations. Summaries and raw logs both need
     85           # a sign-in to read; annotations do not, and this repository is a
     86           # mirror people land on without credentials.
     87           grep -E '^(--- FAIL|FAIL|panic)|_test\.go:[0-9]+:|running tests:|^[[:space:]]+(Test|Fuzz)[A-Za-z0-9_]* \(' test.log | head -30 | while IFS= read -r line; do
     88             echo "::error::$RUNNER_OS: $line"
     89           done
     90           exit 1
     91 
     92       # ASan gets its own pass because it and the race detector cannot both
     93       # instrument the same build. It is here for the linked ffmpeg
     94       # backend: that C side allocates with av_malloc, which the leak test
     95       # cannot see, since it reads Go's heap profile and so counts only Go
     96       # allocations. Nothing else in the suite would notice it leaking.
     97       - name: Test under AddressSanitizer
     98         if: runner.os == 'Linux'
     99         shell: bash
    100         run: |
    101           set -o pipefail
    102           if go test -asan -count=1 -timeout 5m ./... 2>&1 | tee asan.log; then
    103             exit 0
    104           fi
    105           {
    106             echo "### AddressSanitizer failures"
    107             echo '```'
    108             grep -E '^(--- |FAIL|panic)|_test\.go:|ERROR: (Address|Leak)Sanitizer|SUMMARY:' asan.log | head -100
    109             echo '```'
    110           } >> "$GITHUB_STEP_SUMMARY"
    111 
    112           grep -E '^(--- FAIL|FAIL|panic)|ERROR: (Address|Leak)Sanitizer|SUMMARY:' asan.log | head -30 | while IFS= read -r line; do
    113             echo "::error::asan: $line"
    114           done
    115           exit 1
    116 
    117       # The support matrix in the readme is meant to be measured rather
    118       # than copied from vendor documentation, and this is where the
    119       # measuring happens. Notices are readable without signing in, so
    120       # each platform publishes its own row.
    121       - name: Publish the format support matrix
    122         if: always()
    123         shell: bash
    124         run: |
    125           rows=$(go test ./internal/test -run TestFormatSupport -v 2>&1 |
    126             grep -o 'MATRIX .*' | sed 's/^MATRIX //')
    127           # One annotation, not one per row: only the first ten of each
    128           # kind are kept per step, and the matrix is longer than that.
    129           echo "::notice::$RUNNER_OS format support%0A${rows//$'\n'/%0A}"
    130 
    131   crossbuild:
    132     name: cross-compile
    133     runs-on: ubuntu-latest
    134     steps:
    135       - uses: actions/checkout@v4
    136 
    137       - uses: actions/setup-go@v5
    138         with:
    139           go-version-file: go.mod
    140 
    141       # ALSA is for the play subpackage; the libav headers are for the linked
    142       # ffmpeg backend, which every cgo-enabled Linux target now builds.
    143       - name: Install build dependencies
    144         run: >-
    145           sudo apt-get update && sudo apt-get install -y
    146           pkg-config libasound2-dev
    147           libavcodec-dev libavformat-dev libavutil-dev libswresample-dev
    148 
    149       # The core package is meant to build anywhere, including targets with
    150       # no native decoder and no cgo, where it falls back to ffmpeg. The
    151       # 32-bit Windows target is the only place internal/mf/callback_32.go
    152       # is compiled, which is the whole reason it is listed.
    153       - name: Build the core package for every target
    154         shell: bash
    155         run: |
    156           set -euo pipefail
    157           while read -r goos goarch cgo; do
    158             echo "== GOOS=$goos GOARCH=$goarch CGO_ENABLED=$cgo"
    159             GOOS=$goos GOARCH=$goarch CGO_ENABLED=$cgo go build .
    160           done <<'TARGETS'
    161           linux amd64 1
    162           linux amd64 0
    163           linux arm64 0
    164           windows amd64 1
    165           windows amd64 0
    166           windows 386 0
    167           darwin arm64 0
    168           freebsd amd64 0
    169           TARGETS
    170 
    171       # The play subpackage is bounded by what its audio backend supports:
    172       # oto needs cgo on Linux and has no FreeBSD backend at all. Keeping
    173       # this list separate is the point of the split, so a regression in
    174       # core portability cannot hide behind playback requirements.
    175       - name: Build the whole module where playback is supported
    176         shell: bash
    177         run: |
    178           set -euo pipefail
    179           while read -r goos goarch cgo; do
    180             echo "== GOOS=$goos GOARCH=$goarch CGO_ENABLED=$cgo"
    181             GOOS=$goos GOARCH=$goarch CGO_ENABLED=$cgo go build ./...
    182           done <<'TARGETS'
    183           linux amd64 1
    184           windows amd64 1
    185           windows amd64 0
    186           windows 386 0
    187           darwin arm64 0
    188           TARGETS