将 GitHub Actions 运行器作为沙盒运行

这些工作流允许您将 GitHub Actions 运行器作为沙盒运行,以测试和修复您的工作流。

通过 Tailscale 访问沙盒,您可以:

  • 检查运行器镜像中实际包含的内容。
  • 观察运行器内部正在发生的情况。
  • 手动查看文件变更。
  • 动态运行命令。
  • 手动与 Windows GUI 交互。

GitHub 托管的运行器是公共资源,不应用于任何非开发用途。

您需要在您的仓库中设置 TS_OAUTH_CLIENT_IDTS_OAUTH_SECRET 密钥。该 OAuth 客户端需要拥有对 tag:ciauth_keys(读取或修改认证密钥)范围的写入权限。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
name: Windows RDP Sandbox with Tailscale
# RDP: runneradmin:6MonkeysRLooking^
# SSH: runneradmin:6MonkeysRLooking^
# Why 6MonkeysRLooking^: https://support.microsoft.com/en-us/windows/create-and-use-strong-passwords-c5cebb49-8c53-4f5e-2bc4-fe357ca048eb

# Controls when the workflow will run
on:
    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:
    # Allows external webhook trigger
    repository_dispatch:
        types: [windows-rdp-tailscale]

# You can use the following syntax to disable permissions for all of the available permissions:
permissions: {}

# concurrency:
#     # Only one workflow can run at a time
#     group: ${{ github.workflow }}
#     cancel-in-progress: true # Cancel previous runs

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
    # This workflow contains a single job called "sandbox"
    sandbox:
        # The type of runner that the job will run on
        runs-on: windows-2025
        # This is a hard limit. 360 is the maximum allowed by GitHub.
        timeout-minutes: 360

        # Steps represent a sequence of tasks that will be executed as part of the job
        steps:
            # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
            # - uses: actions/checkout@v4

            # Windows Server runner seems have SSH already enabled
            - name: Setup
              run: |
                  # Enable RDP
                  Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server'-name "fDenyTSConnections" -Value 0
                  Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
                  Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 1
                  # Set password
                  Set-LocalUser -Name "runneradmin" -Password (ConvertTo-SecureString -AsPlainText "6MonkeysRLooking^" -Force)
                  # Enable Audio
                  Set-Service -Name "Audiosrv" -StartupType Automatic
                  Start-Service -Name "Audiosrv"
                  # Hide power button and log off button
                  function Set-DwordRegistryValue {
                      param (
                          [Parameter(Mandatory=$true)]
                          [string]$Path,
                          [Parameter(Mandatory=$true)]
                          [string]$Name,
                          [Parameter(Mandatory=$true)]
                          [int]$Value
                      )

                      if (-not (Test-Path $Path)) {
                          New-Item -Path $Path -Force | Out-Null
                      }

                      New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType DWord -Force | Out-Null
                  }
                      
                  Set-DwordRegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "StartMenuLogOff" -Value 1
                  Set-DwordRegistryValue -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "NoClose" -Value 1
                  Set-DwordRegistryValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "HidePowerOptions" -Value 1
                  # Hide hosted-compute-agent window
                  function Hide-Window {
                      param([string]$ProcessName = "notepad")

                      Add-Type @"
                  using System;
                  using System.Runtime.InteropServices;
                  public class Win32 {
                      [DllImport("user32.dll")]
                      public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
                      [DllImport("user32.dll")]
                      public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
                      [DllImport("user32.dll")]
                      public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
                  }
                  "@

                      $SW_HIDE = 0
                      $GWL_EXSTYLE = -20
                      $WS_EX_TOOLWINDOW = 0x00000080

                      $procs = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
                      if (-not $procs) { return }

                      foreach ($proc in $procs) {
                          $hwnd = $proc.MainWindowHandle
                          if ($hwnd -eq 0) { continue }
                          $exStyle = [Win32]::GetWindowLong($hwnd, $GWL_EXSTYLE)
                          [Win32]::SetWindowLong($hwnd, $GWL_EXSTYLE, $exStyle -bor $WS_EX_TOOLWINDOW) | Out-Null
                          [Win32]::ShowWindow($hwnd, $SW_HIDE) | Out-Null
                      }
                  }

                  Hide-Window -ProcessName hosted-compute-agent

            - name: Tailscale
              uses: tailscale/github-action@v3
              with:
                  oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
                  oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
                  tags: tag:ci
                  args: --advertise-exit-node
                  hostname: gha-windows-sandbox
                  version: latest

            # Should be runneradmin
            - name: whoami
              run: whoami

            # Each job in a workflow can run for up to 6 hours of execution time.
            # If a job reaches this limit, the job is terminated and fails.
            # You may NOT log out runneradmin, since this will kill the Actions agent executable.
            # ("C:\ProgramData\GitHub\HostedComputeAgent\hosted-compute-agent")
            # The VM will be destroyed without agent watchdog message. So do not kill the agent process.
            - name: Sleep
              run: |
                  '@echo off\n type nul > C:\Users\runneradmin\Desktop\stop_sleeping_step_confirmed.txt' | Out-File C:\Users\runneradmin\Desktop\shutdown_confirmed.bat -Encoding ASCII
                  Write-Host "Sleeping..."
                  while (-not (Test-Path "C:\Users\runneradmin\Desktop\stop_sleeping_step_confirmed.txt")) {
                      Start-Sleep -Seconds 5
                  }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
