1111#
1212# The convention here is tailscale-android-build-amd64-<date>
1313DOCKER_IMAGE := tailscale-android-build-amd64-041425-1
14+
15+ # The integration test image contains the Android emulator, system image, SDK,
16+ # build-tools, NDK, adb, and helper tools needed to run the emulator-backed Go
17+ # integration tests. Bump this tag when docker/Dockerfile.android-integration
18+ # or the required tool versions change, using:
19+ # tailscale-android-integration-amd64-YYYYMMDD-N
20+ ANDROID_INTEGRATION_DOCKER_IMAGE := tailscale-android-integration-amd64-20260526-3
1421export TS_USE_TOOLCHAIN =1
1522
1623# If set, additional comma-separated build tags passed to the libtailscale Go
@@ -365,6 +372,14 @@ docker-build-image: ## Builds the docker image for the android build environment
365372 docker build -f docker/DockerFile.amd64-build -t $(DOCKER_IMAGE ) . ; \
366373 fi
367374
375+ .PHONY : docker-build-android-integration-image
376+ docker-build-android-integration-image : # # Build the Docker image used to run Android integration tests
377+ @echo " Checking if docker image $( ANDROID_INTEGRATION_DOCKER_IMAGE) already exists..."
378+ @if ! docker images $(ANDROID_INTEGRATION_DOCKER_IMAGE ) -q | grep -q . ; then \
379+ echo " Image does not exist. Building..." ; \
380+ docker build -f docker/Dockerfile.android-integration -t $(ANDROID_INTEGRATION_DOCKER_IMAGE ) . ; \
381+ fi
382+
368383# DOCKER_ANDROID_DIR is bind-mounted as /root/.android inside the container
369384# so the Gradle-generated debug keystore (and anything else under ~/.android)
370385# persists across docker runs. Without this, every docker-based debug build
@@ -373,12 +388,19 @@ docker-build-image: ## Builds the docker image for the android build environment
373388# JVM's user.home resolves to /root for the container's root user, regardless
374389# of the Dockerfile's HOME=/build env.
375390DOCKER_ANDROID_DIR := $(CURDIR ) /.android-docker
391+ DOCKER_ANDROID_INTEGRATION_DIR := $(CURDIR ) /.android-integration-docker
392+ DOCKER_GRADLE_DIR := $(CURDIR ) /.gradle-docker
393+ DOCKER_GO_CACHE_DIR := $(CURDIR ) /.cache-docker
376394
377395.PHONY : docker-android-dir
378396docker-android-dir :
379- @mkdir -p $(DOCKER_ANDROID_DIR )
397+ @mkdir -p $(DOCKER_ANDROID_DIR ) $(DOCKER_GRADLE_DIR ) $(DOCKER_GO_CACHE_DIR )
398+
399+ .PHONY : docker-android-integration-dir
400+ docker-android-integration-dir :
401+ @mkdir -p $(DOCKER_ANDROID_INTEGRATION_DIR ) $(DOCKER_GO_CACHE_DIR )
380402
381- DOCKER_RUN_VOLS := -v $(CURDIR ) :/build/tailscale-android -v $(DOCKER_ANDROID_DIR ) :/root/.android
403+ DOCKER_RUN_VOLS := -v $(CURDIR ) :/build/tailscale-android -v $(DOCKER_ANDROID_DIR ) :/root/.android -v $( DOCKER_GRADLE_DIR ) :/build/.gradle -v $( DOCKER_GO_CACHE_DIR ) :/build/.cache --env GOPATH=/build/.cache/go --env GOMODCACHE=/build/.cache/go/pkg/mod
382404
383405.PHONY : docker-run-build
384406docker-run-build : clean jarsign-env docker-build-image docker-android-dir # # Runs the docker image for the android build environment and builds release
@@ -388,6 +410,21 @@ docker-run-build: clean jarsign-env docker-build-image docker-android-dir ## Run
388410docker-tailscale-debug : docker-build-image docker-android-dir # # Build tailscale-debug.apk inside the docker env (stable signer across runs)
389411 @docker run --rm $(DOCKER_RUN_VOLS ) $(DOCKER_IMAGE ) make tailscale-debug
390412
413+ .PHONY : android-integration-test
414+ android-integration-test : docker-tailscale-debug android-integration-test-run # # Build APK and run adb-backed Android integration tests in Docker
415+
416+ .PHONY : android-integration-test-run
417+ android-integration-test-run : docker-build-android-integration-image docker-android-integration-dir # # Run adb-backed Android integration tests in Docker using existing APK
418+ @docker run --rm --device /dev/kvm \
419+ -v $(CURDIR ) :/workspace \
420+ -v $(DOCKER_ANDROID_INTEGRATION_DIR ) :/root/.android \
421+ -v $(DOCKER_GO_CACHE_DIR ) :/root/.cache \
422+ --env GOPATH=/root/.cache/go \
423+ --env GOMODCACHE=/root/.cache/go/pkg/mod \
424+ -w /workspace \
425+ $(ANDROID_INTEGRATION_DOCKER_IMAGE ) \
426+ /usr/local/bin/run-android-integration-test /workspace/$(DEBUG_APK )
427+
391428.PHONY : docker-remove-build-image
392429docker-remove-build-image : # # Removes the current docker build image
393430 docker rmi --force $(DOCKER_IMAGE )
0 commit comments