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