mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-13 14:29:49 -04:00
This change adds an entry point for oss-fuzz `fuzz/oss-fuzz.sh`, allowing us to wire in our current and future fuzzing into oss-fuzz without needing to update the google/oss-fuzz repo. Existing fuzzing was also reviewed with the following changes: * disco/disco_fuzzer.go renamed to disco/fuzz_test.go so that it can have a _test.go suffix and match the modern go fuzzing design. * net/stun/stun_fuzzer.go renamed to net/stun/fuzz_test.go similar to the above * Disco and stun recieved seeds for their fuzzing starts * All existing fuzzing was given a local round of testing, which resulted in a round trip fix for disco not handling a full zero node key. * Running and building fuzzing was removed from CI (build only). The fuzz seeds are validated in normal go testing, but the fuzzing itself will only happen if run manually or on oss-fuzz. Updates https://github.com/tailscale/corp/issues/46608 Change-Id: I47cb70169aefb02ac5a56220f26a6ec07fa135ee Signed-off-by: Mike Jensen <mikej@tailscale.com>
1034 lines
40 KiB
YAML
1034 lines
40 KiB
YAML
# This is our main "CI tests" workflow. It runs everything that should run on
|
|
# both PRs and merged commits, and for the latter reports failures to slack.
|
|
name: CI
|
|
|
|
env:
|
|
# GOMODCACHE is the same definition on all OSes. Within the workspace, we use
|
|
# toplevel directories "src" (for the checked out source code), and "gomodcache"
|
|
# and other caches as siblings to follow.
|
|
GOMODCACHE: ${{ github.workspace }}/gomodcache
|
|
CMD_GO_USE_GIT_HASH: "true"
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- "main"
|
|
- "release-branch/*"
|
|
pull_request:
|
|
# all PRs on all branches
|
|
merge_group:
|
|
branches:
|
|
- "main"
|
|
|
|
concurrency:
|
|
# For PRs, later CI runs preempt previous ones. e.g. a force push on a PR
|
|
# cancels running CI jobs and starts all new ones.
|
|
#
|
|
# For non-PR pushes, concurrency.group needs to be unique for every distinct
|
|
# CI run we want to have happen. Use run_id, which in practice means all
|
|
# non-PR CI runs will be allowed to run without preempting each other.
|
|
group: ${{ github.workflow }}-$${{ github.pull_request.number || github.run_id }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
gomod-cache:
|
|
runs-on: ubuntu-24.04
|
|
outputs:
|
|
cache-key: ${{ steps.hash.outputs.key }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Compute cache key from go.{mod,sum}
|
|
id: hash
|
|
run: echo "key=gomod-cross3-${{ hashFiles('src/go.mod', 'src/go.sum') }}" >> $GITHUB_OUTPUT
|
|
# See if the cache entry already exists to avoid downloading it
|
|
# and doing the cache write again.
|
|
- id: check-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache # relative to workspace; see env note at top of file
|
|
key: ${{ steps.hash.outputs.key }}
|
|
lookup-only: true
|
|
enableCrossOsArchive: true
|
|
- name: Download modules
|
|
if: steps.check-cache.outputs.cache-hit != 'true'
|
|
working-directory: src
|
|
run: go mod download
|
|
- name: Cache Go modules
|
|
if: steps.check-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # zizmor: ignore[cache-poisoning] v5.0.4
|
|
with:
|
|
path: gomodcache # relative to workspace; see env note at top of file
|
|
key: ${{ steps.hash.outputs.key }}
|
|
enableCrossOsArchive: true
|
|
|
|
race-root-integration:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
- shard: '1/4'
|
|
- shard: '2/4'
|
|
- shard: '3/4'
|
|
- shard: '4/4'
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: build test wrapper
|
|
working-directory: src
|
|
run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper
|
|
- name: integration tests as root
|
|
working-directory: src
|
|
run: PATH=$PWD/tool:$PATH /tmp/testwrapper -exec "sudo -E" -race ./tstest/integration/
|
|
env:
|
|
TS_TEST_SHARD: ${{ matrix.shard }}
|
|
|
|
test:
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
- goarch: amd64
|
|
- goarch: amd64
|
|
buildflags: "-race"
|
|
shard: '1/3'
|
|
- goarch: amd64
|
|
buildflags: "-race"
|
|
shard: '2/3'
|
|
- goarch: amd64
|
|
buildflags: "-race"
|
|
shard: '3/3'
|
|
- goarch: "386" # thanks yaml
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: Restore Cache
|
|
id: restore-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only restoring the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-${{ matrix.shard }}-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
restore-keys: |
|
|
${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-${{ matrix.shard }}-${{ hashFiles('**/go.sum') }}-${{ github.job }}-
|
|
${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-${{ matrix.shard }}-${{ hashFiles('**/go.sum') }}-
|
|
${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-${{ matrix.shard }}-
|
|
${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-
|
|
- name: build all
|
|
if: matrix.buildflags == '' # skip on race builder
|
|
working-directory: src
|
|
run: ./tool/go build ${{matrix.buildflags}} ./...
|
|
env:
|
|
GOARCH: ${{ matrix.goarch }}
|
|
- name: build variant CLIs
|
|
if: matrix.buildflags == '' # skip on race builder
|
|
working-directory: src
|
|
run: |
|
|
./build_dist.sh --extra-small ./cmd/tailscaled
|
|
./build_dist.sh --box ./cmd/tailscaled
|
|
./build_dist.sh --extra-small --box ./cmd/tailscaled
|
|
rm -f tailscaled
|
|
env:
|
|
GOARCH: ${{ matrix.goarch }}
|
|
- name: get qemu # for tstest/archtest
|
|
if: matrix.goarch == 'amd64' && matrix.buildflags == ''
|
|
run: |
|
|
sudo apt-get -y update
|
|
sudo apt-get -y install qemu-user
|
|
- name: build test wrapper
|
|
working-directory: src
|
|
run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper
|
|
- name: test all
|
|
working-directory: src
|
|
run: NOBASHDEBUG=true NOPWSHDEBUG=true PATH=$PWD/tool:$PATH /tmp/testwrapper ./... ${{matrix.buildflags}}
|
|
env:
|
|
GOARCH: ${{ matrix.goarch }}
|
|
TS_TEST_SHARD: ${{ matrix.shard }}
|
|
- name: bench all
|
|
working-directory: src
|
|
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)
|
|
env:
|
|
GOARCH: ${{ matrix.goarch }}
|
|
- name: check that no tracked files changed
|
|
working-directory: src
|
|
run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1)
|
|
- name: check that no new files were added
|
|
working-directory: src
|
|
run: |
|
|
# Note: The "error: pathspec..." you see below is normal!
|
|
# In the success case in which there are no new untracked files,
|
|
# git ls-files complains about the pathspec not matching anything.
|
|
# That's OK. It's not worth the effort to suppress. Please ignore it.
|
|
if git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*'
|
|
then
|
|
echo "Build/test created untracked files in the repo (file names above)."
|
|
exit 1
|
|
fi
|
|
- name: Tidy cache
|
|
working-directory: src
|
|
shell: bash
|
|
run: |
|
|
find $(go env GOCACHE) -type f -mmin +90 -delete
|
|
- name: Save Cache
|
|
# Save cache even on failure, but only on cache miss and main branch to avoid thrashing.
|
|
if: always() && steps.restore-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main'
|
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only saving the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goarch }}-${{ matrix.buildflags }}-go-${{ matrix.shard }}-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
|
|
windows:
|
|
permissions:
|
|
id-token: write # This is required for requesting the GitHub action identity JWT that can auth to cigocached
|
|
contents: read # This is required for actions/checkout
|
|
# ci-windows-github-1 is a 2022 GitHub-managed runner in our org with 8 cores
|
|
# and 32 GB of RAM. It is connected to a private Azure VNet that hosts cigocached.
|
|
# https://github.com/organizations/tailscale/settings/actions/github-hosted-runners/5
|
|
runs-on: ci-windows-github-1
|
|
needs: gomod-cache
|
|
name: Windows (${{ matrix.name || matrix.shard}})
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
- key: "win-bench"
|
|
name: "benchmarks"
|
|
- key: "win-shard-1-2"
|
|
shard: "1/2"
|
|
- key: "win-shard-2-2"
|
|
shard: "2/2"
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: ${{ github.workspace }}/src
|
|
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
|
|
- name: Set up cigocacher
|
|
id: cigocacher-setup
|
|
uses: ./src/.github/actions/go-cache
|
|
with:
|
|
checkout-path: ${{ github.workspace }}/src
|
|
cache-dir: ${{ github.workspace }}/cigocacher
|
|
cigocached-url: ${{ vars.CIGOCACHED_AZURE_URL }}
|
|
cigocached-host: ${{ vars.CIGOCACHED_AZURE_HOST }}
|
|
|
|
- name: test
|
|
shell: bash
|
|
if: matrix.key != 'win-bench' # skip on bench builder
|
|
working-directory: src
|
|
# -count=1: a cached pass is never retried, so flakes can't be reported.
|
|
run: ./tool/go run ./cmd/testwrapper sharded:${{ matrix.shard }} -count=1
|
|
env:
|
|
NOPWSHDEBUG: "true" # to quiet tool/gocross/gocross-wrapper.ps1 in CI
|
|
TS_TESTWRAPPER_RESULTS_SUMMARY: "1"
|
|
TS_TESTWRAPPER_RESULTS_PKG: tailscale.com/tstest/integration
|
|
TS_TESTWRAPPER_RESULTS_JSON: ${{ github.workspace }}/windows-integration-results.json
|
|
|
|
- name: Upload Windows integration results
|
|
if: always() && matrix.key != 'win-bench'
|
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
with:
|
|
name: windows-integration-results-${{ matrix.key }}
|
|
path: ${{ github.workspace }}/windows-integration-results.json
|
|
if-no-files-found: ignore
|
|
|
|
- name: bench all
|
|
shell: bash
|
|
if: matrix.key == 'win-bench'
|
|
working-directory: src
|
|
run: ./tool/go test -bench=. -benchtime=1x -run='^$' $(for x in $(git grep -l '^func Benchmark' | xargs dirname | sort | uniq); do echo "./$x"; done)
|
|
env:
|
|
NOPWSHDEBUG: "true" # to quiet tool/gocross/gocross-wrapper.ps1 in CI
|
|
|
|
- name: Print stats
|
|
shell: pwsh
|
|
if: steps.cigocacher-setup.outputs.success == 'true'
|
|
env:
|
|
GOCACHEPROG: ${{ env.GOCACHEPROG }}
|
|
run: |
|
|
Invoke-Expression "$env:GOCACHEPROG --stats" | jq .
|
|
|
|
macos:
|
|
runs-on: macos-latest
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: Restore Cache
|
|
id: restore-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: ~/Library/Caches/go-build
|
|
key: ${{ runner.os }}-go-test-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
restore-keys: |
|
|
${{ runner.os }}-go-test-${{ hashFiles('**/go.sum') }}-${{ github.job }}-
|
|
${{ runner.os }}-go-test-${{ hashFiles('**/go.sum') }}-
|
|
${{ runner.os }}-go-test-
|
|
- name: build test wrapper
|
|
working-directory: src
|
|
run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper
|
|
- name: test all
|
|
working-directory: src
|
|
run: PATH=$PWD/tool:$PATH /tmp/testwrapper ./...
|
|
- name: check that no tracked files changed
|
|
working-directory: src
|
|
run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1)
|
|
- name: check that no new files were added
|
|
working-directory: src
|
|
run: |
|
|
# Note: The "error: pathspec..." you see below is normal!
|
|
# In the success case in which there are no new untracked files,
|
|
# git ls-files complains about the pathspec not matching anything.
|
|
# That's OK. It's not worth the effort to suppress. Please ignore it.
|
|
if git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*'
|
|
then
|
|
echo "Build/test created untracked files in the repo (file names above)."
|
|
exit 1
|
|
fi
|
|
- name: Tidy cache
|
|
working-directory: src
|
|
run: |
|
|
find $(./tool/go env GOCACHE) -type f -mmin +90 -delete
|
|
- name: Save Cache
|
|
# Save cache even on failure, but only on cache miss and main branch to avoid thrashing.
|
|
if: always() && steps.restore-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main'
|
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: ~/Library/Caches/go-build
|
|
key: ${{ runner.os }}-go-test-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
|
|
privileged:
|
|
needs: gomod-cache
|
|
runs-on: ubuntu-24.04
|
|
container:
|
|
image: golang:latest # zizmor: ignore[unpinned-images]
|
|
options: --privileged
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: chown
|
|
working-directory: src
|
|
run: chown -R $(id -u):$(id -g) $PWD
|
|
- name: privileged tests
|
|
working-directory: src
|
|
run: ./tool/go test $(./tool/go run ./tool/listpkgs --has-root-tests)
|
|
|
|
cross: # cross-compile checks, build only.
|
|
needs: gomod-cache
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
# Note: linux/amd64 is not in this matrix, because that goos/goarch is
|
|
# tested more exhaustively in the 'test' job above.
|
|
- goos: linux
|
|
goarch: arm64
|
|
- goos: linux
|
|
goarch: "386" # thanks yaml
|
|
- goos: linux
|
|
goarch: loong64
|
|
- goos: linux
|
|
goarch: arm
|
|
goarm: "5"
|
|
- goos: linux
|
|
goarch: arm
|
|
goarm: "7"
|
|
# macOS
|
|
- goos: darwin
|
|
goarch: amd64
|
|
- goos: darwin
|
|
goarch: arm64
|
|
# Windows
|
|
- goos: windows
|
|
goarch: amd64
|
|
- goos: windows
|
|
goarch: arm64
|
|
# BSDs
|
|
- goos: freebsd
|
|
goarch: amd64
|
|
- goos: openbsd
|
|
goarch: amd64
|
|
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: Restore Cache
|
|
id: restore-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only restoring the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
restore-keys: |
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}-go-${{ hashFiles('**/go.sum') }}-
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}-go-
|
|
- name: build all
|
|
working-directory: src
|
|
run: ./tool/go build ./cmd/...
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
GOARM: ${{ matrix.goarm }}
|
|
CGO_ENABLED: "0"
|
|
- name: build tests
|
|
working-directory: src
|
|
run: ./tool/go test -exec=true ./...
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
CGO_ENABLED: "0"
|
|
- name: Tidy cache
|
|
working-directory: src
|
|
shell: bash
|
|
run: |
|
|
find $(go env GOCACHE) -type f -mmin +90 -delete
|
|
- name: Save Cache
|
|
# Save cache even on failure, but only on cache miss and main branch to avoid thrashing.
|
|
if: always() && steps.restore-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main'
|
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only saving the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
|
|
ios: # similar to cross above, but iOS can't build most of the repo. So, just
|
|
# make it build a few smoke packages.
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: build some
|
|
working-directory: src
|
|
run: ./tool/go build ./ipn/... ./ssh/tailssh ./wgengine/ ./types/... ./control/controlclient
|
|
env:
|
|
GOOS: ios
|
|
GOARCH: arm64
|
|
|
|
crossmin: # cross-compile for platforms where we only check cmd/tailscale{,d}
|
|
needs: gomod-cache
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
# Plan9
|
|
- goos: plan9
|
|
goarch: amd64
|
|
# AIX
|
|
- goos: aix
|
|
goarch: ppc64
|
|
# Solaris
|
|
- goos: solaris
|
|
goarch: amd64
|
|
# illumos
|
|
- goos: illumos
|
|
goarch: amd64
|
|
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: Restore Cache
|
|
id: restore-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only restoring the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
restore-keys: |
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-${{ hashFiles('**/go.sum') }}-
|
|
${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-
|
|
- name: build core
|
|
working-directory: src
|
|
run: ./tool/go build ./cmd/tailscale ./cmd/tailscaled
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
GOARM: ${{ matrix.goarm }}
|
|
CGO_ENABLED: "0"
|
|
- name: Tidy cache
|
|
working-directory: src
|
|
shell: bash
|
|
run: |
|
|
find $(go env GOCACHE) -type f -mmin +90 -delete
|
|
- name: Save Cache
|
|
# Save cache even on failure, but only on cache miss and main branch to avoid thrashing.
|
|
if: always() && steps.restore-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main'
|
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only saving the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-${{ matrix.goos }}-${{ matrix.goarch }}-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
|
|
android:
|
|
# similar to cross above, but android fails to build a few pieces of the
|
|
# repo. We should fix those pieces, they're small, but as a stepping stone,
|
|
# only test the subset of android that our past smoke test checked.
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
# Super minimal Android build that doesn't even use CGO and doesn't build everything that's needed
|
|
# and is only arm64. But it's a smoke build: it's not meant to catch everything. But it'll catch
|
|
# some Android breakages early.
|
|
# TODO(bradfitz): better; see https://github.com/tailscale/tailscale/issues/4482
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: build some
|
|
working-directory: src
|
|
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 ./ssh/tailssh
|
|
env:
|
|
GOOS: android
|
|
GOARCH: arm64
|
|
|
|
wasm: # builds tsconnect, which is the only wasm build we support
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: Restore Cache
|
|
id: restore-cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only restoring the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-js-wasm-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
restore-keys: |
|
|
${{ runner.os }}-js-wasm-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-
|
|
${{ runner.os }}-js-wasm-go-${{ hashFiles('**/go.sum') }}-
|
|
${{ runner.os }}-js-wasm-go-
|
|
- name: build tsconnect client
|
|
working-directory: src
|
|
run: ./tool/go build ./cmd/tsconnect/wasm ./cmd/tailscale/cli
|
|
env:
|
|
GOOS: js
|
|
GOARCH: wasm
|
|
- name: build tsconnect server
|
|
working-directory: src
|
|
# Note, no GOOS/GOARCH in env on this build step, we're running a build
|
|
# tool that handles the build itself.
|
|
run: |
|
|
./tool/go run ./cmd/tsconnect --fast-compression build
|
|
./tool/go run ./cmd/tsconnect --fast-compression build-pkg
|
|
- name: verify Google Chrome is available
|
|
run: |
|
|
which google-chrome
|
|
google-chrome --version
|
|
- name: tsconnect js/wasm headless-browser tests
|
|
working-directory: src
|
|
run: ./tool/go test ./tstest/integration/jswasmtest/ -v -timeout 180s --run-headless-browser-tests
|
|
- name: Tidy cache
|
|
working-directory: src
|
|
shell: bash
|
|
run: |
|
|
find $(go env GOCACHE) -type f -mmin +90 -delete
|
|
- name: Save Cache
|
|
# Save cache even on failure, but only on cache miss and main branch to avoid thrashing.
|
|
if: always() && steps.restore-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main'
|
|
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
# Note: this is only saving the build cache. Mod cache is shared amongst
|
|
# all jobs in the workflow.
|
|
path: |
|
|
~/.cache/go-build
|
|
~\AppData\Local\go-build
|
|
key: ${{ runner.os }}-js-wasm-go-${{ hashFiles('**/go.sum') }}-${{ github.job }}-${{ github.run_id }}
|
|
|
|
tailscale_go: # Subset of tests that depend on our custom Go toolchain.
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- name: Set GOMODCACHE env
|
|
run: echo "GOMODCACHE=$HOME/.cache/go-mod" >> $GITHUB_ENV
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: test tailscale_go
|
|
run: ./tool/go test -tags=tailscale_go,ts_enable_sockstats ./net/sockstats/...
|
|
|
|
depaware:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Set GOMODCACHE env
|
|
run: echo "GOMODCACHE=$HOME/.cache/go-mod" >> $GITHUB_ENV
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: check depaware
|
|
working-directory: src
|
|
run: make depaware
|
|
|
|
go_generate:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: check that 'go generate' is clean
|
|
working-directory: src
|
|
run: |
|
|
pkgs=$(./tool/go list ./... | grep -Ev 'dnsfallback|k8s-operator|xdp')
|
|
./tool/go generate $pkgs
|
|
git add -N . # ensure untracked files are noticed
|
|
echo
|
|
echo
|
|
git diff --name-only --exit-code || (echo "The files above need updating. Please run 'go generate'."; exit 1)
|
|
- name: check that 'genreadme' is clean
|
|
working-directory: src
|
|
run: |
|
|
./tool/go run ./misc/genreadme
|
|
git add -N . # ensure untracked files are noticed
|
|
echo
|
|
echo
|
|
git diff --name-only --exit-code || (echo "The files above need updating. Please run './tool/go run ./misc/genreadme'."; exit 1)
|
|
|
|
make_tidy:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: check that 'make tidy' is clean
|
|
working-directory: src
|
|
run: |
|
|
make tidy
|
|
echo
|
|
echo
|
|
git diff --name-only --exit-code || (echo "Please run 'make tidy'"; exit 1)
|
|
|
|
licenses:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: check licenses
|
|
working-directory: src
|
|
run: |
|
|
grep -q TestLicenseHeaders *.go || (echo "Expected a test named TestLicenseHeaders"; exit 1)
|
|
./tool/go test -v -run=TestLicenseHeaders
|
|
|
|
staticcheck:
|
|
runs-on: ubuntu-24.04
|
|
needs: gomod-cache
|
|
name: staticcheck (${{ matrix.name }})
|
|
strategy:
|
|
fail-fast: false # don't abort the entire matrix if one element fails
|
|
matrix:
|
|
include:
|
|
- name: "macOS"
|
|
goos: "darwin"
|
|
goarch: "arm64"
|
|
flags: "--with-tags-all=darwin"
|
|
- name: "Windows"
|
|
goos: "windows"
|
|
goarch: "amd64"
|
|
flags: "--with-tags-all=windows"
|
|
- name: "Linux"
|
|
goos: "linux"
|
|
goarch: "amd64"
|
|
flags: "--with-tags-all=linux"
|
|
- name: "Portable (1/4)"
|
|
goos: "linux"
|
|
goarch: "amd64"
|
|
flags: "--without-tags-any=windows,darwin,linux --shard=1/4"
|
|
- name: "Portable (2/4)"
|
|
goos: "linux"
|
|
goarch: "amd64"
|
|
flags: "--without-tags-any=windows,darwin,linux --shard=2/4"
|
|
- name: "Portable (3/4)"
|
|
goos: "linux"
|
|
goarch: "amd64"
|
|
flags: "--without-tags-any=windows,darwin,linux --shard=3/4"
|
|
- name: "Portable (4/4)"
|
|
goos: "linux"
|
|
goarch: "amd64"
|
|
flags: "--without-tags-any=windows,darwin,linux --shard=4/4"
|
|
|
|
steps:
|
|
- name: checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
path: src
|
|
- name: Restore Go module cache
|
|
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
|
with:
|
|
path: gomodcache
|
|
key: ${{ needs.gomod-cache.outputs.cache-key }}
|
|
enableCrossOsArchive: true
|
|
- name: run staticcheck (${{ matrix.name }})
|
|
working-directory: src
|
|
run: |
|
|
export GOROOT=$(./tool/go env GOROOT)
|
|
./tool/go run -exec \
|
|
"env GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }}" \
|
|
honnef.co/go/tools/cmd/staticcheck -- \
|
|
$(./tool/go run ./tool/listpkgs --ignore-3p --goos=${{ matrix.goos }} --goarch=${{ matrix.goarch }} ${{ matrix.flags }} ./...)
|
|
|
|
notify_slack:
|
|
if: always()
|
|
# Any of these jobs failing causes a slack notification.
|
|
needs:
|
|
- android
|
|
- test
|
|
- windows
|
|
- macos
|
|
- cross
|
|
- ios
|
|
- wasm
|
|
- tailscale_go
|
|
- depaware
|
|
- go_generate
|
|
- make_tidy
|
|
- licenses
|
|
- staticcheck
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: notify
|
|
# Only notify slack for merged commits, not PR failures.
|
|
#
|
|
# It may be tempting to move this condition into the job's 'if' block, but
|
|
# don't: Github only collapses the test list into "everything is OK" if
|
|
# all jobs succeeded. A skipped job results in the list staying expanded.
|
|
# By having the job always run, but skipping its only step as needed, we
|
|
# let the CI output collapse nicely in PRs.
|
|
if: failure() && github.event_name == 'push'
|
|
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
|
|
with:
|
|
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
webhook-type: incoming-webhook
|
|
payload: |
|
|
{
|
|
"attachments": [{
|
|
"title": "Failure: ${{ github.workflow }}",
|
|
"title_link": "https://github.com/${{ github.repository }}/commit/${{ github.sha }}/checks",
|
|
"text": "${{ github.repository }}@${{ github.ref_name }}: <https://github.com/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>",
|
|
"fields": [{ "value": ${{ toJson(github.event.head_commit.message) }}, "short": false }],
|
|
"footer": "${{ github.event.head_commit.committer.name }} at ${{ github.event.head_commit.timestamp }}",
|
|
"color": "danger"
|
|
}]
|
|
}
|
|
|
|
notify_windows:
|
|
if: always()
|
|
needs:
|
|
- windows
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: Download Windows integration results
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: windows-integration-results-*
|
|
path: results
|
|
- name: Build Slack payload
|
|
id: payload
|
|
env:
|
|
WINDOWS_RESULT: ${{ needs.windows.result }}
|
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
# head.ref is untrusted on fork PRs; keep it in env and encode via jq --arg, never run: text.
|
|
HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
# Non-bench legs of the windows matrix; a missing artifact means a shard never reported.
|
|
EXPECTED_SHARDS: "2"
|
|
run: |
|
|
# Read each artifact separately so one unreadable file can't discard the others.
|
|
rows='[]'; unreadable=0; reported=0
|
|
while IFS= read -r -d '' f; do
|
|
reported=$((reported + 1))
|
|
[ -s "$f" ] || continue
|
|
case "$(jq -r 'type' "$f" 2>/dev/null)" in
|
|
array) rows=$(printf '%s\n%s' "$rows" "$(jq -c . "$f")" | jq -s 'add') ;;
|
|
null) ;; # shard ran none of the filtered package
|
|
*) unreadable=$((unreadable + 1)) ;;
|
|
esac
|
|
done < <(find results -name windows-integration-results.json -print0 2>/dev/null)
|
|
# Dedupe so a re-shard reporting a test twice can't double every count.
|
|
rows=$(printf '%s' "$rows" | jq '[ .[] | objects ] | unique_by([.Package, .Test])')
|
|
count() { printf '%s' "$rows" | jq "[ (. // [])[] | select(.Outcome == \"$1\") ] | length"; }
|
|
retried=$(count retried)
|
|
passed=$(( $(count pass) + retried ))
|
|
failed=$(count fail)
|
|
skipped=$(count skip)
|
|
executed=$((passed + failed))
|
|
if [ "$executed" -gt 0 ]; then pct=$(( (passed * 100) / executed )); else pct=0; fi
|
|
# Names behind the retried count, capped so one bad run can't flood the message.
|
|
flaky=$(printf '%s' "$rows" | jq -r '
|
|
[ .[] | select(.Outcome == "retried") | (.Package | sub("^tailscale\\.com/"; "")) + "." + .Test ]
|
|
| sort
|
|
| if length > 5 then (.[:5] | join(", ")) + ", and \(length - 5) more" else join(", ") end')
|
|
|
|
case "$WINDOWS_RESULT" in
|
|
success) emoji=":white_check_mark:"; color="good" ;;
|
|
failure) emoji=":x:"; color="danger" ;;
|
|
cancelled) emoji=":no_entry_sign:"; color="warning" ;;
|
|
skipped) emoji=":fast_forward:"; color="warning" ;;
|
|
*) emoji=":question:"; color="warning" ;;
|
|
esac
|
|
|
|
integration="${passed} passed, ${failed} failed, ${skipped} skipped"
|
|
if [ "$executed" -gt 0 ]; then
|
|
integration="${integration} (${pct}%)"
|
|
fi
|
|
# Anything that makes the numbers incomplete or overstated is said out loud.
|
|
caveats=""
|
|
if [ "$unreadable" -gt 0 ]; then
|
|
caveats="${caveats} — ${unreadable} shard artifact(s) unreadable"
|
|
fi
|
|
if [ "$reported" -lt "$EXPECTED_SHARDS" ]; then
|
|
caveats="${caveats} — only ${reported} of ${EXPECTED_SHARDS} shards reported"
|
|
fi
|
|
# Retries get their own line below, so they don't warn the count line.
|
|
if [ "$executed" -eq 0 ]; then
|
|
caveats="${caveats} — no tests executed"
|
|
fi
|
|
if [ "$WINDOWS_RESULT" = "failure" ] && [ "$failed" -eq 0 ]; then
|
|
caveats="${caveats} — results may be partial (build error or timeout)"
|
|
fi
|
|
integration="${integration}${caveats}"
|
|
if [ "$failed" -gt 0 ]; then int_emoji=":x:"
|
|
elif [ -n "$caveats" ]; then int_emoji=":warning:"
|
|
else int_emoji=":white_check_mark:"; fi
|
|
|
|
jq -n --arg emoji "$emoji" --arg status "$WINDOWS_RESULT" --arg int_emoji "$int_emoji" \
|
|
--arg integration "$integration" --arg flaky "$flaky" --arg retried "$retried" \
|
|
--arg branch "$HEAD_REF" --arg title "$PR_TITLE" --arg pr_url "$PR_URL" --arg pr_number "$PR_NUMBER" \
|
|
--arg color "$color" --arg run_url "$RUN_URL" \
|
|
'{attachments: [{
|
|
title: ($emoji + " " + $title + ": " + $status),
|
|
title_link: $run_url,
|
|
text: (
|
|
"<" + $pr_url + "|PR #" + $pr_number + "> · `" + $branch + "`"
|
|
+ "\n\n" + $emoji + " Windows CI: " + $status
|
|
+ "\n" + $int_emoji + " Windows Integration Tests: " + $integration
|
|
+ (if $flaky == "" then "" else "\n ↳ :warning: Flaky Tests (" + $retried + " passed on retry): " + $flaky end)
|
|
+ "\n\n<" + $run_url + "|View run details>"
|
|
),
|
|
color: $color,
|
|
mrkdwn_in: ["text"]
|
|
}]}' > payload.json
|
|
- name: Send Slack notification
|
|
env:
|
|
WEBHOOK: ${{ secrets.WINDOWS_SLACK_WEBHOOK_URL }}
|
|
if: env.WEBHOOK != '' && github.event_name == 'pull_request' && needs.windows.result != 'cancelled'
|
|
continue-on-error: true
|
|
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
|
|
with:
|
|
webhook: ${{ env.WEBHOOK }}
|
|
webhook-type: incoming-webhook
|
|
payload-file-path: payload.json
|
|
|
|
merge_blocker:
|
|
if: always()
|
|
runs-on: ubuntu-24.04
|
|
needs:
|
|
- android
|
|
- test
|
|
- windows
|
|
- macos
|
|
- cross
|
|
- ios
|
|
- wasm
|
|
- tailscale_go
|
|
- depaware
|
|
- go_generate
|
|
- make_tidy
|
|
- licenses
|
|
- staticcheck
|
|
steps:
|
|
- name: Decide if change is okay to merge
|
|
if: github.event_name != 'push'
|
|
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
|
|
with:
|
|
jobs: ${{ toJSON(needs) }}
|
|
|
|
# This waits on all the jobs which must never fail. Branch protection rules
|
|
# enforce these. No flaky tests are allowed in these jobs. (We don't want flaky
|
|
# tests anywhere, really, but a flaky test here prevents merging.)
|
|
check_mergeability_strict:
|
|
if: always()
|
|
runs-on: ubuntu-24.04
|
|
needs:
|
|
- android
|
|
- cross
|
|
- crossmin
|
|
- ios
|
|
- tailscale_go
|
|
- depaware
|
|
- go_generate
|
|
- make_tidy
|
|
- licenses
|
|
- staticcheck
|
|
steps:
|
|
- name: Decide if change is okay to merge
|
|
if: github.event_name != 'push'
|
|
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
|
|
with:
|
|
jobs: ${{ toJSON(needs) }}
|
|
|
|
check_mergeability:
|
|
if: always()
|
|
runs-on: ubuntu-24.04
|
|
needs:
|
|
- check_mergeability_strict
|
|
- test
|
|
- windows
|
|
- macos
|
|
- wasm
|
|
- race-root-integration
|
|
- privileged
|
|
steps:
|
|
- name: Decide if change is okay to merge
|
|
if: github.event_name != 'push'
|
|
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
|
|
with:
|
|
jobs: ${{ toJSON(needs) }}
|