name: Ubuntu VNC Sandbox with Tailscale
# SSH: runner:6MonkeysRLooking^
# VNC: 6MonkeysRLooking^ (Port: 5901)

# Controls when the workflow will run
on:
    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:
    # Allows external webhook trigger
    repository_dispatch:
        types: [ubuntu-vnc-tailscale]

# You can use the following syntax to disable permissions for all of the available permissions:
permissions: {}

# concurrency:
#     # Only one workflow can run at a time
#     group: ${{ github.workflow }}
#     cancel-in-progress: true # Cancel previous runs

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
    # This workflow contains a single job called "sandbox"
    sandbox:
        # The type of runner that the job will run on
        runs-on: ubuntu-24.04
        # This is a hard limit. 360 is the maximum allowed by GitHub.
        timeout-minutes: 360

        # Steps represent a sequence of tasks that will be executed as part of the job
        steps:
            # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
            # - uses: actions/checkout@v4

            - name: Setup
              run: |
                  # Change password
                  echo "runner:6MonkeysRLooking^" | sudo chpasswd
                  # Install SSH
                  sudo apt-get update
                  sudo apt-get install openssh-server
                  sudo systemctl enable --now ssh
                  # Install Desktop
                  sudo apt-get install ubuntu-desktop-minimal
                  # Install VNC server
                  sudo apt-get install tigervnc-standalone-server tigervnc-common
                  # Set VNC password
                  mkdir -p ~/.vnc
                  echo "6MonkeysRLooking^" | vncpasswd -f > ~/.vnc/passwd
                  chmod 600 ~/.vnc/passwd
                  # Start VNC server
                  vncserver :1 -geometry 1920x1080 -depth 24 -localhost no

            - name: Tailscale
              uses: tailscale/github-action@v3
              with:
                  oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
                  oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
                  tags: tag:ci
                  # Tailscale SSH feature does not need openssh-server or user password, it's controlled by ACL
                  args: --advertise-exit-node --ssh
                  hostname: gha-ubuntu-sandbox
                  version: latest

            # Should be runner
            - name: whoami
              run: whoami

            # Each job in a workflow can run for up to 6 hours of execution time.
            # If a job reaches this limit, the job is terminated and fails.
            - name: Sleep
              run: |
                  echo -e "#!/bin/bash\n\ntouch /tmp/stop_sleeping_step_confirmed" | sudo tee /home/runner/shutdown_confirmed.sh
                  sudo chmod +x /home/runner/shutdown_confirmed.sh
                  echo "Sleeping..."
                  while [ ! -e /tmp/stop_sleeping_step_confirmed ]; do
                      sleep 5
                  done
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
name: Ubuntu SSH Sandbox with Tailscale
# SSH: runner:6MonkeysRLooking^

# Controls when the workflow will run
on:
    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:
    # Allows external webhook trigger
    repository_dispatch:
        types: [ubuntu-ssh-tailscale]

# You can use the following syntax to disable permissions for all of the available permissions:
permissions: {}

# concurrency:
#     # Only one workflow can run at a time
#     group: ${{ github.workflow }}
#     cancel-in-progress: true # Cancel previous runs

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
    # This workflow contains a single job called "sandbox"
    sandbox:
        # The type of runner that the job will run on
        runs-on: ubuntu-24.04
        # This is a hard limit. 360 is the maximum allowed by GitHub.
        timeout-minutes: 360

        # Steps represent a sequence of tasks that will be executed as part of the job
        steps:
            # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
            # - uses: actions/checkout@v4

            - name: Setup
              run: |
                  # Change password
                  echo "runner:6MonkeysRLooking^" | sudo chpasswd
                  # Install SSH
                  sudo apt-get update
                  sudo apt-get install openssh-server
                  sudo systemctl enable --now ssh

            - name: Tailscale
              uses: tailscale/github-action@v3
              with:
                  oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
                  oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
                  tags: tag:ci
                  # Tailscale SSH feature does not need openssh-server or user password, it's controlled by ACL
                  args: --advertise-exit-node --ssh
                  hostname: gha-ubuntu-sandbox
                  version: latest

            # Should be runner
            - name: whoami
              run: whoami

            # Each job in a workflow can run for up to 6 hours of execution time.
            # If a job reaches this limit, the job is terminated and fails.
            - name: Sleep
              run: |
                  echo -e "#!/bin/bash\n\ntouch /tmp/stop_sleeping_step_confirmed" | sudo tee /home/runner/shutdown_confirmed.sh
                  sudo chmod +x /home/runner/shutdown_confirmed.sh
                  echo "Sleeping..."
                  while [ ! -e /tmp/stop_sleeping_step_confirmed ]; do
                      sleep 5
                  done
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
name: macOS SSH Sandbox with Tailscale
# SSH: altrunner:6MonkeysRLooking^
# VNC: altrunner:6MonkeysRLooking^ (Port: 5900) (Black Screen)

