Skip to content

Commit 148ffe3

Browse files
committed
fix bugs in ping logic, ping hosts in parallel, and tweak README and LICENSE
The ping logic had some bugs in the wait logic which are now fixed. Pinging hosts in parallel will speed up CI. LICENSE and README got small updates in preparation for moving this code to tailscale/github-action. Updates tailscale/corp#32862 Signed-off-by: Percy Wegmann <percy@tailscale.com>
1 parent c9da281 commit 148ffe3

4 files changed

Lines changed: 39 additions & 21 deletions

File tree

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
BSD 3-Clause License
22

3+
Copyright (c) 2020 Tailscale Inc & Contributors
34
Copyright (c) 2025 Lee Briggs
4-
Copyright (c) 2025 Tailscale Inc & Contributors
55
All rights reserved.
66

77
Redistribution and use in source and binary forms, with or without

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ by adding a step to your workflow.
55

66
```yaml
77
- name: Tailscale
8-
uses: tailscale/github-action@v3
8+
uses: tailscale/github-action@v4
99
with:
1010
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
1111
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
@@ -40,7 +40,7 @@ You can do this by adding a list of hosts to ping to the action configuration:
4040

4141
```yaml
4242
- name: Tailscale
43-
uses: tailscale/github-action@v3
43+
uses: tailscale/github-action@v4
4444
with:
4545
ping: 100.x.y.z,my-machine.my-tailnet.ts.net
4646
```
@@ -51,6 +51,8 @@ or with the [tailscale ping](https://tailscale.com/kb/1080/cli#ping) command if
5151
tailscale ping my-target.my-tailnet.ts.net
5252
```
5353

54+
The `ping` option will wait up to to 3 minutes for a connection (direct or relayed).
55+
5456
> ⚠️ On macOS runners, one can only ping IP addresses, not hostnames.
5557

5658
## Tailnet Lock
@@ -67,7 +69,7 @@ Lock](https://tailscale.com/kb/1226/tailnet-lock) enabled network, you need to:
6769

6870
```yaml
6971
- name: Tailscale
70-
uses: tailscale/github-action@v3
72+
uses: tailscale/github-action@v4
7173
with:
7274
authkey: tskey-auth-...
7375
statedir: /tmp/tailscale-state/
@@ -79,7 +81,7 @@ Which Tailscale version to use can be set like this:
7981

8082
```yaml
8183
- name: Tailscale
82-
uses: tailscale/github-action@v3
84+
uses: tailscale/github-action@v4
8385
with:
8486
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
8587
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
@@ -91,7 +93,7 @@ If you'd like to specify the latest version, simply set the version as `latest`
9193

9294
```yaml
9395
- name: Tailscale
94-
uses: tailscale/github-action@v3
96+
uses: tailscale/github-action@v4
9597
with:
9698
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
9799
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
@@ -115,7 +117,7 @@ Although caching is generally recommended, you can disable it by passing `'false
115117

116118
```yaml
117119
- name: Tailscale
118-
uses: tailscale/github-action@v3
120+
uses: tailscale/github-action@v4
119121
with:
120122
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
121123
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}

dist/index.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41270,27 +41270,35 @@ async function pingHostsIfNecessary(config) {
4127041270
if (config.pingHosts.length == 0) {
4127141271
return;
4127241272
}
41273-
core.info(`Will ping hosts ${config.pingHosts.join(",")} up to 3 minutes each in order to check connectivity`);
41274-
for (const host of config.pingHosts) {
41275-
await pingHost(host);
41273+
core.info(`Will ping hosts ${config.pingHosts.join(",")} up to 3 minutes each (in parallel) in order to check connectivity`);
41274+
let pings = config.pingHosts.map((host) => pingHost(host));
41275+
for (const ping of pings) {
41276+
await ping;
4127641277
}
4127741278
}
4127841279
async function pingHost(host) {
4127941280
core.info(`Pinging host ${host}`);
41280-
for (let i = 0; i <= 36; i++) {
41281-
if (i < 0) {
41282-
// wait 5 seconds before pinging
41283-
(0, promises_1.setTimeout)(5000);
41281+
let start = new Date().getTime();
41282+
var i = 0;
41283+
// Try for up to 180 seconds (3 minutes).
41284+
while ((new Date().getTime() - start) / 1000 < 180) {
41285+
if (i > 0) {
41286+
// Exponential backoff on wait time, with maximum 5 second wait.
41287+
let waitTime = Math.min(Math.pow(1.3, i), 5000);
41288+
core.debug(`Waiting ${waitTime} milliseconds before pinging`);
41289+
await (0, promises_1.setTimeout)(waitTime);
4128441290
}
4128541291
let result = await exec.getExecOutput(cmdTailscale, ["ping", "-c", "1", host], { ignoreReturnCode: true });
4128641292
if (result.exitCode === 0) {
4128741293
core.info(`✅ Ping host ${host} reachable via direct connection!`);
4128841294
return;
4128941295
}
4129041296
else if (result.stderr.includes("direct connection not established")) {
41297+
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
4129141298
core.info(`✅ Ping host ${host} reachable via DERP!`);
4129241299
return;
4129341300
}
41301+
i++;
4129441302
}
4129541303
core.setFailed(`❌ Ping host ${host} did not respond`);
4129641304
process.exit(1);

src/main.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,25 @@ async function pingHostsIfNecessary(config: TailscaleConfig): Promise<void> {
199199
core.info(
200200
`Will ping hosts ${config.pingHosts.join(
201201
","
202-
)} up to 3 minutes each in order to check connectivity`
202+
)} up to 3 minutes each (in parallel) in order to check connectivity`
203203
);
204-
for (const host of config.pingHosts) {
205-
await pingHost(host);
204+
let pings = config.pingHosts.map((host) => pingHost(host));
205+
for (const ping of pings) {
206+
await ping;
206207
}
207208
}
208209

209210
async function pingHost(host: string): Promise<void> {
210211
core.info(`Pinging host ${host}`);
211-
for (let i = 0; i <= 36; i++) {
212-
if (i < 0) {
213-
// wait 5 seconds before pinging
214-
wait(5000);
212+
let start = new Date().getTime();
213+
var i = 0;
214+
// Try for up to 180 seconds (3 minutes).
215+
while ((new Date().getTime() - start) / 1000 < 180) {
216+
if (i > 0) {
217+
// Exponential backoff on wait time, with maximum 5 second wait.
218+
let waitTime = Math.min(Math.pow(1.3, i), 5000);
219+
core.debug(`Waiting ${waitTime} milliseconds before pinging`);
220+
await wait(waitTime);
215221
}
216222
let result = await exec.getExecOutput(
217223
cmdTailscale,
@@ -222,9 +228,11 @@ async function pingHost(host: string): Promise<void> {
222228
core.info(`✅ Ping host ${host} reachable via direct connection!`);
223229
return;
224230
} else if (result.stderr.includes("direct connection not established")) {
231+
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
225232
core.info(`✅ Ping host ${host} reachable via DERP!`);
226233
return;
227234
}
235+
i++;
228236
}
229237
core.setFailed(`❌ Ping host ${host} did not respond`);
230238
process.exit(1);

0 commit comments

Comments
 (0)