Merge pull request #195 from tailscale/max/test-target-connectivity-check

Added argument to test targets connectivity
This commit is contained in:
Max Coulombe 2025-09-25 11:43:46 -04:00 committed by GitHub
commit 6cae46e2d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 94 additions and 33 deletions

View file

@ -4,12 +4,12 @@ This GitHub Action connects to your [Tailscale network](https://tailscale.com)
by adding a step to your workflow.
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
```
Subsequent steps in the Action can then access nodes in your Tailnet.
@ -29,6 +29,28 @@ be automatically removed by the coordination server a short time after they
finish their run. The nodes are also [marked Preapproved](https://tailscale.com/kb/1085/auth-keys/)
on tailnets which use [Device Approval](https://tailscale.com/kb/1099/device-approval/)
## Eventual consistency
Propagating information about new peers - such as the node created by this action - across your tailnet
is an eventually consistent process, and brief delays are expected. Until the GitHub workflow node
becomes visible, other peers will not accept connections. It is best to verify connectivity to the
intended nodes before executing steps that rely on them.
You can do this by adding a list of targets to the action configuration:
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
targets: 100.x.y.z,my-machine.my-tailnet.ts.net
```
or with the [tailscale ping](https://tailscale.com/kb/1080/cli#ping) command if you do not know the targets at the time of installing Tailscale in the workflow:
```bash
tailscale ping my-target.my-tailnet.ts.net
```
## Tailnet Lock
If you are using this Action in a [Tailnet
@ -42,11 +64,11 @@ Lock](https://tailscale.com/kb/1226/tailnet-lock) enabled network, you need to:
client to store the Tailnet Key Authority data in.
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
authkey: tskey-auth-...
statedir: /tmp/tailscale-state/
- name: Tailscale
uses: tailscale/github-action@v3
with:
authkey: tskey-auth-...
statedir: /tmp/tailscale-state/
```
## Defining Tailscale version
@ -54,25 +76,25 @@ Lock](https://tailscale.com/kb/1226/tailnet-lock) enabled network, you need to:
Which Tailscale version to use can be set like this:
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
version: 1.52.0
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
version: 1.52.0
```
If you'd like to specify the latest version, simply set the version as `latest`
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
version: latest
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
tags: tag:ci
version: latest
```
You can find the latest Tailscale stable version number at
@ -86,10 +108,10 @@ Caching can reduce download times and download failures on runners with slower n
You can opt in to caching Tailscale binaries by passing `'true'` to the `use-cache` input:
```yaml
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
use-cache: 'true'
- name: Tailscale
uses: tailscale/github-action@v3
with:
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
use-cache: 'true'
```

View file

@ -56,6 +56,10 @@ inputs:
description: 'Whether to cache the Tailscale binaries (Linux/macOS) or installer (Windows)'
required: false
default: 'false'
targets:
description: 'Comma separated list of targets (Tailscale IP addresses or machine names if MagicDNS is enabled on the tailnet) to `tailscale ping` for connectivity verification after `tailscale up` completes'
required: false
default: ''
runs:
using: 'composite'
steps:
@ -150,7 +154,7 @@ runs:
URL="https://pkgs.tailscale.com/unstable/tailscale_${RESOLVED_VERSION}_${TS_ARCH}.tgz"
fi
echo "Downloading $URL"
curl -H user-agent:tailscale-github-action -L "$URL" -o tailscale.tgz --max-time 300 --fail
curl -H user-agent:tailscale-github-action -L "$URL" -o tailscale.tgz --max-time 300 --retry 3 --retry-all-errors --fail
echo "Expected sha256: $SHA256SUM"
echo "Actual sha256: $(sha256sum tailscale.tgz)"
echo "$SHA256SUM tailscale.tgz" | sha256sum -c
@ -209,7 +213,7 @@ runs:
URL="https://pkgs.tailscale.com/unstable/tailscale-setup-${RESOLVED_VERSION}-${TS_ARCH}.msi"
fi
echo "Downloading $URL"
curl -H user-agent:tailscale-github-action -L "$URL" -o tailscale.msi --max-time 300 --fail
curl -H user-agent:tailscale-github-action -L "$URL" -o tailscale.msi --max-time 300 --retry 3 --retry-all-errors --fail
echo "Expected sha256: $SHA256SUM"
echo "Actual sha256: $(sha256sum tailscale.msi)"
echo "$SHA256SUM tailscale.msi" | sha256sum -c
@ -353,3 +357,38 @@ runs:
echo "Tailscale up failed. Retrying in $((i * 5)) seconds..."
sleep $((i * 5))
done
- name: Verify Target Connectivity
if: ${{ inputs.targets != '' }}
shell: bash
env:
TARGETS: ${{ inputs.targets }}
run: |
IFS=',' read -ra TARGET_ARRAY <<< "$TARGETS"
if [ "${{ runner.os }}" != "Windows" ]; then
MAYBE_SUDO="sudo -E"
fi
failed_targets=()
for target in "${TARGET_ARRAY[@]}"; do
target=$(echo "$target" | xargs) # trim whitespace
if [ -n "$target" ]; then
output=$(${MAYBE_SUDO} tailscale ping --c=36 $target 2>&1)
exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "Successfully reached $target"
elif echo "$output" | grep -q "direct connection not established"; then
echo "::warning title=Target Connectivity Warning::Failed to establish direct connection to $target but was able to connect via DERP"
else
# Regular failure case
echo "Failed to reach $target"
failed_targets+=("$target")
fi
fi
done
if [ ${#failed_targets[@]} -gt 0 ]; then
echo "::error title=Target Connectivity Failed::Failed to reach the following targets: ${failed_targets[*]}"
exit 1
fi