name: Linux on: push: branches: - main pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || github.actor_id }} cancel-in-progress: true jobs: build-cache: name: "Build Cache" runs-on: ubuntu-22.04 outputs: management: ${{ steps.filter.outputs.management }} steps: - name: Checkout code uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: filters: | management: - 'management/**' - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache@v4 id: cache with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} - name: Install dependencies if: steps.cache.outputs.cache-hit != 'true' run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-multilib libpcap-dev - name: Install 32-bit libpcap if: steps.cache.outputs.cache-hit != 'true' run: sudo dpkg --add-architecture i386 && sudo apt update && sudo apt-get install -y libpcap0.8-dev:i386 - name: Build client if: steps.cache.outputs.cache-hit != 'true' working-directory: client run: CGO_ENABLED=1 go build . - name: Build client 386 if: steps.cache.outputs.cache-hit != 'true' working-directory: client run: CGO_ENABLED=1 GOARCH=386 go build -o client-386 . - name: Build management if: steps.cache.outputs.cache-hit != 'true' working-directory: management run: CGO_ENABLED=1 go build . - name: Build management 386 if: steps.cache.outputs.cache-hit != 'true' working-directory: management run: CGO_ENABLED=1 GOARCH=386 go build -o management-386 . - name: Build signal if: steps.cache.outputs.cache-hit != 'true' working-directory: signal run: CGO_ENABLED=1 go build . - name: Build signal 386 if: steps.cache.outputs.cache-hit != 'true' working-directory: signal run: CGO_ENABLED=1 GOARCH=386 go build -o signal-386 . - name: Build relay if: steps.cache.outputs.cache-hit != 'true' working-directory: relay run: CGO_ENABLED=1 go build . - name: Build relay 386 if: steps.cache.outputs.cache-hit != 'true' working-directory: relay run: CGO_ENABLED=1 GOARCH=386 go build -o relay-386 . test: name: "Client / Unit" needs: [build-cache] strategy: fail-fast: false matrix: arch: [ '386','amd64' ] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install dependencies run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-multilib libpcap-dev - name: Install 32-bit libpcap if: matrix.arch == '386' run: sudo dpkg --add-architecture i386 && sudo apt update && sudo apt-get install -y libpcap0.8-dev:i386 - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Test run: CGO_ENABLED=1 GOARCH=${{ matrix.arch }} CI=true go test -tags devcert -exec 'sudo' -timeout 10m -p 1 $(go list ./... | grep -v -e /management -e /signal -e /relay) test_client_on_docker: name: "Client (Docker) / Unit" needs: [ build-cache ] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment id: go-env run: | echo "cache_dir=$(go env GOCACHE)" >> $GITHUB_OUTPUT echo "modcache_dir=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT - name: Cache Go modules uses: actions/cache/restore@v4 id: cache-restore with: path: | ${{ steps.go-env.outputs.cache_dir }} ${{ steps.go-env.outputs.modcache_dir }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Run tests in container env: HOST_GOCACHE: ${{ steps.go-env.outputs.cache_dir }} HOST_GOMODCACHE: ${{ steps.go-env.outputs.modcache_dir }} CONTAINER: "true" run: | CONTAINER_GOCACHE="/root/.cache/go-build" CONTAINER_GOMODCACHE="/go/pkg/mod" docker run --rm \ --cap-add=NET_ADMIN \ --privileged \ -v $PWD:/app \ -w /app \ -v "${HOST_GOCACHE}:${CONTAINER_GOCACHE}" \ -v "${HOST_GOMODCACHE}:${CONTAINER_GOMODCACHE}" \ -e CGO_ENABLED=1 \ -e CI=true \ -e DOCKER_CI=true \ -e GOARCH=${GOARCH_TARGET} \ -e GOCACHE=${CONTAINER_GOCACHE} \ -e GOMODCACHE=${CONTAINER_GOMODCACHE} \ -e CONTAINER=${CONTAINER} \ golang:1.23-alpine \ sh -c ' \ apk update; apk add --no-cache \ ca-certificates iptables ip6tables dbus dbus-dev libpcap-dev build-base; \ go test -buildvcs=false -tags devcert -v -timeout 10m -p 1 $(go list -buildvcs=false ./... | grep -v -e /management -e /signal -e /relay -e /client/ui -e /upload-server) ' test_relay: name: "Relay / Unit" needs: [build-cache] strategy: fail-fast: false matrix: include: - arch: "386" raceFlag: "" - arch: "amd64" raceFlag: "" runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies if: steps.cache.outputs.cache-hit != 'true' run: sudo apt update && sudo apt install -y gcc-multilib g++-multilib libc6-dev-i386 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ go test ${{ matrix.raceFlag }} \ -exec 'sudo' \ -timeout 10m ./relay/... ./shared/relay/... test_signal: name: "Signal / Unit" needs: [build-cache] strategy: fail-fast: false matrix: arch: [ '386','amd64' ] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies if: steps.cache.outputs.cache-hit != 'true' run: sudo apt update && sudo apt install -y gcc-multilib g++-multilib libc6-dev-i386 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ go test \ -exec 'sudo' \ -timeout 10m ./signal/... ./shared/signal/... test_management: name: "Management / Unit" needs: [ build-cache ] strategy: fail-fast: false matrix: arch: [ 'amd64' ] store: [ 'sqlite', 'postgres', 'mysql' ] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Login to Docker hub if: matrix.store == 'mysql' && (github.repository == github.head.repo.full_name || !github.head_ref) uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_TOKEN }} - name: download mysql image if: matrix.store == 'mysql' run: docker pull mlsmaycon/warmed-mysql:8 - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ NETBIRD_STORE_ENGINE=${{ matrix.store }} \ CI=true \ go test -tags=devcert \ -exec "sudo --preserve-env=CI,NETBIRD_STORE_ENGINE" \ -timeout 20m ./management/... ./shared/management/... benchmark: name: "Management / Benchmark" needs: [ build-cache ] if: ${{ needs.build-cache.outputs.management == 'true' || github.event_name != 'pull_request' }} strategy: fail-fast: false matrix: arch: [ 'amd64' ] store: [ 'sqlite', 'postgres' ] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Login to Docker hub if: matrix.store == 'mysql' && (github.repository == github.head.repo.full_name || !github.head_ref) uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_TOKEN }} - name: download mysql image if: matrix.store == 'mysql' run: docker pull mlsmaycon/warmed-mysql:8 - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ NETBIRD_STORE_ENGINE=${{ matrix.store }} \ CI=true \ go test -tags devcert -run=^$ -bench=. \ -exec 'sudo --preserve-env=CI,NETBIRD_STORE_ENGINE' \ -timeout 20m ./management/... ./shared/management/... api_benchmark: name: "Management / Benchmark (API)" needs: [ build-cache ] if: ${{ needs.build-cache.outputs.management == 'true' || github.event_name != 'pull_request' }} strategy: fail-fast: false matrix: arch: [ 'amd64' ] store: [ 'sqlite', 'postgres' ] runs-on: ubuntu-22.04 steps: - name: Create Docker network run: docker network create promnet - name: Start Prometheus Pushgateway run: docker run -d --name pushgateway --network promnet -p 9091:9091 prom/pushgateway - name: Start Prometheus (for Pushgateway forwarding) run: | echo ' global: scrape_interval: 15s scrape_configs: - job_name: "pushgateway" static_configs: - targets: ["pushgateway:9091"] remote_write: - url: ${{ secrets.GRAFANA_URL }} basic_auth: username: ${{ secrets.GRAFANA_USER }} password: ${{ secrets.GRAFANA_API_KEY }} ' > prometheus.yml docker run -d --name prometheus --network promnet \ -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml \ -p 9090:9090 \ prom/prometheus - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Login to Docker hub if: matrix.store == 'mysql' && (github.repository == github.head.repo.full_name || !github.head_ref) uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_TOKEN }} - name: download mysql image if: matrix.store == 'mysql' run: docker pull mlsmaycon/warmed-mysql:8 - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ NETBIRD_STORE_ENGINE=${{ matrix.store }} \ CI=true \ GIT_BRANCH=${{ github.ref_name }} \ go test -tags=benchmark \ -run=^$ \ -bench=. \ -exec 'sudo --preserve-env=CI,NETBIRD_STORE_ENGINE,GIT_BRANCH,GITHUB_RUN_ID' \ -timeout 20m ./management/... ./shared/management/... api_integration_test: name: "Management / Integration" needs: [ build-cache ] if: ${{ needs.build-cache.outputs.management == 'true' || github.event_name != 'pull_request' }} strategy: fail-fast: false matrix: arch: [ 'amd64' ] store: [ 'sqlite', 'postgres'] runs-on: ubuntu-22.04 steps: - name: Install Go uses: actions/setup-go@v5 with: go-version: "1.23.x" cache: false - name: Checkout code uses: actions/checkout@v4 - name: Get Go environment run: | echo "cache=$(go env GOCACHE)" >> $GITHUB_ENV echo "modcache=$(go env GOMODCACHE)" >> $GITHUB_ENV - name: Cache Go modules uses: actions/cache/restore@v4 with: path: | ${{ env.cache }} ${{ env.modcache }} key: ${{ runner.os }}-gotest-cache-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-gotest-cache- - name: Install modules run: go mod tidy - name: check git status run: git --no-pager diff --exit-code - name: Test run: | CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \ NETBIRD_STORE_ENGINE=${{ matrix.store }} \ CI=true \ go test -tags=integration \ -exec 'sudo --preserve-env=CI,NETBIRD_STORE_ENGINE' \ -timeout 20m ./management/... ./shared/management/...