diff --git a/dist/index.js b/dist/index.js index 5bddb73..e59b833 100644 --- a/dist/index.js +++ b/dist/index.js @@ -52515,17 +52515,37 @@ async function installTailscaleLinux(config, toolPath) { } // Download and extract const downloadUrl = `${baseUrl}/tailscale_${config.resolvedVersion}_${config.arch}.tgz`; - (0, logging_1.logInfo)(config.logMode, `Downloading ${downloadUrl}`); + const expectedSha = config.sha256Sum.trim().toLowerCase(); const tarDest = path.join(xdgCacheDir(), "tailscale.tgz"); fs.mkdirSync(path.dirname(tarDest), { recursive: true }); - const tarPath = await tc.downloadTool(downloadUrl, tarDest); - // Verify checksum - const actualSha = await calculateFileSha256(tarPath); - const expectedSha = config.sha256Sum.trim().toLowerCase(); - (0, logging_1.logInfo)(config.logMode, `Expected sha256: ${expectedSha}`); - (0, logging_1.logInfo)(config.logMode, `Actual sha256: ${actualSha}`); - if (actualSha !== expectedSha) { - throw new Error("SHA256 checksum mismatch"); + // Check if the tarball already exists with the correct checksum (for + // persistent self-hosted runners). tc.downloadTool refuses to overwrite an + // existing destination, so a tarball leaked by a previous job would + // otherwise fail with "Destination file path already exists" whenever the + // GitHub Actions cache backend doesn't return a hit. + let tarPath = tarDest; + let needsDownload = true; + if (fs.existsSync(tarDest)) { + const existingSha = await calculateFileSha256(tarDest); + if (existingSha === expectedSha) { + (0, logging_1.logInfo)(config.logMode, `Using existing tarball at ${tarDest} (checksum verified)`); + needsDownload = false; + } + else { + (0, logging_1.logInfo)(config.logMode, `Existing tarball checksum mismatch, re-downloading`); + fs.unlinkSync(tarDest); + } + } + if (needsDownload) { + (0, logging_1.logInfo)(config.logMode, `Downloading ${downloadUrl}`); + tarPath = await tc.downloadTool(downloadUrl, tarDest); + // Verify checksum + const actualSha = await calculateFileSha256(tarPath); + (0, logging_1.logInfo)(config.logMode, `Expected sha256: ${expectedSha}`); + (0, logging_1.logInfo)(config.logMode, `Actual sha256: ${actualSha}`); + if (actualSha !== expectedSha) { + throw new Error("SHA256 checksum mismatch"); + } } // Extract to tool path const extractedPath = await tc.extractTar(tarPath, undefined, "xz"); diff --git a/src/main.ts b/src/main.ts index dfb92bb..109d4c1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -472,19 +472,46 @@ async function installTailscaleLinux( // Download and extract const downloadUrl = `${baseUrl}/tailscale_${config.resolvedVersion}_${config.arch}.tgz`; - logInfo(config.logMode, `Downloading ${downloadUrl}`); + const expectedSha = config.sha256Sum.trim().toLowerCase(); const tarDest = path.join(xdgCacheDir(), "tailscale.tgz"); fs.mkdirSync(path.dirname(tarDest), { recursive: true }); - const tarPath = await tc.downloadTool(downloadUrl, tarDest); - // Verify checksum - const actualSha = await calculateFileSha256(tarPath); - const expectedSha = config.sha256Sum.trim().toLowerCase(); - logInfo(config.logMode, `Expected sha256: ${expectedSha}`); - logInfo(config.logMode, `Actual sha256: ${actualSha}`); - if (actualSha !== expectedSha) { - throw new Error("SHA256 checksum mismatch"); + // Check if the tarball already exists with the correct checksum (for + // persistent self-hosted runners). tc.downloadTool refuses to overwrite an + // existing destination, so a tarball leaked by a previous job would + // otherwise fail with "Destination file path already exists" whenever the + // GitHub Actions cache backend doesn't return a hit. + let tarPath = tarDest; + let needsDownload = true; + if (fs.existsSync(tarDest)) { + const existingSha = await calculateFileSha256(tarDest); + if (existingSha === expectedSha) { + logInfo( + config.logMode, + `Using existing tarball at ${tarDest} (checksum verified)`, + ); + needsDownload = false; + } else { + logInfo( + config.logMode, + `Existing tarball checksum mismatch, re-downloading`, + ); + fs.unlinkSync(tarDest); + } + } + + if (needsDownload) { + logInfo(config.logMode, `Downloading ${downloadUrl}`); + tarPath = await tc.downloadTool(downloadUrl, tarDest); + + // Verify checksum + const actualSha = await calculateFileSha256(tarPath); + logInfo(config.logMode, `Expected sha256: ${expectedSha}`); + logInfo(config.logMode, `Actual sha256: ${actualSha}`); + if (actualSha !== expectedSha) { + throw new Error("SHA256 checksum mismatch"); + } } // Extract to tool path