Skip to content

Commit 21fc386

Browse files
committed
default to running all commands except tailscale up silently
To avoid leaking any potentially sensitive information, all commands are now run without logging to the console. Logging can be enabled by turning on debug logging as described at https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging. Updates tailscale/corp#33405 Signed-off-by: Percy Wegmann <[email protected]>
1 parent b69384a commit 21fc386

File tree

2 files changed

+251
-96
lines changed

2 files changed

+251
-96
lines changed

dist/index.js

Lines changed: 112 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41129,26 +41129,17 @@ const cmdTailscale = "tailscale";
4112941129
const cmdTailscaleFullPath = "/usr/local/bin/tailscale";
4113041130
const cmdTailscaled = "tailscaled";
4113141131
const cmdTailscaledFullPath = "/usr/local/bin/tailscaled";
41132-
const platformWin32 = "win32";
41133-
const platformDarwin = "darwin";
4113441132
const runnerLinux = "Linux";
4113541133
const runnerWindows = "Windows";
4113641134
const runnerMacOS = "macOS";
4113741135
const versionLatest = "latest";
4113841136
const versionUnstable = "unstable";
4113941137
// Cross-platform Tailscale local API status check
4114041138
async function getTailscaleStatus() {
41141-
const { exitCode, stdout, stderr } = await exec.getExecOutput(cmdTailscale, ["status", "--json"], {
41142-
silent: true,
41143-
ignoreReturnCode: true,
41144-
});
41145-
if (exitCode !== 0) {
41146-
process.stderr.write(stderr);
41147-
throw new Error(`tailscale status failed with exit code ${exitCode}`);
41148-
}
41149-
if (core.isDebug()) {
41150-
process.stdout.write(stdout);
41151-
}
41139+
const { stdout } = await execSilent("get tailscale status", cmdTailscale, [
41140+
"status",
41141+
"--json",
41142+
]);
4115241143
return JSON.parse(stdout);
4115341144
}
4115441145
async function run() {
@@ -41236,15 +41227,23 @@ async function pingHost(host) {
4123641227
core.debug(`Waiting ${waitTime} milliseconds before pinging`);
4123741228
await (0, promises_1.setTimeout)(waitTime);
4123841229
}
41239-
let result = await exec.getExecOutput(cmdTailscale, ["ping", "-c", "1", host], { ignoreReturnCode: true });
41240-
if (result.exitCode === 0) {
41230+
try {
41231+
let result = await execSilent("ping host", cmdTailscale, [
41232+
"ping",
41233+
"-c",
41234+
"1",
41235+
host,
41236+
]);
4124141237
core.info(`✅ Ping host ${host} reachable via direct connection!`);
4124241238
return;
4124341239
}
41244-
else if (result.stderr.includes("direct connection not established")) {
41245-
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
41246-
core.info(`✅ Ping host ${host} reachable via DERP!`);
41247-
return;
41240+
catch (err) {
41241+
if (err instanceof execError &&
41242+
err.stderr.includes("direct connection not established")) {
41243+
// Relayed connectivity is good enough, we don't want to tie up a CI job waiting for a direct connection.
41244+
core.info(`✅ Ping host ${host} reachable via DERP!`);
41245+
return;
41246+
}
4124841247
}
4124941248
i++;
4125041249
}
@@ -41295,11 +41294,12 @@ async function resolveVersion(version, runnerOS) {
4129541294
}
4129641295
if (version === versionLatest || version === versionUnstable) {
4129741296
let path = version === versionUnstable ? versionUnstable : "stable";
41298-
const { stdout } = await exec.getExecOutput("curl", [
41297+
let pkg = `https://pkgs.tailscale.com/${path}/?mode=json`;
41298+
const { stdout } = await execSilent(`curl ${pkg}`, "curl", [
4129941299
"-H",
4130041300
"user-agent:action-setup-tailscale",
4130141301
"-s",
41302-
`https://pkgs.tailscale.com/${path}/?mode=json`,
41302+
pkg,
4130341303
]);
4130441304
const response = JSON.parse(stdout);
4130541305
return response.Version;
@@ -41400,7 +41400,7 @@ async function installTailscaleLinux(config, toolPath) {
4140041400
// Get SHA256 if not provided
4140141401
if (!config.sha256Sum) {
4140241402
const shaUrl = `${baseUrl}/tailscale_${config.resolvedVersion}_${config.arch}.tgz.sha256`;
41403-
const { stdout } = await exec.getExecOutput("curl", [
41403+
const { stdout } = await execSilent(`curl ${shaUrl}`, "curl", [
4140441404
"-H",
4140541405
"user-agent:action-setup-tailscale",
4140641406
"-L",
@@ -41429,15 +41429,23 @@ async function installTailscaleLinux(config, toolPath) {
4142941429
fs.copyFileSync(path.join(extractedDir, cmdTailscale), path.join(toolPath, cmdTailscale));
4143041430
fs.copyFileSync(path.join(extractedDir, cmdTailscaled), path.join(toolPath, cmdTailscaled));
4143141431
// Install binaries to /usr/local/bin
41432-
await exec.exec("sudo", [
41432+
await execSilent("copy tailscale binaries to /usr/local/bin", "sudo", [
4143341433
"cp",
4143441434
path.join(toolPath, cmdTailscale),
4143541435
path.join(toolPath, cmdTailscaled),
4143641436
"/usr/local/bin",
4143741437
]);
4143841438
// Make sure they're executable
41439-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41440-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41439+
await execSilent("chmod tailscale binary", "sudo", [
41440+
"chmod",
41441+
"+x",
41442+
cmdTailscaleFullPath,
41443+
]);
41444+
await execSilent("chmod tailscaled binary", "sudo", [
41445+
"chmod",
41446+
"+x",
41447+
cmdTailscaledFullPath,
41448+
]);
4144141449
}
4144241450
async function installTailscaleWindows(config, toolPath, fromCache = false) {
4144341451
// Create tool directory
@@ -41461,7 +41469,7 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4146141469
// Get SHA256 if not provided
4146241470
if (!config.sha256Sum) {
4146341471
const shaUrl = `${baseUrl}/tailscale-setup-${config.resolvedVersion}-${config.arch}.msi.sha256`;
41464-
const { stdout } = await exec.getExecOutput("curl", [
41472+
const { stdout } = await execSilent(`curl ${shaUrl}`, "curl", [
4146541473
"-H",
4146641474
"user-agent:action-setup-tailscale",
4146741475
"-L",
@@ -41489,7 +41497,7 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4148941497
}
4149041498
}
4149141499
// Install MSI (same for both fresh and cached)
41492-
await exec.exec("msiexec.exe", [
41500+
await execSilent("install msi", "msiexec.exe", [
4149341501
"/quiet",
4149441502
`/l*v`,
4149541503
path.join(process.env.RUNNER_TEMP || "", "tailscale.log"),
@@ -41502,16 +41510,16 @@ async function installTailscaleWindows(config, toolPath, fromCache = false) {
4150241510
async function installTailscaleMacOS(config, toolPath) {
4150341511
core.info("Building tailscale from src on macOS...");
4150441512
// Clone the repo
41505-
await exec.exec("git clone https://github.com/tailscale/tailscale.git tailscale");
41513+
await execSilent("glone tailscale repo", "git clone https://github.com/tailscale/tailscale.git tailscale");
4150641514
// Checkout the resolved version
41507-
await exec.exec(`git checkout v${config.resolvedVersion}`, [], {
41515+
await execSilent("checkout resolved version", `git checkout v${config.resolvedVersion}`, [], {
4150841516
cwd: cmdTailscale,
4150941517
});
4151041518
// Create tool directory and copy binaries there for caching
4151141519
fs.mkdirSync(toolPath, { recursive: true });
4151241520
// Build tailscale and tailscaled into tool directory
4151341521
for (const binary of [cmdTailscale, cmdTailscaled]) {
41514-
await exec.exec(`./build_dist.sh -o ${path.join(toolPath, binary)} ./cmd/${binary}`, [], {
41522+
await execSilent(`build ${binary}`, `./build_dist.sh -o ${path.join(toolPath, binary)} ./cmd/${binary}`, [], {
4151541523
cwd: cmdTailscale,
4151641524
env: {
4151741525
...process.env,
@@ -41520,15 +41528,23 @@ async function installTailscaleMacOS(config, toolPath) {
4152041528
});
4152141529
}
4152241530
// Install binaries to /usr/local/bin
41523-
await exec.exec("sudo", [
41531+
await execSilent("copy binaries to /usr/local/bin", "sudo", [
4152441532
"cp",
4152541533
path.join(toolPath, cmdTailscale),
4152641534
path.join(toolPath, cmdTailscaled),
4152741535
"/usr/local/bin",
4152841536
]);
4152941537
// Make sure they're executable
41530-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41531-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41538+
await execSilent("chmod tailscale", "sudo", [
41539+
"chmod",
41540+
"+x",
41541+
cmdTailscaleFullPath,
41542+
]);
41543+
await execSilent("chmod tailscaled", "sudo", [
41544+
"chmod",
41545+
"+x",
41546+
cmdTailscaledFullPath,
41547+
]);
4153241548
core.info("✅ Tailscale installed successfully on macOS from source");
4153341549
}
4153441550
async function startTailscaleDaemon(config) {
@@ -41599,7 +41615,7 @@ async function connectToTailscale(config, runnerOS) {
4159941615
hostname = `github-${process.env.COMPUTERNAME}`;
4160041616
}
4160141617
else {
41602-
const { stdout } = await exec.getExecOutput("hostname");
41618+
const { stdout } = await execSilent("hostname", "hostname");
4160341619
hostname = `github-${stdout.trim()}`;
4160441620
}
4160541621
}
@@ -41642,9 +41658,8 @@ async function connectToTailscale(config, runnerOS) {
4164241658
execArgs = ["sudo", "-E", cmdTailscale, ...upArgs];
4164341659
}
4164441660
const timeoutMs = parseTimeout(config.timeout);
41645-
core.info(`Running: ${execArgs.join(" ")} (timeout: ${timeoutMs}ms)`);
4164641661
await Promise.race([
41647-
exec.exec(execArgs[0], execArgs.slice(1)),
41662+
execSilent("tailscale up", execArgs[0], execArgs.slice(1)),
4164841663
new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), timeoutMs)),
4164941664
]);
4165041665
// Success
@@ -41701,10 +41716,26 @@ async function installCachedBinaries(toolPath, runnerOS) {
4170141716
const tailscaleBin = path.join(toolPath, cmdTailscale);
4170241717
const tailscaledBin = path.join(toolPath, cmdTailscaled);
4170341718
if (fs.existsSync(tailscaleBin) && fs.existsSync(tailscaledBin)) {
41704-
await exec.exec("sudo", ["cp", tailscaleBin, cmdTailscaleFullPath]);
41705-
await exec.exec("sudo", ["cp", tailscaledBin, cmdTailscaledFullPath]);
41706-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaleFullPath]);
41707-
await exec.exec("sudo", ["chmod", "+x", cmdTailscaledFullPath]);
41719+
await execSilent("copy tailscale from cache", "sudo", [
41720+
"cp",
41721+
tailscaleBin,
41722+
cmdTailscaleFullPath,
41723+
]);
41724+
await execSilent("copy tailscaled from cache", "sudo", [
41725+
"cp",
41726+
tailscaledBin,
41727+
cmdTailscaledFullPath,
41728+
]);
41729+
await execSilent("chmod tailscale", "sudo", [
41730+
"chmod",
41731+
"+x",
41732+
cmdTailscaleFullPath,
41733+
]);
41734+
await execSilent("chmod tailscaled", "sudo", [
41735+
"chmod",
41736+
"+x",
41737+
cmdTailscaledFullPath,
41738+
]);
4170841739
}
4170941740
else {
4171041741
throw new Error(`Cached binaries not found in ${toolPath}`);
@@ -41718,12 +41749,12 @@ async function configureDNSOnMacOS(status) {
4171841749
}
4171941750
core.info(`Setting system DNS server to 100.100.100.100 and searchdomains to ${status.CurrentTailnet.MagicDNSSuffix}`);
4172041751
try {
41721-
await exec.exec("networksetup", [
41752+
await execSilent("set dns servers", "networksetup", [
4172241753
"-setdnsservers",
4172341754
"Ethernet",
4172441755
"100.100.100.100",
4172541756
]);
41726-
await exec.exec("networksetup", [
41757+
await execSilent("set search domains", "networksetup", [
4172741758
"-setsearchdomains",
4172841759
"Ethernet",
4172941760
status.CurrentTailnet.MagicDNSSuffix,
@@ -41734,6 +41765,45 @@ async function configureDNSOnMacOS(status) {
4173441765
}
4173541766
}
4173641767
run();
41768+
/**
41769+
* Executes the given command, logging the given label as info, but suppressing
41770+
* all other output including the command line itself (unless debug logging is enabled,
41771+
* see https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging).
41772+
*
41773+
* If the command fails, stderr is written to the console.
41774+
*
41775+
* @param label a label to use for info logging what's happening
41776+
* @param cmd the command to run
41777+
* @param args arguments to the command
41778+
* @returns stdout (if command was successful)
41779+
* @throws execError if exec returned a non-zero status code
41780+
*/
41781+
async function execSilent(label, cmd, args, opts) {
41782+
core.info(`▶️ ${label}`);
41783+
const out = await exec.getExecOutput(cmd, args, {
41784+
...opts,
41785+
silent: !core.isDebug(),
41786+
ignoreReturnCode: true,
41787+
});
41788+
if (out.exitCode !== 0) {
41789+
if (!core.isDebug) {
41790+
// When debug logging is off, stderr won't have been written to console, write it now.
41791+
process.stderr.write(out.stderr);
41792+
}
41793+
throw new execError(`${cmd} failed with exit code ${out.exitCode}`, out.exitCode, out.stderr);
41794+
}
41795+
return out;
41796+
}
41797+
class execError {
41798+
constructor(msg, exitCode, stderr) {
41799+
this.msg = msg;
41800+
this.exitCode = exitCode;
41801+
this.stderr = stderr;
41802+
}
41803+
toString() {
41804+
return this.msg;
41805+
}
41806+
}
4173741807

4173841808

4173941809
/***/ }),

0 commit comments

Comments
 (0)