From 4022796484db7f44f0a8598ed9a5d880d1a5b6ae Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 11 Feb 2023 12:16:15 -0800 Subject: [PATCH] .github/workflows: unify and matrixify all our CI steps Instead of having a dozen files that contribute CI steps with inconsistent configs, this one file lists out everything that, for us, constitutes "a CI run". It also enables the slack notification webhook to notify us exactly once on a mass breakage, rather than once for every sub-job that fails. Signed-off-by: David Anderson --- .github/workflows/cifuzz.yml | 31 --- .github/workflows/cross-android.yml | 53 ----- .github/workflows/cross-darwin.yml | 61 ----- .github/workflows/cross-freebsd.yml | 55 ----- .github/workflows/cross-loong64.yml | 55 ----- .github/workflows/cross-openbsd.yml | 55 ----- .github/workflows/cross-wasm.yml | 56 ----- .github/workflows/cross-windows.yml | 55 ----- .github/workflows/depaware.yml | 33 --- .github/workflows/go_generate.yml | 42 ---- .github/workflows/go_mod_tidy.yml | 35 --- .github/workflows/license.yml | 45 ---- .github/workflows/linux-race.yml | 68 ------ .github/workflows/linux.yml | 78 ------- .github/workflows/linux32.yml | 65 ------ .github/workflows/static-analysis.yml | 119 ---------- .github/workflows/test.yml | 325 ++++++++++++++++++++++++++ .github/workflows/vm.yml | 52 ----- .github/workflows/windows.yml | 65 ------ 19 files changed, 325 insertions(+), 1023 deletions(-) delete mode 100644 .github/workflows/cifuzz.yml delete mode 100644 .github/workflows/cross-android.yml delete mode 100644 .github/workflows/cross-darwin.yml delete mode 100644 .github/workflows/cross-freebsd.yml delete mode 100644 .github/workflows/cross-loong64.yml delete mode 100644 .github/workflows/cross-openbsd.yml delete mode 100644 .github/workflows/cross-wasm.yml delete mode 100644 .github/workflows/cross-windows.yml delete mode 100644 .github/workflows/depaware.yml delete mode 100644 .github/workflows/go_generate.yml delete mode 100644 .github/workflows/go_mod_tidy.yml delete mode 100644 .github/workflows/license.yml delete mode 100644 .github/workflows/linux-race.yml delete mode 100644 .github/workflows/linux.yml delete mode 100644 .github/workflows/linux32.yml delete mode 100644 .github/workflows/static-analysis.yml create mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/vm.yml delete mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml deleted file mode 100644 index a75be317a..000000000 --- a/.github/workflows/cifuzz.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: CIFuzz -on: [pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - Fuzzing: - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'tailscale' - dry-run: false - language: go - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'tailscale' - fuzz-seconds: 300 - dry-run: false - language: go - - name: Upload Crash - uses: actions/upload-artifact@v3 - if: failure() && steps.build.outcome == 'success' - with: - name: artifacts - path: ./out/artifacts diff --git a/.github/workflows/cross-android.yml b/.github/workflows/cross-android.yml deleted file mode 100644 index 3f8b2c20f..000000000 --- a/.github/workflows/cross-android.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Android-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Android smoke build - # 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 - env: - GOOS: android - GOARCH: arm64 - run: go install ./net/netns ./ipn/ipnlocal ./wgengine/magicsock/ ./wgengine/ ./wgengine/router/ ./wgengine/netstack ./util/dnsname/ ./ipn/ ./net/interfaces ./wgengine/router/ ./tailcfg/ ./types/logger/ ./net/dns ./hostinfo ./version - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-darwin.yml b/.github/workflows/cross-darwin.yml deleted file mode 100644 index cb224479d..000000000 --- a/.github/workflows/cross-darwin.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Darwin-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: macOS build cmd - env: - GOOS: darwin - GOARCH: amd64 - run: go build ./cmd/... - - - name: macOS build tests - env: - GOOS: darwin - GOARCH: amd64 - run: for d in $(go list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do (echo $d; cd $d && go test -c ); done - - - name: iOS build most - env: - GOOS: ios - GOARCH: arm64 - run: go install ./ipn/... ./wgengine/ ./types/... ./control/controlclient - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-freebsd.yml b/.github/workflows/cross-freebsd.yml deleted file mode 100644 index bac7641e0..000000000 --- a/.github/workflows/cross-freebsd.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: FreeBSD-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: FreeBSD build cmd - env: - GOOS: freebsd - GOARCH: amd64 - run: go build ./cmd/... - - - name: FreeBSD build tests - env: - GOOS: freebsd - GOARCH: amd64 - run: for d in $(go list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do (echo $d; cd $d && go test -c ); done - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-loong64.yml b/.github/workflows/cross-loong64.yml deleted file mode 100644 index 09f94cddb..000000000 --- a/.github/workflows/cross-loong64.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Loongnix-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Loongnix build cmd - env: - GOOS: linux - GOARCH: loong64 - run: go build ./cmd/... - - - name: Loongnix build tests - env: - GOOS: linux - GOARCH: loong64 - run: for d in $(go list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do (echo $d; cd $d && go test -c ); done - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-openbsd.yml b/.github/workflows/cross-openbsd.yml deleted file mode 100644 index ecc866781..000000000 --- a/.github/workflows/cross-openbsd.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: OpenBSD-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: OpenBSD build cmd - env: - GOOS: openbsd - GOARCH: amd64 - run: go build ./cmd/... - - - name: OpenBSD build tests - env: - GOOS: openbsd - GOARCH: amd64 - run: for d in $(go list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do (echo $d; cd $d && go test -c ); done - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-wasm.yml b/.github/workflows/cross-wasm.yml deleted file mode 100644 index 4f067cfd7..000000000 --- a/.github/workflows/cross-wasm.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Wasm-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Wasm client build - env: - GOOS: js - GOARCH: wasm - run: go build ./cmd/tsconnect/wasm ./cmd/tailscale/cli - - - name: tsconnect static build - # Use our custom Go toolchain, we set build tags (to control binary size) - # that depend on it. - run: | - ./tool/go run ./cmd/tsconnect --fast-compression build - ./tool/go run ./cmd/tsconnect --fast-compression build-pkg - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/cross-windows.yml b/.github/workflows/cross-windows.yml deleted file mode 100644 index 28d2d53ee..000000000 --- a/.github/workflows/cross-windows.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Windows-Cross - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Windows build cmd - env: - GOOS: windows - GOARCH: amd64 - run: go build ./cmd/... - - - name: Windows build tests - env: - GOOS: windows - GOARCH: amd64 - run: for d in $(go list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do (echo $d; cd $d && go test -c ); done - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/depaware.yml b/.github/workflows/depaware.yml deleted file mode 100644 index 1610a4a64..000000000 --- a/.github/workflows/depaware.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: depaware - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: depaware - run: go run github.com/tailscale/depaware --check - tailscale.com/cmd/tailscaled - tailscale.com/cmd/tailscale - tailscale.com/cmd/derper diff --git a/.github/workflows/go_generate.yml b/.github/workflows/go_generate.yml deleted file mode 100644 index 6f82af963..000000000 --- a/.github/workflows/go_generate.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: go generate - -on: - push: - branches: - - main - - "release-branch/*" - pull_request: - branches: - - "*" - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: check 'go generate' is clean - run: | - if [[ "${{github.ref}}" == release-branch/* ]] - then - pkgs=$(go list ./... | grep -v dnsfallback) - else - pkgs=$(go list ./... | grep -v dnsfallback) - fi - go generate $pkgs - echo - echo - git diff --name-only --exit-code || (echo "The files above need updating. Please run 'go generate'."; exit 1) diff --git a/.github/workflows/go_mod_tidy.yml b/.github/workflows/go_mod_tidy.yml deleted file mode 100644 index cdf6283ce..000000000 --- a/.github/workflows/go_mod_tidy.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: go mod tidy - -on: - push: - branches: - - main - pull_request: - branches: - - "*" - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: check 'go mod tidy' is clean - run: | - ./tool/go mod tidy - echo - echo - git diff --name-only --exit-code || (echo "Please run 'go mod tidy'."; exit 1) diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml deleted file mode 100644 index ce242df08..000000000 --- a/.github/workflows/license.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: license - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: Run license checker - run: ./scripts/check_license_headers.sh . - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/linux-race.yml b/.github/workflows/linux-race.yml deleted file mode 100644 index d5e7fec27..000000000 --- a/.github/workflows/linux-race.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Linux race - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Build test wrapper - run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper - - - name: Basic build - run: go build ./cmd/... - - - name: Run tests and benchmarks with -race flag on linux - run: go test -exec=/tmp/testwrapper -race -bench=. -benchtime=1x ./... - - - name: Check that no tracked files in the repo have been modified - run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1) - - - name: Check that no files have been added to the repo - 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 - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' - diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 7d2513275..000000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Linux - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-22.04 - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Basic build - run: go build ./cmd/... - - - name: Build test wrapper - run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper - - - name: Build variants - run: | - go install --tags=ts_include_cli ./cmd/tailscaled - go install --tags=ts_omit_aws ./cmd/tailscaled - - - name: Get QEMU - run: | - sudo apt-get -y update - sudo apt-get -y install qemu-user - - - name: Run tests on linux - run: go test -exec=/tmp/testwrapper -bench=. -benchtime=1x ./... - - - name: Check that no tracked files in the repo have been modified - run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1) - - - name: Check that no files have been added to the repo - 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 - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' - diff --git a/.github/workflows/linux32.yml b/.github/workflows/linux32.yml deleted file mode 100644 index 64ab6258a..000000000 --- a/.github/workflows/linux32.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Linux 32-bit - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - id: go - - - name: Basic build - run: GOARCH=386 go build ./cmd/... - - - name: Run tests on linux - run: GOARCH=386 go test -bench=. -benchtime=1x ./... - - - name: Check that no tracked files in the repo have been modified - run: git diff --no-ext-diff --name-only --exit-code || (echo "Build/test modified the files above."; exit 1) - - - name: Check that no files have been added to the repo - 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 - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' - diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml deleted file mode 100644 index c782715c4..000000000 --- a/.github/workflows/static-analysis.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: static-analysis - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - gofmt: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v3 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - name: Run gofmt (goimports) - run: | - OUT=$(go run golang.org/x/tools/cmd/goimports -d --format-only .) - [ -z "$OUT" ] || (echo "Not gofmt'ed: $OUT" && exit 1) - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' - - vet: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: Run go vet - run: go vet ./... - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' - - staticcheck: - runs-on: ubuntu-latest - strategy: - matrix: - goos: [linux, windows, darwin] - goarch: [amd64] - include: - - goos: windows - goarch: 386 - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - - name: Install staticcheck - run: "GOBIN=~/.local/bin go install honnef.co/go/tools/cmd/staticcheck" - - - name: Print staticcheck version - run: "staticcheck -version" - - - name: "Run staticcheck (${{ matrix.goos }}/${{ matrix.goarch }})" - env: - GOOS: ${{ matrix.goos }} - GOARCH: ${{ matrix.goarch }} - run: "staticcheck -- $(go list ./... | grep -v tempfork)" - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..ee7672304 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,325 @@ +# 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 + +on: + push: + branches: + - "main" + - "release-branch/*" + pull_request: + branches: + - "*" + +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: + test: + strategy: + fail-fast: false # don't abort the entire matrix if one element fails + matrix: + include: + - goarch: amd64 + - goarch: amd64 + race: true + - goarch: "386" # thanks yaml + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: build all + run: ./tool/go build ./... + env: + GOARCH: ${{ matrix.goarch }} + - name: build variant CLIs + 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.race + run: | + sudo apt-get -y update + sudo apt-get -y install qemu-user + - name: build test wrapper + run: ./tool/go build -o /tmp/testwrapper ./cmd/testwrapper + - name: test all + if: "!matrix.race" # thanks yaml, unquoted !foo has a magical meaning + run: ./tool/go test -exec=/tmp/testwrapper -bench=. -benchtime=1x ./... + env: + GOARCH: ${{ matrix.goarch }} + - name: test all (race) + if: matrix.race + run: ./tool/go test -race -exec=/tmp/testwrapper -bench=. -benchtime=1x ./... + env: + GOARCH: ${{ matrix.goarch }} + - name: check that no tracked files changed + 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 + 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 + + windows: + runs-on: windows-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: Restore Cache + uses: actions/cache@v3 + with: + # Note: unlike the other setups, this is only grabbing the mod download + # cache, rather than the whole mod directory, as the download cache + # contains zips that can be unpacked in parallel faster than they can be + # fetched and extracted by tar + path: | + ~/go/pkg/mod/cache + ~\AppData\Local\go-build + # The -2- here should be incremented when the scheme of data to be + # cached changes (e.g. path above changes). + # TODO(raggi): add a go version here. + key: ${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }} + - name: test + # Don't use -bench=. -benchtime=1x. + # Somewhere in the layers (powershell?) + # the equals signs cause great confusion. + run: ./tool/go test -bench . -benchtime 1x ./... + + vm: + runs-on: ["self-hosted", "linux", "vm"] + # VM tests run with some privileges, don't let them run on 3p PRs. + if: github.repository == 'tailscale/tailscale' + steps: + - name: checkout + uses: actions/checkout@v3 + - name: Run VM tests + run: ./tool/go test ./tstest/integration/vms -v -no-s3 -run-vm-tests -run=TestRunUbuntu2004 + env: + HOME: "/tmp" + TMPDIR: "/tmp" + XDB_CACHE_HOME: "/var/lib/ghrunner/cache" + + cross: # cross-compile checks, build only. + 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 + # 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-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: build all + run: ./tool/go build ./cmd/... + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: "0" + - name: build tests + run: | + toolgo=`pwd`/tool/go + for d in $($toolgo list -f '{{if .TestGoFiles}}{{.Dir}}{{end}}' ./... ); do + (echo $d; cd $d && $toolgo test -c) + done + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: "0" + + 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-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: build some + run: ./tool/go build ./ipn/... ./wgengine/ ./types/... ./control/controlclient + env: + GOOS: ios + GOARCH: arm64 + + wasm: # builds tsconnect, which is the only wasm build we support + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: build tsconnect client + run: ./tool/go build ./cmd/tsconnect/wasm ./cmd/tailscale/cli + env: + GOOS: js + GOARCH: wasm + - name: build tsconnect server + # 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 + + fuzz: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: build fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'tailscale' + dry-run: false + language: go + - name: run fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'tailscale' + fuzz-seconds: 300 + dry-run: false + language: go + - name: upload crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts + + depaware: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: check depaware + run: | + export PATH=$(./tool/go env GOROOT)/bin:$PATH + find . -name 'depaware.txt' | xargs -n1 dirname | xargs ./tool/go run github.com/tailscale/depaware --check + + go_generate: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: check that 'go generate' is clean + run: | + pkgs=$(./tool/go list ./... | grep -v dnsfallback) + ./tool/go generate $pkgs + echo + echo + git diff --name-only --exit-code || (echo "The files above need updating. Please run 'go generate'."; exit 1) + + go_mod_tidy: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: check that 'go mod tidy' is clean + run: | + ./tool/go mod tidy + echo + echo + git diff --name-only --exit-code || (echo "Please run 'go mod tidy'."; exit 1) + + licenses: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + - name: check licenses + run: ./scripts/check_license_headers.sh . + + staticcheck: + runs-on: ubuntu-latest + strategy: + fail-fast: false # don't abort the entire matrix if one element fails + matrix: + goos: ["linux", "windows", "darwin"] + goarch: ["amd64"] + include: + - goos: "windows" + goarch: "386" + steps: + - name: checkout + uses: actions/checkout@v3 + - name: install staticcheck + run: GOBIN=~/.local/bin ./tool/go install honnef.co/go/tools/cmd/staticcheck + - name: run staticcheck + run: | + export GOROOT=$(./tool/go env GOROOT) + export PATH=$GOROOT/bin:$PATH + staticcheck -- $(./tool/go list ./... | grep -v tempfork) + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + + notify_slack: + # Only notify slack for merged commits, not PR failures. + if: failure() && github.event_name == 'push' + # Any of these jobs failing causes a slack notification. + needs: + - test + - windows + - vm + - cross + - ios + - wasm + - fuzz + - depaware + - go_generate + - go_mod_tidy + - licenses + - staticcheck + runs-on: ubuntu-latest + steps: + - name: notify + uses: ruby/action-slack@v3.0.0 + with: + payload: | + { + "attachments": [{ + "title": "Failure: ${{ github.workflow }}", + "title_link": "https://github.com/${{ github.repository }}/commit/${{ github.sha }}/checks", + "text": "${{ github.repository }}@${{ github.ref_name }}: ", + "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" + }] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/vm.yml b/.github/workflows/vm.yml deleted file mode 100644 index 28a1d5da3..000000000 --- a/.github/workflows/vm.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: VM - -on: - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - ubuntu2004-LTS-cloud-base: - runs-on: [ self-hosted, linux, vm ] - - # VM tests run with some privileges, don't let them run on 3p PRs. - if: "github.repository == 'tailscale/tailscale'" - - steps: - - name: Set GOPATH - run: echo "GOPATH=$HOME/go" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: Run VM tests - run: go test ./tstest/integration/vms -v -no-s3 -run-vm-tests -run=TestRunUbuntu2004 - env: - HOME: "/tmp" - TMPDIR: "/tmp" - XDG_CACHE_HOME: "/var/lib/ghrunner/cache" - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 22e1f7017..000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Windows - -on: - push: - branches: - - main - pull_request: - branches: - - '*' - - 'release-branch/*' - -concurrency: - group: ${{ github.workflow }}-$${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - test: - runs-on: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install Go - uses: actions/setup-go@v3 - with: - go-version-file: go.mod - - - name: Restore Cache - uses: actions/cache@v3 - with: - # Note: unlike some other setups, this is only grabbing the mod download - # cache, rather than the whole mod directory, as the download cache - # contains zips that can be unpacked in parallel faster than they can be - # fetched and extracted by tar - path: | - ~/go/pkg/mod/cache - ~\AppData\Local\go-build - - # The -2- here should be incremented when the scheme of data to be - # cached changes (e.g. path above changes). - # TODO(raggi): add a go version here. - key: ${{ runner.os }}-go-2-${{ hashFiles('**/go.sum') }} - - - name: Test - # Don't use -bench=. -benchtime=1x. - # Somewhere in the layers (powershell?) - # the equals signs cause great confusion. - run: go test -bench . -benchtime 1x ./... - - - uses: k0kubun/action-slack@v2.0.0 - with: - payload: | - { - "attachments": [{ - "text": "${{ job.status }}: ${{ github.workflow }} " + - "() " + - "of ${{ github.repository }}@" + "${{ github.ref }}".split('/').reverse()[0] + " by ${{ github.event.head_commit.committer.name }}", - "color": "danger" - }] - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() && github.event_name == 'push' -