test.yml 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. # This is our main "CI tests" workflow. It runs everything that should run on
  2. # both PRs and merged commits, and for the latter reports failures to slack.
  3. name: CI
  4. env:
  5. # Our fuzz job, powered by OSS-Fuzz, fails periodically because we upgrade to
  6. # new Go versions very eagerly. OSS-Fuzz is a little more conservative, and
  7. # ends up being unable to compile our code.
  8. #
  9. # When this happens, we want to disable the fuzz target until OSS-Fuzz catches
  10. # up. However, we also don't want to forget to turn it back on when OSS-Fuzz
  11. # can once again build our code.
  12. #
  13. # This variable toggles the fuzz job between two modes:
  14. # - false: we expect fuzzing to be happy, and should report failure if it's not.
  15. # - true: we expect fuzzing is broken, and should report failure if it start working.
  16. TS_FUZZ_CURRENTLY_BROKEN: false
  17. on:
  18. push:
  19. branches:
  20. - "main"
  21. - "release-branch/*"
  22. pull_request:
  23. # all PRs on all branches
  24. merge_group:
  25. branches:
  26. - "main"
  27. concurrency:
  28. # For PRs, later CI runs preempt previous ones. e.g. a force push on a PR
  29. # cancels running CI jobs and starts all new ones.
  30. #
  31. # For non-PR pushes, concurrency.group needs to be unique for every distinct
  32. # CI run we want to have happen. Use run_id, which in practice means all
  33. # non-PR CI runs will be allowed to run without preempting each other.
  34. group: ${{ github.workflow }}-$${{ github.pull_request.number || github.run_id }}
  35. cancel-in-progress: true
  36. jobs:
  37. race-root-integration:
  38. runs-on: ubuntu-22.04
  39. strategy:
  40. fail-fast: false # don't abort the entire matrix if one element fails
  41. matrix:
  42. include:
  43. - shard: '1/4'
  44. - shard: '2/4'
  45. - shard: '3/4'
  46. - shard: '4/4'
  47. steps:
  48. - name: checkout
  49. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  50. - name: build test wrapper
  51. run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper
  52. - name: integration tests as root
  53. run: PATH=$PWD/tool:$PATH /tmp/testwrapper -exec "sudo -E" -race ./tstest/integration/
  54. env:
  55. TS_TEST_SHARD: ${{ matrix.shard }}
  56. test:
  57. strategy:
  58. fail-fast: false # don't abort the entire matrix if one element fails
  59. matrix:
  60. include:
  61. - goarch: amd64
  62. coverflags: "-coverprofile=/tmp/coverage.out"
  63. - goarch: amd64
  64. buildflags: "-race"
  65. shard: '1/3'
  66. - goarch: amd64
  67. buildflags: "-race"
  68. shard: '2/3'
  69. - goarch: amd64
  70. buildflags: "-race"
  71. shard: '3/3'
  72. - goarch: "386" # thanks yaml
  73. runs-on: ubuntu-22.04
  74. steps:
  75. - name: checkout
  76. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  77. - name: Restore Cache
  78. uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
  79. with:
  80. # Note: unlike the other setups, this is only grabbing the mod download
  81. # cache, rather than the whole mod directory, as the download cache
  82. # contains zips that can be unpacked in parallel faster than they can be
  83. # fetched and extracted by tar
  84. path: |
  85. ~/.cache/go-build
  86. ~/go/pkg/mod/cache
  87. ~\AppData\Local\go-build
  88. # The -2- here should be incremented when the scheme of data to be
  89. # cached changes (e.g. path above changes).
  90. key: ${{ github.job }}-${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-2-${{ hashFiles('**/go.sum') }}-${{ github.run_id }}
  91. restore-keys: |
  92. ${{ github.job }}-${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-2-${{ hashFiles('**/go.sum') }}
  93. ${{ github.job }}-${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-2-
  94. - name: build all
  95. if: matrix.buildflags == '' # skip on race builder
  96. run: ./tool/go build ${{matrix.buildflags}} ./...
  97. env:
  98. GOARCH: ${{ matrix.goarch }}
  99. - name: build variant CLIs
  100. if: matrix.buildflags == '' # skip on race builder
  101. run: |
  102. export TS_USE_TOOLCHAIN=1
  103. ./build_dist.sh --extra-small ./cmd/tailscaled
  104. ./build_dist.sh --box ./cmd/tailscaled
  105. ./build_dist.sh --extra-small --box ./cmd/tailscaled
  106. rm -f tailscaled
  107. env:
  108. GOARCH: ${{ matrix.goarch }}
  109. - name: get qemu # for tstest/archtest
  110. if: matrix.goarch == 'amd64' && matrix.buildflags == ''
  111. run: |
  112. sudo apt-get -y update
  113. sudo apt-get -y install qemu-user
  114. - name: build test wrapper
  115. run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper
  116. - name: test all
  117. run: NOBASHDEBUG=true PATH=$PWD/tool:$PATH /tmp/testwrapper ${{matrix.coverflags}} ./... ${{matrix.buildflags}}
  118. env:
  119. GOARCH: ${{ matrix.goarch }}
  120. TS_TEST_SHARD: ${{ matrix.shard }}
  121. - name: Publish to coveralls.io
  122. if: matrix.coverflags != '' # only publish results if we've tracked coverage
  123. uses: shogo82148/actions-goveralls@v1
  124. with:
  125. path-to-profile: /tmp/coverage.out
  126. - name: bench all
  127. run: ./tool/go test ${{matrix.buildflags}} -bench=. -benchtime=1x -run=^$ $(for x in $(git grep -l "^func Benchmark" | xargs dirname | sort | uniq); do echo "./$x"; done)
  128. env:
  129. GOARCH: ${{ matrix.goarch }}
  130. - name: check that no tracked files changed
  131. run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1)
  132. - name: check that no new files were added
  133. run: |
  134. # Note: The "error: pathspec..." you see below is normal!
  135. # In the success case in which there are no new untracked files,
  136. # git ls-files complains about the pathspec not matching anything.
  137. # That's OK. It's not worth the effort to suppress. Please ignore it.
  138. if git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*'
  139. then
  140. echo "Build/test created untracked files in the repo (file names above)."
  141. exit 1
  142. fi
  143. windows:
  144. runs-on: windows-2022
  145. steps:
  146. - name: checkout
  147. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  148. - name: Install Go
  149. uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
  150. with:
  151. go-version-file: go.mod
  152. cache: false
  153. - name: Restore Cache
  154. uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
  155. with:
  156. # Note: unlike the other setups, this is only grabbing the mod download
  157. # cache, rather than the whole mod directory, as the download cache
  158. # contains zips that can be unpacked in parallel faster than they can be
  159. # fetched and extracted by tar
  160. path: |
  161. ~/.cache/go-build
  162. ~/go/pkg/mod/cache
  163. ~\AppData\Local\go-build
  164. # The -2- here should be incremented when the scheme of data to be
  165. # cached changes (e.g. path above changes).
  166. key: ${{ github.job }}-${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }}-${{ github.run_id }}
  167. restore-keys: |
  168. ${{ github.job }}-${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }}
  169. ${{ github.job }}-${{ runner.os }}-go-2-
  170. - name: test
  171. run: go run ./cmd/testwrapper ./...
  172. - name: bench all
  173. # Don't use -bench=. -benchtime=1x.
  174. # Somewhere in the layers (powershell?)
  175. # the equals signs cause great confusion.
  176. run: go test ./... -bench . -benchtime 1x -run "^$"
  177. privileged:
  178. runs-on: ubuntu-22.04
  179. container:
  180. image: golang:latest
  181. options: --privileged
  182. steps:
  183. - name: checkout
  184. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  185. - name: chown
  186. run: chown -R $(id -u):$(id -g) $PWD
  187. - name: privileged tests
  188. run: ./tool/go test ./util/linuxfw ./derp/xdp
  189. vm:
  190. runs-on: ["self-hosted", "linux", "vm"]
  191. # VM tests run with some privileges, don't let them run on 3p PRs.
  192. if: github.repository == 'tailscale/tailscale'
  193. steps:
  194. - name: checkout
  195. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  196. - name: Run VM tests
  197. run: ./tool/go test ./tstest/integration/vms -v -no-s3 -run-vm-tests -run=TestRunUbuntu2004
  198. env:
  199. HOME: "/var/lib/ghrunner/home"
  200. TMPDIR: "/tmp"
  201. XDG_CACHE_HOME: "/var/lib/ghrunner/cache"
  202. race-build:
  203. runs-on: ubuntu-22.04
  204. steps:
  205. - name: checkout
  206. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  207. - name: build all
  208. run: ./tool/go install -race ./cmd/...
  209. - name: build tests
  210. run: ./tool/go test -race -exec=true ./...
  211. cross: # cross-compile checks, build only.
  212. strategy:
  213. fail-fast: false # don't abort the entire matrix if one element fails
  214. matrix:
  215. include:
  216. # Note: linux/amd64 is not in this matrix, because that goos/goarch is
  217. # tested more exhaustively in the 'test' job above.
  218. - goos: linux
  219. goarch: arm64
  220. - goos: linux
  221. goarch: "386" # thanks yaml
  222. - goos: linux
  223. goarch: loong64
  224. - goos: linux
  225. goarch: arm
  226. goarm: "5"
  227. - goos: linux
  228. goarch: arm
  229. goarm: "7"
  230. # macOS
  231. - goos: darwin
  232. goarch: amd64
  233. - goos: darwin
  234. goarch: arm64
  235. # Windows
  236. - goos: windows
  237. goarch: amd64
  238. - goos: windows
  239. goarch: arm64
  240. # BSDs
  241. - goos: freebsd
  242. goarch: amd64
  243. - goos: openbsd
  244. goarch: amd64
  245. runs-on: ubuntu-22.04
  246. steps:
  247. - name: checkout
  248. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  249. - name: Restore Cache
  250. uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
  251. with:
  252. # Note: unlike the other setups, this is only grabbing the mod download
  253. # cache, rather than the whole mod directory, as the download cache
  254. # contains zips that can be unpacked in parallel faster than they can be
  255. # fetched and extracted by tar
  256. path: |
  257. ~/.cache/go-build
  258. ~/go/pkg/mod/cache
  259. ~\AppData\Local\go-build
  260. # The -2- here should be incremented when the scheme of data to be
  261. # cached changes (e.g. path above changes).
  262. key: ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-${{ hashFiles('**/go.sum') }}-${{ github.run_id }}
  263. restore-keys: |
  264. ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-${{ hashFiles('**/go.sum') }}
  265. ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-
  266. - name: build all
  267. run: ./tool/go build ./cmd/...
  268. env:
  269. GOOS: ${{ matrix.goos }}
  270. GOARCH: ${{ matrix.goarch }}
  271. GOARM: ${{ matrix.goarm }}
  272. CGO_ENABLED: "0"
  273. - name: build tests
  274. run: ./tool/go test -exec=true ./...
  275. env:
  276. GOOS: ${{ matrix.goos }}
  277. GOARCH: ${{ matrix.goarch }}
  278. CGO_ENABLED: "0"
  279. ios: # similar to cross above, but iOS can't build most of the repo. So, just
  280. #make it build a few smoke packages.
  281. runs-on: ubuntu-22.04
  282. steps:
  283. - name: checkout
  284. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  285. - name: build some
  286. run: ./tool/go build ./ipn/... ./wgengine/ ./types/... ./control/controlclient
  287. env:
  288. GOOS: ios
  289. GOARCH: arm64
  290. crossmin: # cross-compile for platforms where we only check cmd/tailscale{,d}
  291. strategy:
  292. fail-fast: false # don't abort the entire matrix if one element fails
  293. matrix:
  294. include:
  295. # Plan9
  296. - goos: plan9
  297. goarch: amd64
  298. # AIX
  299. - goos: aix
  300. goarch: ppc64
  301. # Solaris
  302. - goos: solaris
  303. goarch: amd64
  304. # illumos
  305. - goos: illumos
  306. goarch: amd64
  307. runs-on: ubuntu-22.04
  308. steps:
  309. - name: checkout
  310. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  311. - name: Restore Cache
  312. uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
  313. with:
  314. # Note: unlike the other setups, this is only grabbing the mod download
  315. # cache, rather than the whole mod directory, as the download cache
  316. # contains zips that can be unpacked in parallel faster than they can be
  317. # fetched and extracted by tar
  318. path: |
  319. ~/.cache/go-build
  320. ~/go/pkg/mod/cache
  321. ~\AppData\Local\go-build
  322. # The -2- here should be incremented when the scheme of data to be
  323. # cached changes (e.g. path above changes).
  324. key: ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-${{ hashFiles('**/go.sum') }}-${{ github.run_id }}
  325. restore-keys: |
  326. ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-${{ hashFiles('**/go.sum') }}
  327. ${{ github.job }}-${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-2-
  328. - name: build core
  329. run: ./tool/go build ./cmd/tailscale ./cmd/tailscaled
  330. env:
  331. GOOS: ${{ matrix.goos }}
  332. GOARCH: ${{ matrix.goarch }}
  333. GOARM: ${{ matrix.goarm }}
  334. CGO_ENABLED: "0"
  335. android:
  336. # similar to cross above, but android fails to build a few pieces of the
  337. # repo. We should fix those pieces, they're small, but as a stepping stone,
  338. # only test the subset of android that our past smoke test checked.
  339. runs-on: ubuntu-22.04
  340. steps:
  341. - name: checkout
  342. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  343. # Super minimal Android build that doesn't even use CGO and doesn't build everything that's needed
  344. # and is only arm64. But it's a smoke build: it's not meant to catch everything. But it'll catch
  345. # some Android breakages early.
  346. # TODO(bradfitz): better; see https://github.com/tailscale/tailscale/issues/4482
  347. - name: build some
  348. run: ./tool/go install ./net/netns ./ipn/ipnlocal ./wgengine/magicsock/ ./wgengine/ ./wgengine/router/ ./wgengine/netstack ./util/dnsname/ ./ipn/ ./net/netmon ./wgengine/router/ ./tailcfg/ ./types/logger/ ./net/dns ./hostinfo ./version
  349. env:
  350. GOOS: android
  351. GOARCH: arm64
  352. wasm: # builds tsconnect, which is the only wasm build we support
  353. runs-on: ubuntu-22.04
  354. steps:
  355. - name: checkout
  356. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  357. - name: Restore Cache
  358. uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
  359. with:
  360. # Note: unlike the other setups, this is only grabbing the mod download
  361. # cache, rather than the whole mod directory, as the download cache
  362. # contains zips that can be unpacked in parallel faster than they can be
  363. # fetched and extracted by tar
  364. path: |
  365. ~/.cache/go-build
  366. ~/go/pkg/mod/cache
  367. ~\AppData\Local\go-build
  368. # The -2- here should be incremented when the scheme of data to be
  369. # cached changes (e.g. path above changes).
  370. key: ${{ github.job }}-${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }}-${{ github.run_id }}
  371. restore-keys: |
  372. ${{ github.job }}-${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }}
  373. ${{ github.job }}-${{ runner.os }}-go-2-
  374. - name: build tsconnect client
  375. run: ./tool/go build ./cmd/tsconnect/wasm ./cmd/tailscale/cli
  376. env:
  377. GOOS: js
  378. GOARCH: wasm
  379. - name: build tsconnect server
  380. # Note, no GOOS/GOARCH in env on this build step, we're running a build
  381. # tool that handles the build itself.
  382. run: |
  383. ./tool/go run ./cmd/tsconnect --fast-compression build
  384. ./tool/go run ./cmd/tsconnect --fast-compression build-pkg
  385. tailscale_go: # Subset of tests that depend on our custom Go toolchain.
  386. runs-on: ubuntu-22.04
  387. steps:
  388. - name: checkout
  389. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  390. - name: test tailscale_go
  391. run: ./tool/go test -tags=tailscale_go,ts_enable_sockstats ./net/sockstats/...
  392. fuzz:
  393. # This target periodically breaks (see TS_FUZZ_CURRENTLY_BROKEN at the top
  394. # of the file), so it's more complex than usual: the 'build fuzzers' step
  395. # might fail, and depending on the value of 'TS_FUZZ_CURRENTLY_BROKEN', that
  396. # might or might not be fine. The steps after the build figure out whether
  397. # the success/failure is expected, and appropriately pass/fail the job
  398. # overall accordingly.
  399. #
  400. # Practically, this means that all steps after 'build fuzzers' must have an
  401. # explicit 'if' condition, because the default condition for steps is
  402. # 'success()', meaning "only run this if no previous steps failed".
  403. if: github.event_name == 'pull_request'
  404. runs-on: ubuntu-22.04
  405. steps:
  406. - name: build fuzzers
  407. id: build
  408. uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
  409. # continue-on-error makes steps.build.conclusion be 'success' even if
  410. # steps.build.outcome is 'failure'. This means this step does not
  411. # contribute to the job's overall pass/fail evaluation.
  412. continue-on-error: true
  413. with:
  414. oss-fuzz-project-name: 'tailscale'
  415. dry-run: false
  416. language: go
  417. - name: report unexpectedly broken fuzz build
  418. if: steps.build.outcome == 'failure' && env.TS_FUZZ_CURRENTLY_BROKEN != 'true'
  419. run: |
  420. echo "fuzzer build failed, see above for why"
  421. echo "if the failure is due to OSS-Fuzz not being on the latest Go yet,"
  422. echo "set TS_FUZZ_CURRENTLY_BROKEN=true in .github/workflows/test.yml"
  423. echo "to temporarily disable fuzzing until OSS-Fuzz works again."
  424. exit 1
  425. - name: report unexpectedly working fuzz build
  426. if: steps.build.outcome == 'success' && env.TS_FUZZ_CURRENTLY_BROKEN == 'true'
  427. run: |
  428. echo "fuzzer build succeeded, but we expect it to be broken"
  429. echo "please set TS_FUZZ_CURRENTLY_BROKEN=false in .github/workflows/test.yml"
  430. echo "to reenable fuzz testing"
  431. exit 1
  432. - name: run fuzzers
  433. id: run
  434. # Run the fuzzers whenever they're able to build, even if we're going to
  435. # report a failure because TS_FUZZ_CURRENTLY_BROKEN is set to the wrong
  436. # value.
  437. if: steps.build.outcome == 'success'
  438. uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
  439. with:
  440. oss-fuzz-project-name: 'tailscale'
  441. fuzz-seconds: 300
  442. dry-run: false
  443. language: go
  444. - name: Set artifacts_path in env (workaround for actions/upload-artifact#176)
  445. if: steps.run.outcome != 'success' && steps.build.outcome == 'success'
  446. run: |
  447. echo "artifacts_path=$(realpath .)" >> $GITHUB_ENV
  448. - name: upload crash
  449. uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
  450. if: steps.run.outcome != 'success' && steps.build.outcome == 'success'
  451. with:
  452. name: artifacts
  453. path: ${{ env.artifacts_path }}/out/artifacts
  454. depaware:
  455. runs-on: ubuntu-22.04
  456. steps:
  457. - name: checkout
  458. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  459. - name: check depaware
  460. run: |
  461. export PATH=$(./tool/go env GOROOT)/bin:$PATH
  462. find . -name 'depaware.txt' | xargs -n1 dirname | xargs ./tool/go run github.com/tailscale/depaware --check --internal
  463. go_generate:
  464. runs-on: ubuntu-22.04
  465. steps:
  466. - name: checkout
  467. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  468. - name: check that 'go generate' is clean
  469. run: |
  470. pkgs=$(./tool/go list ./... | grep -Ev 'dnsfallback|k8s-operator|xdp')
  471. ./tool/go generate $pkgs
  472. echo
  473. echo
  474. git diff --name-only --exit-code || (echo "The files above need updating. Please run 'go generate'."; exit 1)
  475. go_mod_tidy:
  476. runs-on: ubuntu-22.04
  477. steps:
  478. - name: checkout
  479. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  480. - name: check that 'go mod tidy' is clean
  481. run: |
  482. ./tool/go mod tidy
  483. echo
  484. echo
  485. git diff --name-only --exit-code || (echo "Please run 'go mod tidy'."; exit 1)
  486. licenses:
  487. runs-on: ubuntu-22.04
  488. steps:
  489. - name: checkout
  490. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  491. - name: check licenses
  492. run: ./scripts/check_license_headers.sh .
  493. staticcheck:
  494. runs-on: ubuntu-22.04
  495. strategy:
  496. fail-fast: false # don't abort the entire matrix if one element fails
  497. matrix:
  498. goos: ["linux", "windows", "darwin"]
  499. goarch: ["amd64"]
  500. include:
  501. - goos: "windows"
  502. goarch: "386"
  503. steps:
  504. - name: checkout
  505. uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
  506. - name: install staticcheck
  507. run: GOBIN=~/.local/bin ./tool/go install honnef.co/go/tools/cmd/staticcheck
  508. - name: run staticcheck
  509. run: |
  510. export GOROOT=$(./tool/go env GOROOT)
  511. export PATH=$GOROOT/bin:$PATH
  512. staticcheck -- $(./tool/go list ./... | grep -v tempfork)
  513. env:
  514. GOOS: ${{ matrix.goos }}
  515. GOARCH: ${{ matrix.goarch }}
  516. notify_slack:
  517. if: always()
  518. # Any of these jobs failing causes a slack notification.
  519. needs:
  520. - android
  521. - test
  522. - windows
  523. - vm
  524. - cross
  525. - ios
  526. - wasm
  527. - tailscale_go
  528. - fuzz
  529. - depaware
  530. - go_generate
  531. - go_mod_tidy
  532. - licenses
  533. - staticcheck
  534. runs-on: ubuntu-22.04
  535. steps:
  536. - name: notify
  537. # Only notify slack for merged commits, not PR failures.
  538. #
  539. # It may be tempting to move this condition into the job's 'if' block, but
  540. # don't: Github only collapses the test list into "everything is OK" if
  541. # all jobs succeeded. A skipped job results in the list staying expanded.
  542. # By having the job always run, but skipping its only step as needed, we
  543. # let the CI output collapse nicely in PRs.
  544. if: failure() && github.event_name == 'push'
  545. uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0
  546. with:
  547. webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
  548. webhook-type: incoming-webhook
  549. payload: |
  550. {
  551. "attachments": [{
  552. "title": "Failure: ${{ github.workflow }}",
  553. "title_link": "https://github.com/${{ github.repository }}/commit/${{ github.sha }}/checks",
  554. "text": "${{ github.repository }}@${{ github.ref_name }}: <https://github.com/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>",
  555. "fields": [{ "value": ${{ toJson(github.event.head_commit.message) }}, "short": false }],
  556. "footer": "${{ github.event.head_commit.committer.name }} at ${{ github.event.head_commit.timestamp }}",
  557. "color": "danger"
  558. }]
  559. }
  560. check_mergeability:
  561. if: always()
  562. runs-on: ubuntu-22.04
  563. needs:
  564. - android
  565. - test
  566. - windows
  567. - vm
  568. - cross
  569. - ios
  570. - wasm
  571. - tailscale_go
  572. - fuzz
  573. - depaware
  574. - go_generate
  575. - go_mod_tidy
  576. - licenses
  577. - staticcheck
  578. steps:
  579. - name: Decide if change is okay to merge
  580. if: github.event_name != 'push'
  581. uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
  582. with:
  583. jobs: ${{ toJSON(needs) }}