actions/runner
概要
actions/runner: The Runner for GitHub Actions のコードを読んでみます。
普通に使う場合は 自己ホストランナーの追加 - GitHub Docs に手順があります。
動かす
まずは動かしてみる。
ソースからビルド
runner/contribute.md at main · actions/runner
git clone https://github.com/actions/runner
cd runner
cd ./src
./dev.cmd layout
./dev.cmd build
./dev.cmd test
runner
配下に以下のディレクトリが作成される。
_layout
が本体。
_dotnetsdk/
_downloads/
_layout/
起動
リポジトリの [Settings] > [Actions] > [Add runner] > [Configure] に表示されるコマンドを実行する。
cd runner/_layout/
./config.cmd --url https://github.com/[USER_NAME]/[REPOSITORY_NAME] --token ***
./run.cmd
`config.cmd` を実行するときに色々聞かれるので入力する
> .\config.cmd --url https://github.com/SnowCait/sandbox --token ***
--------------------------------------------------------------------------------
| ____ _ _ _ _ _ _ _ _ |
| / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ |
| | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| |
| | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ |
| \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ |
| |
| Self-hosted runner registration |
| |
--------------------------------------------------------------------------------
# Authentication
√ Connected to GitHub
# Runner Registration
This runner will have the following labels: 'self-hosted', 'Windows', 'X64'
Enter any additional labels (ex. label-1,label-2): [press Enter to skip]
√ Runner successfully added
√ Runner connection is good
# Runner settings
Enter name of work folder: [press Enter for _work]
√ Settings Saved.
Would you like to run the runner as service? (Y/N) [press Enter for N]
ログ
セルフホストランナーのモニタリングとトラブルシューティング - GitHub Docs
_layout/_diag/
がログディレクトリ。
Runner_*
: アプリケーション (config.cmd
や run.cmd
) が起動される度に生成される。
Worker_*
: ジョブ毎に生成される。
ワークフロー
name: CI
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: [self-hosted, Windows]
defaults:
run:
shell: cmd # PowerShell は権限を変更する必要がある
steps:
- uses: actions/checkout@v2
- run: dir
ワークスペース
_diag/_work/[REPOSITORY_NAME]/[REPOSITORY_NAME]/
停止&解除
Ctrl + C で停止します。
リポジトリの登録を解除するには以下のコマンドを実行します。
token
は登録時と異なる解除用のもののようです。
./config.cmd remove --token ***
コードを読む
実行ファイルは config.cmd
と run.cmd
の 2 つ。
ビルドで生成されたコード
@echo off
rem ********************************************************************************
rem Unblock specific files.
rem ********************************************************************************
setlocal
if defined VERBOSE_ARG (
set VERBOSE_ARG='Continue'
) else (
set VERBOSE_ARG='SilentlyContinue'
)
rem Unblock files in the root of the layout folder. E.g. .cmd files.
powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$VerbosePreference = %VERBOSE_ARG% ; Get-ChildItem -LiteralPath '%~dp0' | ForEach-Object { Write-Verbose ('Unblock: {0}' -f $_.FullName) ; $_ } | Unblock-File | Out-Null"
if /i "%~1" equ "remove" (
rem ********************************************************************************
rem Unconfigure the runner.
rem ********************************************************************************
"%~dp0bin\Runner.Listener.exe" %*
) else (
rem ********************************************************************************
rem Configure the runner.
rem ********************************************************************************
"%~dp0bin\Runner.Listener.exe" configure %*
)
@echo off
rem ********************************************************************************
rem Unblock specific files.
rem ********************************************************************************
setlocal
if defined VERBOSE_ARG (
set VERBOSE_ARG='Continue'
) else (
set VERBOSE_ARG='SilentlyContinue'
)
rem Unblock files in the root of the layout folder. E.g. .cmd files.
powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$VerbosePreference = %VERBOSE_ARG% ; Get-ChildItem -LiteralPath '%~dp0' | ForEach-Object { Write-Verbose ('Unblock: {0}' -f $_.FullName) ; $_ } | Unblock-File | Out-Null"
if /i "%~1" equ "localRun" (
rem ********************************************************************************
rem Local run.
rem ********************************************************************************
"%~dp0bin\Runner.Listener.exe" %*
) else (
rem ********************************************************************************
rem Run.
rem ********************************************************************************
"%~dp0bin\Runner.Listener.exe" run %*
rem Return code 4 means the run once runner received an update message.
rem Sleep 5 seconds to wait for the update process finish and run the runner again.
if ERRORLEVEL 4 (
timeout /t 5 /nobreak > NUL
"%~dp0bin\Runner.Listener.exe" run %*
)
)
config.cmd
Runner.Listener.exe
が本体のようです。
runner/src/Runner.Listener の Program.cs から読んでいきましょう。
Program.Main
namespace GitHub.Runner.Listener
{
public static class Program
{
public static int Main(string[] args)
{
// Add environment variables from .env file
LoadAndSetEnv();
using (HostContext context = new HostContext("Runner"))
{
return MainAsync(context, args).GetAwaiter().GetResult();
}
}
}
}
.env
ファイルはないので LoadAndSetEnv()
は無視します。
Program.MainAsync
MainAsync へ。
trace.Info()
で Runner_*
へログを出力しているようです。
Tracing trace = context.GetTrace(nameof(GitHub.Runner.Listener));
trace.Info($"Runner is built for {Constants.Runner.Platform} ({Constants.Runner.PlatformArchitecture}) - {BuildConstants.RunnerPackage.PackageName}.");
コマンドライン引数を受け取ります。
url
と token
が渡されているはずです。
// Parse the command line args.
var command = new CommandSettings(context, args);
おそらくコアクラスであろう Runner を実行します。
実態は Runner.cs でしょうか。
// Defer to the Runner class to execute the command.
IRunner runner = context.GetService<IRunner>();
try
{
var returnCode = await runner.ExecuteCommand(command);
trace.Info($"Runner execution has finished with return code {returnCode}");
return returnCode;
}