diff --git a/README.md b/README.md
index dd74fe2..3e4f68c 100644
--- a/README.md
+++ b/README.md
@@ -26,9 +26,19 @@ with any of the Users on the tailnet, it has to Tag its nodes.
Nodes created by this Action are [marked as Ephemeral](https://tailscale.com/s/ephemeral-nodes) to
and log out immediately after finishing their CI run, at which point they are automatically removed
-by the coordination. The nodes are also [marked Preapproved](https://tailscale.com/kb/1085/auth-keys/)
+by the coordination server. 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/)
+## Prerequisites
+
+Before using the Tailscale GitHub Action, ensure you have the following:
+
+1. A Tailscale account with Owner, Admin, or Network admin permissions.
+1. A GitHub repository that you have admin access to (required to set up the GitHub Action).
+1. At least one configured [tag][kb-tags].
+1. An [OAuth client][kb-oauth-clients] ID and secret OR an [auth key][kb-auth-keys].
+1. A runner image version >= 2.237.1 (required to support running Node.js 24).
+
## Eventual consistency
Propagating information about new peers - such as the node created by this action - across your tailnet
diff --git a/dist/index.js b/dist/index.js
index c725ff1..ba10c95 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -41122,7 +41122,6 @@ const tc = __importStar(__nccwpck_require__(33472));
const child_process_1 = __nccwpck_require__(35317);
const crypto = __importStar(__nccwpck_require__(76982));
const fs = __importStar(__nccwpck_require__(79896));
-const http = __importStar(__nccwpck_require__(58611));
const os = __importStar(__nccwpck_require__(70857));
const path = __importStar(__nccwpck_require__(16928));
const promises_1 = __nccwpck_require__(16460);
@@ -41139,75 +41138,11 @@ const versionLatest = "latest";
const versionUnstable = "unstable";
// Cross-platform Tailscale local API status check
async function getTailscaleStatus() {
- const platform = os.platform();
- if (platform === platformWin32) {
- // Windows: use tailscale status command
- const { stdout } = await exec.getExecOutput(cmdTailscale, [
- "status",
- "--json",
- ]);
- return JSON.parse(stdout);
- }
- else if (platform === platformDarwin) {
- // macOS: use /var/run/tailscaled.socket
- return new Promise((resolve, reject) => {
- const options = {
- socketPath: "/var/run/tailscaled.socket",
- path: "/localapi/v0/status",
- method: "GET",
- headers: { Host: "local-tailscaled.sock" },
- };
- const req = http.request(options, (res) => {
- let data = "";
- res.on("data", (chunk) => (data += chunk));
- res.on("end", () => {
- try {
- resolve(JSON.parse(data));
- }
- catch (e) {
- reject(e);
- }
- });
- });
- // Set timeout to prevent hanging
- req.setTimeout(5000, () => {
- req.destroy();
- reject(new Error("Request timeout"));
- });
- req.on("error", reject);
- req.end();
- });
- }
- else {
- // Linux: use Unix socket
- return new Promise((resolve, reject) => {
- const options = {
- socketPath: "/run/tailscale/tailscaled.sock",
- path: "/localapi/v0/status",
- method: "GET",
- headers: { Host: "local-tailscaled.sock" },
- };
- const req = http.request(options, (res) => {
- let data = "";
- res.on("data", (chunk) => (data += chunk));
- res.on("end", () => {
- try {
- resolve(JSON.parse(data));
- }
- catch (e) {
- reject(e);
- }
- });
- });
- // Set timeout to prevent hanging
- req.setTimeout(5000, () => {
- req.destroy();
- reject(new Error("Request timeout"));
- });
- req.on("error", reject);
- req.end();
- });
- }
+ const { stdout } = await exec.getExecOutput(cmdTailscale, [
+ "status",
+ "--json",
+ ]);
+ return JSON.parse(stdout);
}
async function run() {
try {
diff --git a/src/main.ts b/src/main.ts
index b925986..99aa5ec 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,7 +8,6 @@ import * as tc from "@actions/tool-cache";
import { spawn } from "child_process";
import * as crypto from "crypto";
import * as fs from "fs";
-import * as http from "http";
import * as os from "os";
import * as path from "path";
import { setTimeout as wait } from "timers/promises";
@@ -59,78 +58,11 @@ type tailscaleStatus = {
// Cross-platform Tailscale local API status check
async function getTailscaleStatus(): Promise {
- const platform = os.platform();
-
- if (platform === platformWin32) {
- // Windows: use tailscale status command
- const { stdout } = await exec.getExecOutput(cmdTailscale, [
- "status",
- "--json",
- ]);
- return JSON.parse(stdout);
- } else if (platform === platformDarwin) {
- // macOS: use /var/run/tailscaled.socket
- return new Promise((resolve, reject) => {
- const options: http.RequestOptions = {
- socketPath: "/var/run/tailscaled.socket",
- path: "/localapi/v0/status",
- method: "GET",
- headers: { Host: "local-tailscaled.sock" },
- };
-
- const req = http.request(options, (res) => {
- let data = "";
- res.on("data", (chunk) => (data += chunk));
- res.on("end", () => {
- try {
- resolve(JSON.parse(data));
- } catch (e) {
- reject(e);
- }
- });
- });
-
- // Set timeout to prevent hanging
- req.setTimeout(5000, () => {
- req.destroy();
- reject(new Error("Request timeout"));
- });
-
- req.on("error", reject);
- req.end();
- });
- } else {
- // Linux: use Unix socket
- return new Promise((resolve, reject) => {
- const options: http.RequestOptions = {
- socketPath: "/run/tailscale/tailscaled.sock",
- path: "/localapi/v0/status",
- method: "GET",
- headers: { Host: "local-tailscaled.sock" },
- };
-
- const req = http.request(options, (res) => {
- let data = "";
- res.on("data", (chunk) => (data += chunk));
- res.on("end", () => {
- try {
- resolve(JSON.parse(data));
- } catch (e) {
- reject(e);
- }
- });
- });
-
- // Set timeout to prevent hanging
- req.setTimeout(5000, () => {
- req.destroy();
- reject(new Error("Request timeout"));
- });
-
- req.on("error", reject);
- req.end();
- });
- }
+ const { stdout } = await exec.getExecOutput(cmdTailscale, [
+ "status",
+ "--json",
+ ]);
+ return JSON.parse(stdout);
}
async function run(): Promise {