33
44import * as core from "@actions/core" ;
55import * as exec from "@actions/exec" ;
6+ import * as fs from "fs" ;
7+
8+ const runnerWindows = "Windows" ;
69
710async function logout ( ) : Promise < void > {
811 try {
@@ -24,31 +27,47 @@ async function logout(): Promise<void> {
2427 // Check if tailscale is available first
2528 try {
2629 await exec . exec ( "tailscale" , [ "--version" ] , { silent : true } ) ;
30+
31+ // Determine the correct command based on OS
32+ let execArgs : string [ ] ;
33+ if ( runnerOS === runnerWindows ) {
34+ execArgs = [ "tailscale" , "logout" ] ;
35+ } else {
36+ // Linux and macOS - use system-installed binary with sudo
37+ execArgs = [ "sudo" , "-E" , "tailscale" , "logout" ] ;
38+ }
39+
40+ core . info ( `Running: ${ execArgs . join ( " " ) } ` ) ;
41+
42+ try {
43+ await exec . exec ( execArgs [ 0 ] , execArgs . slice ( 1 ) ) ;
44+ core . info ( "✅ Successfully logged out of Tailscale" ) ;
45+ } catch ( error ) {
46+ // Don't fail the action if logout fails - it's just cleanup
47+ core . warning ( `Failed to logout from Tailscale: ${ error } ` ) ;
48+ core . info (
49+ "Your ephemeral node will eventually be cleaned up by Tailscale"
50+ ) ;
51+ }
2752 } catch ( error ) {
2853 core . info ( "Tailscale not found or not accessible, skipping logout" ) ;
2954 return ;
3055 }
3156
32- // Determine the correct command based on OS
33- let execArgs : string [ ] ;
34- if ( runnerOS === "Windows" ) {
35- execArgs = [ "tailscale" , "logout" ] ;
36- } else {
37- // Linux and macOS - use system-installed binary with sudo
38- execArgs = [ "sudo" , "-E" , "tailscale" , "logout" ] ;
39- }
40-
41- core . info ( `Running: ${ execArgs . join ( " " ) } ` ) ;
42-
43- try {
44- await exec . exec ( execArgs [ 0 ] , execArgs . slice ( 1 ) ) ;
45- core . info ( "✅ Successfully logged out of Tailscale" ) ;
46- } catch ( error ) {
47- // Don't fail the action if logout fails - it's just cleanup
48- core . warning ( `Failed to logout from Tailscale: ${ error } ` ) ;
49- core . info (
50- "Your ephemeral node will eventually be cleaned up by Tailscale"
51- ) ;
57+ if ( runnerOS !== runnerWindows ) {
58+ try {
59+ core . info ( "Stopping tailscaled" ) ;
60+ const pid = fs . readFileSync ( "tailscaled.pid" ) . toString ( ) ;
61+ if ( pid === "" ) {
62+ throw new Error ( "pid file empty" ) ;
63+ }
64+ exec . exec ( "sudo" , [ "ps" , "-ef" ] )
65+ await exec . exec ( "sudo" , [ "kill" , "-9" , pid ] ) ;
66+ core . info ( "✅ Stopped tailscaled" ) ;
67+ exec . exec ( "sudo" , [ "ps" , "-ef" ] )
68+ } catch ( error ) {
69+ core . warning ( `Failed to stop tailscaled: ${ error } ` ) ;
70+ }
5271 }
5372 } catch ( error ) {
5473 // Don't fail the action for post-cleanup issues
0 commit comments