# Controls when the workflow will run
on:
    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:
    # Allows external webhook trigger
    repository_dispatch:
        types: [macos-ssh-tailscale]

# You can use the following syntax to disable permissions for all of the available permissions:
permissions: {}

# concurrency:
#     # Only one workflow can run at a time
#     group: ${{ github.workflow }}
#     cancel-in-progress: true # Cancel previous runs

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
    # This workflow contains a single job called "sandbox"
    sandbox:
        # The type of runner that the job will run on
        runs-on: macos-26
        # This is a hard limit. 360 is the maximum allowed by GitHub.
        timeout-minutes: 360

        # Steps represent a sequence of tasks that will be executed as part of the job
        steps:
            # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
            # - uses: actions/checkout@v4

            # macOS runner seems have SSH already enabled
            - name: Setup
              run: |
                  # https://github.com/dikeckaan/MacOS-Workflow-VNC/blob/master/configure.sh
                  # Disable spotlight indexing
                  sudo mdutil -i off -a

                  # Create new account
                  sudo dscl . -create /Users/altrunner
                  sudo dscl . -create /Users/altrunner UserShell /bin/bash
                  sudo dscl . -create /Users/altrunner RealName "My User"
                  sudo dscl . -create /Users/altrunner UniqueID 1001
                  sudo dscl . -create /Users/altrunner PrimaryGroupID 80
                  sudo dscl . -create /Users/altrunner NFSHomeDirectory /Users/altrunner
                  sudo dscl . -passwd /Users/altrunner "6MonkeysRLooking^"
                  sudo dscl . -passwd /Users/altrunner "6MonkeysRLooking^"
                  sudo createhomedir -c -u altrunner

                  # Enable VNC
                  # Set priveleges
                  sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -allUsers -privs -all
                  # Allow VNC clients
                  sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvnclegacy -vnclegacy yes 

                  # VNC password - http://hints.macworld.com/article.php?story=20071103011608872
                  echo "6MonkeysRLooking^" | perl -we 'BEGIN { @k = unpack "C*", pack "H*", "1734516E8BA8C5E2FF1C39567390ADCA"}; $_ = <>; chomp; s/^(.{8}).*/$1/; @p = unpack "C*", $_; foreach (@k) { printf "%02X", $_ ^ (shift @p || 0) }; print "\n"' | sudo tee /Library/Preferences/com.apple.VNCSettings.txt

                  # Start VNC/reset changes
                  sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -restart -agent -console
                  sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate
                  # This actually won't work. VNC client only shows black screen
                  # Screen recording might be disabled. Screen Sharing or Remote Management must be enabled from System Preferences or via MDM.
                  # Screen control might be disabled. Screen Sharing or Remote Management must be enabled from System Preferences or via MDM.

            - name: Tailscale
              uses: tailscale/github-action@v3
              with:
                  oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
                  oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
                  tags: tag:ci
                  # Tailscale SSH feature does not need openssh-server or user password, it's controlled by ACL
                  args: --advertise-exit-node --ssh
                  hostname: gha-macos-sandbox
                  version: latest

            # Should be runner
            - name: whoami
              run: whoami

            # Each job in a workflow can run for up to 6 hours of execution time.
            # If a job reaches this limit, the job is terminated and fails.
            - name: Sleep
              run: |
                  echo -e "#!/bin/bash\n\ntouch /tmp/stop_sleeping_step_confirmed" | sudo tee /Users/altrunner/shutdown_confirmed.sh
                  sudo chmod +x /Users/altrunner/shutdown_confirmed.sh
                  echo "Sleeping..."
                  while [ ! -e /tmp/stop_sleeping_step_confirmed ]; do
                      sleep 5
                  done
除非另有说明,此内容使用 CC BY-SA 4.0 许可。
最后更新于 2025-09-21 12:32:30
此处获取此页源码。
提交: 81240ebc 环境: production Hugo: 0.151.0 主题: 3.31.0-modified 时间: 1760521115101600 Cloudflare: Unknown
本博客内容仅供参考,作者不对其准确性、完整性或适用性作出任何明示或暗示的保证。因使用、引用或解读本博客内容所引发的任何直接或间接后果,作者概不承担任何责任。
本博客可能包含第三方转载内容,相关版权归原作者所有。转载内容仅为分享信息之目的,不代表作者观点。如涉及侵权,请联系删除。
使用 Hugo 构建
主题 StackJimmy 设计