The following Vagrant and Docker and Azure scripts are available to provision Tentacles and assist with manually setting up different versions of Tentacle for compatibility testing.
Use the Vagrant scripts to setup a Windows or Linux VM with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported.
Use the Docker Compose scripts to setup docker containers with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported.
Use the Azure scripts to setup Azure Virtual Machines with a selection of Tentacle versions, both Polling and Listening Deployment Targets and Workers are supported.
Use docker-linux/build-and-test-linux-docker-image.sh to build and verify the Linux Tentacle container image (docker/linux/Dockerfile) end to end, the way TeamCity does. This is the only local way to check a change to that Dockerfile, since the image is built in TeamCity rather than by NUKE.
The script runs in four stages, each of which can be skipped:
| Stage | What it does |
|---|---|
deb |
Builds the linux-x64 .deb via NUKE (--target PackDebianPackage) |
image |
Builds the image with the same docker-compose.build.yml command TeamCity runs |
smoke |
Asserts the image's contents and behaviour - base image, .NET runtime dependencies, docker-in-docker, entrypoint guards, labels |
e2e |
Stands up SQL Server and an Octopus Server, then registers a listening and a polling Tentacle built from the fresh image |
# everything
./docker-linux/build-and-test-linux-docker-image.sh
# reuse the last .deb and image, just re-run the assertions
./docker-linux/build-and-test-linux-docker-image.sh --skip-deb --skip-image
# full options
./docker-linux/build-and-test-linux-docker-image.sh --help
The e2e stage needs an Octopus Server licence, because an unlicensed server enforces a limit of 0 targets and no Tentacle can register. Set OCTOPUS_SERVER_BASE64_LICENSE, or let the script read a development licence from 1Password when run interactively. Without one, the stage still verifies configuration and server connectivity up to the licence refusal. Pass --no-1password anywhere op must not run.
Use linux-packages/test-packages-on-distros.sh to run NUKE's TestLinuxPackages target locally. That target installs the built .deb/.rpm on every distribution in the matrix in build/Build.Tests.cs and checks the installed Tentacle reports the expected version.
The wrapper exists because the target needs three things set up before it will run outside TeamCity - exactly one package of each type in _artifacts (it calls .Single()), DOCKER_DEFAULT_PLATFORM=linux/amd64 for the amd64-only images, and OCTOPUS__Tests__SecretManagerEnabled=False so NUKE's start-up does not block on the 1Password CLI - and because its result cannot be read from its exit code.
Logging.InTest catches each per-distribution failure, logs it and carries on. On TeamCity that still fails the build, through the ##teamcity[testFailed] service message it writes, but locally the target reports Succeeded and build.sh exits 0 even when a distribution failed; the only trace is the "Errors & Warnings" block at the bottom of the output. The wrapper reads the log back, reports every distribution individually, and exits non-zero if any of them did not pass.
# the whole matrix, against the packages already in _artifacts
./linux-packages/test-packages-on-distros.sh
# build the packages first
./linux-packages/test-packages-on-distros.sh --pack
# iterate on one distribution, skipping NUKE entirely
./linux-packages/test-packages-on-distros.sh --distro ubuntu:24.04
# full options
./linux-packages/test-packages-on-distros.sh --help