name: Integration Tests on: [pull_request] concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: integration-test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: test: - TestACLHostsInNetMapTable - TestACLAllowUser80Dst - TestACLDenyAllPort80 - TestACLAllowUserDst - TestACLAllowStarDst - TestACLNamedHostsCanReachBySubnet - TestACLNamedHostsCanReach - TestACLDevice1CanAccessDevice2 - TestPolicyUpdateWhileRunningWithCLIInDatabase - TestOIDCAuthenticationPingAll - TestOIDCExpireNodesBasedOnTokenExpiry - TestOIDC024UserCreation - TestAuthWebFlowAuthenticationPingAll - TestAuthWebFlowLogoutAndRelogin - TestUserCommand - TestPreAuthKeyCommand - TestPreAuthKeyCommandWithoutExpiry - TestPreAuthKeyCommandReusableEphemeral - TestPreAuthKeyCorrectUserLoggedInCommand - TestApiKeyCommand - TestNodeTagCommand - TestNodeAdvertiseTagNoACLCommand - TestNodeAdvertiseTagWithACLCommand - TestNodeCommand - TestNodeExpireCommand - TestNodeRenameCommand - TestNodeMoveCommand - TestPolicyCommand - TestPolicyBrokenConfigCommand - TestDERPVerifyEndpoint - TestResolveMagicDNS - TestValidateResolvConf - TestDERPServerScenario - TestDERPServerWebsocketScenario - TestPingAllByIP - TestPingAllByIPPublicDERP - TestAuthKeyLogoutAndRelogin - TestEphemeral - TestEphemeralInAlternateTimezone - TestEphemeral2006DeletedTooQuickly - TestPingAllByHostname - TestTaildrop - TestUpdateHostnameFromClient - TestExpireNode - TestNodeOnlineStatus - TestPingAllByIPManyUpDown - Test2118DeletingOnlineNodePanics - TestEnablingRoutes - TestHASubnetRouterFailover - TestEnableDisableAutoApprovedRoute - TestAutoApprovedSubRoute2068 - TestSubnetRouteACL - TestHeadscale - TestCreateTailscale - TestTailscaleNodesJoiningHeadcale - TestSSHOneUserToAll - TestSSHMultipleUsersAllToAll - TestSSHNoSSHConfigured - TestSSHIsBlockedInACL - TestSSHUserOnlyIsolation database: [postgres, sqlite] steps: - uses: actions/checkout@v4 with: fetch-depth: 2 - name: Get changed files id: changed-files uses: dorny/paths-filter@v3 with: filters: | files: - '*.nix' - 'go.*' - '**/*.go' - 'integration_test/' - 'config-example.yaml' - uses: DeterminateSystems/nix-installer-action@main if: steps.changed-files.outputs.files == 'true' - uses: DeterminateSystems/magic-nix-cache-action@main if: steps.changed-files.outputs.files == 'true' - uses: satackey/action-docker-layer-caching@main if: steps.changed-files.outputs.files == 'true' continue-on-error: true - name: Run Integration Test uses: Wandalen/wretry.action@master if: steps.changed-files.outputs.files == 'true' env: USE_POSTGRES: ${{ matrix.database == 'postgres' && '1' || '0' }} with: attempt_limit: 5 command: | nix develop --command -- docker run \ --tty --rm \ --volume ~/.cache/hs-integration-go:/go \ --name headscale-test-suite \ --volume $PWD:$PWD -w $PWD/integration \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume $PWD/control_logs:/tmp/control \ --env HEADSCALE_INTEGRATION_POSTGRES=${{env.USE_POSTGRES}} \ golang:1 \ go run gotest.tools/gotestsum@latest -- ./... \ -failfast \ -timeout 120m \ -parallel 1 \ -run "^${{ matrix.test }}$" - uses: actions/upload-artifact@v4 if: always() && steps.changed-files.outputs.files == 'true' with: name: ${{ matrix.test }}-${{matrix.database}}-logs path: "control_logs/*.log" - uses: actions/upload-artifact@v4 if: always() && steps.changed-files.outputs.files == 'true' with: name: ${{ matrix.test }}-${{matrix.database}}-pprof path: "control_logs/*.pprof.tar"