ci.yml (6123B)
1 name: CI 2 3 on: 4 push: 5 branches: [main] 6 pull_request: 7 workflow_dispatch: 8 schedule: 9 # Weekly, so new advisories surface without waiting for a commit. 10 - cron: "0 6 * * 1" 11 12 permissions: 13 contents: read 14 15 jobs: 16 library: 17 name: library (${{ matrix.os }}) 18 runs-on: ${{ matrix.os }} 19 strategy: 20 fail-fast: false 21 matrix: 22 os: [ubuntu-latest, macos-latest, windows-latest] 23 steps: 24 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 25 # go-version-file reads the go directive, so CI proves the declared 26 # minimum actually builds rather than whatever is newest. 27 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 28 with: 29 go-version-file: go.mod 30 cache-dependency-path: | 31 go.sum 32 cmd/preview/go.sum 33 cmd/shell-extension/go.sum 34 - run: go build ./... 35 - name: go test 36 # Windows runners default to PowerShell, and this is a shell script. 37 shell: bash 38 run: | 39 status=0 40 go test -count=1 ./... 2>&1 | tee go-test.log || status=$? 41 if [ "$status" -ne 0 ]; then 42 grep -E '\.go:[0-9]+|FAIL' go-test.log | head -40 | 43 while IFS= read -r line; do echo "::error::$line"; done || true 44 fi 45 exit "$status" 46 47 race: 48 name: library under the race detector 49 runs-on: ubuntu-latest 50 steps: 51 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 52 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 53 with: 54 go-version-file: go.mod 55 cache-dependency-path: go.sum 56 # The encoder resizes every icon concurrently. 57 - run: go test -count=1 -race ./... 58 59 fuzz: 60 name: decoder fuzzing 61 runs-on: ubuntu-latest 62 steps: 63 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 64 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 65 with: 66 go-version-file: go.mod 67 cache-dependency-path: go.sum 68 - run: go test -run='^$' -fuzz=FuzzDecode -fuzztime=120s . 69 - name: Keep any crasher for download 70 if: failure() 71 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 72 with: 73 name: fuzz-corpus 74 path: testdata/fuzz 75 76 oracle: 77 name: iconutil oracle 78 # Apple's own tool is the only authority on the format, and it ships with 79 # the macOS runner. The tests are darwin-only, so this is where they run. 80 runs-on: macos-latest 81 steps: 82 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 83 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 84 with: 85 go-version-file: go.mod 86 cache-dependency-path: go.sum 87 # Annotations show on the run itself, so a failure here is legible 88 # without opening the log. 89 - name: iconutil oracle 90 run: | 91 status=0 92 go test -count=1 -v -run 'TestIconutil' . 2>&1 | tee oracle.log || status=$? 93 if [ "$status" -ne 0 ]; then 94 grep -E 'oracle_test\.go|FAIL|iconutil' oracle.log | head -40 | 95 while IFS= read -r line; do echo "::error::$line"; done || true 96 fi 97 exit "$status" 98 99 shell-extension: 100 name: shell extension 101 runs-on: windows-latest 102 defaults: 103 run: 104 working-directory: cmd/shell-extension 105 steps: 106 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 107 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 108 with: 109 go-version-file: cmd/shell-extension/go.mod 110 cache-dependency-path: cmd/shell-extension/go.sum 111 # The DLL is built with -buildmode=c-shared, which needs cgo. 112 - run: gcc --version 113 - run: go vet ./... 114 - run: go test -count=1 ./... 115 # Outside the workspace the module resolves the published library, which 116 # is what `go install` gets; it catches a go.sum that never learned it. 117 - run: go build ./... 118 env: 119 GOWORK: "off" 120 121 preview: 122 name: preview (${{ matrix.os }}) 123 # Gio needs a long list of X11 and Wayland headers on Linux, so the GUI is 124 # only built where its dependencies ship with the runner. 125 runs-on: ${{ matrix.os }} 126 strategy: 127 fail-fast: false 128 matrix: 129 os: [macos-latest, windows-latest] 130 defaults: 131 run: 132 working-directory: cmd/preview 133 steps: 134 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 135 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 136 with: 137 go-version-file: cmd/preview/go.mod 138 cache-dependency-path: cmd/preview/go.sum 139 - run: go build ./... 140 - run: go vet ./... 141 # The render test skips itself where the runner has no GPU to draw on. 142 - run: go test -count=1 ./... 143 - run: go build ./... 144 env: 145 GOWORK: "off" 146 147 checks: 148 name: formatting, vet and vulnerabilities 149 runs-on: ubuntu-latest 150 steps: 151 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 152 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0 153 with: 154 go-version: stable 155 cache-dependency-path: | 156 go.sum 157 cmd/preview/go.sum 158 cmd/shell-extension/go.sum 159 - name: gofmt 160 run: | 161 unformatted="$(gofmt -l .)" 162 if [ -n "$unformatted" ]; then 163 echo "not gofmt clean:" 164 echo "$unformatted" 165 exit 1 166 fi 167 # Only the library, which builds anywhere. The command modules are 168 # vetted in their own jobs: preview needs a desktop toolchain that Linux 169 # runners lack, and the shell extension has no files outside Windows. 170 - run: go vet ./... 171 - name: govulncheck 172 run: | 173 go install golang.org/x/vuln/cmd/govulncheck@v1.8.0 174 govulncheck ./...