Merge branch 'main' into embedded-vnc

# Conflicts:
#	client/ui/frontend/src/app.tsx
#	client/ui/frontend/src/modules/main/MainConnectionStatusSwitch.tsx
#	client/ui/i18n/locales/uk/common.json
#	go.sum
This commit is contained in:
Viktor Liu
2026-09-22 14:53:34 +02:00
205 changed files with 12118 additions and 1280 deletions
+7 -5
View File
@@ -46,15 +46,17 @@ jobs:
run: git --no-pager diff --exit-code
- name: Test
# Exclude client/ui: its main.go uses //go:embed all:frontend/dist,
# which fails to compile until the frontend has been built. The Wails UI
# has no Go-side unit tests, and its release pipeline runs `pnpm build`
# before goreleaser.
# Exclude the client/ui package itself: its main.go uses //go:embed
# all:frontend/dist, which fails to compile until the frontend has been
# built, and its release pipeline runs `pnpm build` before goreleaser.
# The pattern is anchored so the subpackages (services, preferences,
# i18n, authsession) still run: they hold Go-side unit tests and need no
# frontend bundle.
# `go list -e` lets the listing succeed even though the embed fails to
# resolve; the grep then drops the broken package by path. Without -e,
# go list aborts with empty stdout and `go test` falls back to the repo
# root, which has no Go files.
run: NETBIRD_STORE_ENGINE=${{ matrix.store }} CI=true go test -coverprofile=coverage.txt -tags 'devcert privileged' -exec 'sudo --preserve-env=CI,NETBIRD_STORE_ENGINE' -timeout 5m -p 1 $(go list -e ./... | grep -v -e /management -e /signal -e /relay -e /proxy -e /combined -e /client/ui -e /client/testutil/privileged)
run: NETBIRD_STORE_ENGINE=${{ matrix.store }} CI=true go test -coverprofile=coverage.txt -tags 'devcert privileged' -exec 'sudo --preserve-env=CI,NETBIRD_STORE_ENGINE' -timeout 5m -p 1 $(go list -e ./... | grep -v -e /management -e /signal -e /relay -e /proxy -e /combined -e '/client/ui$' -e /client/testutil/privileged)
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f #v7.0.0
+72 -6
View File
@@ -160,9 +160,10 @@ jobs:
- name: Test
# Exclude client/ui: its main.go uses //go:embed all:frontend/dist,
# which fails to compile until the frontend has been built. The Wails UI
# has no Go-side unit tests, and its release pipeline runs `pnpm build`
# before goreleaser.
# which fails to compile until the frontend has been built, and its
# release pipeline runs `pnpm build` before goreleaser. The subpackages
# go with it because this runner's gtk4 is older than the wails runtime
# needs; the Client UI / Unit job below covers them instead.
# `go list -e` lets the listing succeed even though the embed fails to
# resolve; the grep then drops the broken package by path. Without -e,
# go list aborts with empty stdout and `go test` falls back to the repo
@@ -177,6 +178,35 @@ jobs:
slug: netbirdio/netbird
flags: unit,client
test_client_ui:
name: "Client UI / Unit"
# Pinned to 24.04 rather than the 22.04 the other client jobs use: the wails
# runtime's linux cgo layer needs GtkFileDialog, which arrived in gtk4 4.10,
# and jammy ships 4.6. Not ubuntu-latest, so a runner image rollover cannot
# move this out from under us.
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: "go.mod"
cache: false
- name: Install dependencies
run: sudo apt update && sudo apt install -y -q libgtk-4-dev libwebkitgtk-6.0-dev libsoup-3.0-dev
- name: Test
# client/ui itself stays out: its main.go embeds all:frontend/dist,
# which only exists after `pnpm build`. The subpackages carry the
# Go-side unit tests, including the window manager re-entrancy
# regression test, and need no frontend bundle.
run: CGO_ENABLED=1 go test -timeout 5m ./client/ui/authsession/... ./client/ui/i18n/... ./client/ui/preferences/... ./client/ui/services/...
test_client_on_docker:
name: "Client (Docker) / Unit"
needs: [build-cache]
@@ -211,6 +241,9 @@ jobs:
${{ runner.os }}-gotest-cache-
- name: Run tests in container
# Unlike the native job above, this one drops all of client/ui including
# the subpackages: the alpine container has no gtk4/webkitgtk, so the
# Wails application package they import would fail to link.
env:
HOST_GOCACHE: ${{ steps.go-env.outputs.cache_dir }}
HOST_GOMODCACHE: ${{ steps.go-env.outputs.modcache_dir }}
@@ -481,14 +514,32 @@ jobs:
if: matrix.store == 'mysql'
run: docker pull mlsmaycon/warmed-mysql:8
# The -json stream goes through tools/gotestsummary so the log shows one
# line per test, the output of failed tests, the head of a timeout panic
# with the still-running tests, and the slowest tests per package.
- name: Test
shell: bash
run: |
set -o pipefail
CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \
NETBIRD_STORE_ENGINE=${{ matrix.store }} \
CI=true \
go test -tags=devcert -coverprofile=coverage.txt \
go test -json -tags=devcert -coverprofile=coverage.txt \
-exec "sudo --preserve-env=CI,NETBIRD_STORE_ENGINE" \
-timeout 20m ./management/... ./shared/management/...
-timeout 20m ./management/... ./shared/management/... \
| tee management-test-events.jsonl \
| go run ./tools/gotestsummary
# The summary trims long outputs; the raw stream keeps every line for
# the failures that need it. A green run has no use for it.
- name: Upload raw test events
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
with:
name: management-unit-test-events-${{ matrix.store }}
path: management-test-events.jsonl
if-no-files-found: ignore
retention-days: 14
- name: Upload coverage reports to Codecov
if: matrix.arch == 'amd64'
@@ -738,12 +789,27 @@ jobs:
- name: check git status
run: git --no-pager diff --exit-code
# Same summary as the unit job: a timeout here names the tests still
# running instead of ending in a goroutine dump.
- name: Test
shell: bash
run: |
set -o pipefail
CGO_ENABLED=1 GOARCH=${{ matrix.arch }} \
NETBIRD_STORE_ENGINE=${{ matrix.store }} \
CI=true \
mage integrationtest:all -gotestflags="-coverprofile=coverage.txt"
mage integrationtest:all -gotestflags="-json -coverprofile=coverage.txt" \
| tee management-integration-test-events.jsonl \
| go run ./tools/gotestsummary
- name: Upload raw test events
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
with:
name: management-integration-test-events-${{ matrix.store }}
path: management-integration-test-events.jsonl
if-no-files-found: ignore
retention-days: 14
- name: Upload coverage reports to Codecov
if: matrix.arch == 'amd64'
+7 -5
View File
@@ -66,15 +66,17 @@ jobs:
- run: PsExec64 -s -w ${{ github.workspace }} C:\hostedtoolcache\windows\go\${{ steps.go.outputs.go-version }}\x64\bin\go.exe env -w GOCACHE=${{ env.modcache }}
- run: PsExec64 -s -w ${{ github.workspace }} C:\hostedtoolcache\windows\go\${{ steps.go.outputs.go-version }}\x64\bin\go.exe mod tidy
- name: Generate test script
# Exclude client/ui: its main.go uses //go:embed all:frontend/dist,
# which fails to compile until the frontend has been built. The Wails UI
# has no Go-side unit tests, and its release pipeline runs `pnpm build`
# before goreleaser.
# Exclude the client/ui package itself: its main.go uses //go:embed
# all:frontend/dist, which fails to compile until the frontend has been
# built, and its release pipeline runs `pnpm build` before goreleaser.
# The pattern is anchored so the subpackages (services, preferences,
# i18n, authsession) still run: they hold Go-side unit tests and need no
# frontend bundle.
# `go list -e` lets the listing succeed even though the embed fails to
# resolve; the Where-Object pipeline then drops the broken package by
# path. Without -e, go list aborts with empty stdout.
run: |
$packages = go list -e ./... | Where-Object { $_ -notmatch '/management' } | Where-Object { $_ -notmatch '/relay' } | Where-Object { $_ -notmatch '/signal' } | Where-Object { $_ -notmatch '/proxy' } | Where-Object { $_ -notmatch '/combined' } | Where-Object { $_ -notmatch '/client/ui' }
$packages = go list -e ./... | Where-Object { $_ -notmatch '/management' } | Where-Object { $_ -notmatch '/relay' } | Where-Object { $_ -notmatch '/signal' } | Where-Object { $_ -notmatch '/proxy' } | Where-Object { $_ -notmatch '/combined' } | Where-Object { $_ -notmatch '/client/ui$' }
$goExe = "C:\hostedtoolcache\windows\go\${{ steps.go.outputs.go-version }}\x64\bin\go.exe"
$cmd = "$goExe test -tags `"devcert privileged`" -timeout 10m -p 1 $($packages -join ' ') > test-out.txt 2>&1"
Set-Content -Path "${{ github.workspace }}\run-tests.cmd" -Value $cmd
+12 -2
View File
@@ -186,6 +186,11 @@ jobs:
run: bash shared/management/http/api/generate.sh
- name: check git status
run: git --no-pager diff --exit-code
- name: Generate RPM changelog from git tags
# nfpm embeds changelog.yml into the RPM; Red Hat software certification
# requires a changelog. Generated, not committed (see .gitignore).
# chglog is a go.mod tool directive, so go.sum pins it and its deps.
run: bash release_files/rpm-changelog.sh
- name: Set up QEMU
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 #v4.1.0
- name: Set up Docker Buildx
@@ -287,10 +292,15 @@ jobs:
image_refs=()
tag_and_push() {
local src="$1" img_name tag dst
local src="$1" img_name tag dst variant=""
img_name="${src%%:*}"
# Client variants share a repository, so keep their tag suffixes.
case "$src" in
*-rootless-ubi-amd64) variant="-rootless-ubi" ;;
*-rootless-amd64) variant="-rootless" ;;
esac
for tag in $(resolve_tags); do
dst="${img_name}:${tag}"
dst="${img_name}:${tag}${variant}"
echo "Tagging ${src} -> ${dst}"
docker tag "$src" "$dst"
docker push "$dst"