Skip to content

Commit

Permalink
Allow net6.0 releases / Support single file deployment (#487)
Browse files Browse the repository at this point in the history
* allow .net6.0 releases

* support single file deployment e2e
  • Loading branch information
ChristopherHX authored Dec 22, 2024
1 parent 8723742 commit d92536b
Show file tree
Hide file tree
Showing 20 changed files with 269 additions and 88 deletions.
43 changes: 33 additions & 10 deletions src/Runner.Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,13 @@ private static async Task<int> CreateRunner(string binpath, Parameters parameter
#else
string ext = IOUtil.ExeExtension;
#endif
var runner = Path.Join(binpath, $"Runner.Listener{ext}");
var runner = string.IsNullOrWhiteSpace(binpath) ? Environment.ProcessPath : Path.Join(binpath, $"Runner.Listener{ext}");
var file = runner;
if(!string.IsNullOrWhiteSpace(binpath)) {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
file = dotnet;
file = dotnet;
#endif
}
var agentname = Path.GetRandomFileName();
string tmpdir = Path.Combine(Path.GetFullPath(parameters.RunnerDirectory), agentname);
Directory.CreateDirectory(tmpdir);
Expand Down Expand Up @@ -320,10 +322,12 @@ private static async Task<int> CreateRunner(string binpath, Parameters parameter
runnerEnv["RUNNER_CONTAINER_KEEP"] = "1";
}

var arguments = $"Configure --name {agentname} --unattended --url {parameters.Server}/runner/server --token {parameters.Token ?? "empty"} --labels container-host --work w";
var arguments = $"configure --name {agentname} --unattended --url {parameters.Server}/runner/server --token {parameters.Token ?? "empty"} --labels container-host --work w";
if(!string.IsNullOrWhiteSpace(binpath)) {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{runner}\" {arguments}";
arguments = $"\"{runner}\" {arguments}";
#endif
}

var code = await inv.ExecuteAsync(binpath, file, arguments, runnerEnv, true, null, true, CancellationTokenSource.CreateLinkedTokenSource(source.Token, new CancellationTokenSource(60 * 1000).Token).Token);
int execAttempt = 1;
Expand All @@ -348,10 +352,12 @@ private static async Task<int> CreateRunner(string binpath, Parameters parameter
if(source.IsCancellationRequested) {
return 1;
}
arguments = $"Run{(parameters.KeepContainer || parameters.NoReuse ? " --once" : "")}";
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{runner}\" {arguments}";
#endif
arguments = $"run{(parameters.KeepContainer || parameters.NoReuse ? " --once" : "")}";
if(!string.IsNullOrWhiteSpace(binpath)) {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{runner}\" {arguments}";
#endif
}
await runnerlistener.ExecuteAsync(binpath, file, arguments, runnerEnv, true, null, true, runToken.Token);
break;
}
Expand Down Expand Up @@ -553,13 +559,18 @@ private static async Task<int> CreateExternalRunner(string binpath, Parameters p
// Wrap listener to avoid that ctrl-c is sent to the runner
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
{
if(string.IsNullOrWhiteSpace(binpath)) {
arguments = $"spawn \"{file}\" {arguments}";
file = Environment.ProcessPath;
} else {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{Path.Join(binpath, "Runner.Client.dll")}\" spawn \"{file}\" {arguments}";
file = Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
#else
arguments = $"spawn \"{file}\" {arguments}";
file = Path.Join(binpath, $"Runner.Client{ext}");
arguments = $"spawn \"{file}\" {arguments}";
file = Path.Join(binpath, $"Runner.Client{ext}");
#endif
}
}
((Func<Task>)(async () =>
{
Expand Down Expand Up @@ -979,6 +990,18 @@ static int Main(string[] args)
Runner.Server.Program.Main(args.Skip(1).ToArray());
return 0;
}
if(args.Length > 0 && (args[0] == "configure" || args[0] == "run" || args[0] == "remove")) {
GitHub.Runner.Listener.Program.Main(args);
return 0;
}
if(args.Length > 0 && args[0] == "spawnclient") {
GitHub.Runner.Worker.Program.Main(args);
return 0;
}
if(args.Length > 0 && args[0] == "action") {
GitHub.Runner.PluginHost.Program.Main(args);
return 0;
}
if(System.OperatingSystem.IsWindowsVersionAtLeast(10)) {
WindowsUtils.EnableVT();
}
Expand Down
17 changes: 15 additions & 2 deletions src/Runner.Client/Runner.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
<PackAsTool>true</PackAsTool>
<PackageOutputPath>./nupkg</PackageOutputPath>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition="'$(RuntimeFrameworkVersion)' != '6.0.0'">net8.0</TargetFramework>
<TargetFramework Condition="'$(RuntimeFrameworkVersion)' == '6.0.0'">net6.0</TargetFramework>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<NoWarn>NU5118;NU5123;NU5119;NU1701;NU1603;CS4014</NoWarn>
<Authors>Christopher Homberger</Authors>
<PackageTags>GitHub Actions;GitHub Runner;Actions;Runner;Runner.Client;Runner.Server</PackageTags>
<Description>Unofficial GitHub Actions Runner Client, run your github action workflows locally. $(CHANGELOG_LINE)More Information https://github.com/ChristopherHX/runner.server.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/ChristopherHX/runner.server</PackageProjectUrl>
<!-- See https://github.com/dotnet/sdk/issues/18116#issuecomment-855266314 -->
<ValidateExecutableReferencesMatchSelfContained Condition="'$(RuntimeFrameworkVersion)' == '6.0.0'">false</ValidateExecutableReferencesMatchSelfContained>
</PropertyGroup>

<ItemGroup>
Expand All @@ -30,13 +33,23 @@
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition="'$(RuntimeFrameworkVersion)' != '6.0.0'">
<Content Include="..\Misc\layoutbin\**" PackagePath="tools\net8.0\any" >
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

</ItemGroup>

<ItemGroup Condition="'$(RuntimeFrameworkVersion)' == '6.0.0'">
<Content Include="..\Misc\layoutbin\**" PackagePath="tools\net6.0\any" >
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\Runner.Server\$(OutDir)\Runner.Server.deps.json" PackagePath="tools\net6.0\any" >
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sdk\Sdk.csproj" />
<ProjectReference Include="..\Runner.Server\Runner.Server.csproj" />
Expand Down
26 changes: 18 additions & 8 deletions src/Runner.Client/WrapProcService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,18 @@ public Task<int> ExecuteAsync(string workingDirectory, string fileName, string a
var binpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
fileName = Path.Join(_context.GetDirectory(WellKnownDirectory.ConfigRoot), "bin", $"{queue.Prefix}.Worker{queue.Suffix}");
arguments = i == -1 ? arguments : arguments.Substring(i);
if(string.IsNullOrWhiteSpace(binpath)) {
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Environment.ProcessPath;
} else {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{Path.Join(binpath, "Runner.Client.dll")}\" spawn \"{fileName}\" {arguments}";
fileName = Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
arguments = $"\"{Path.Join(binpath, "Runner.Client.dll")}\" spawn \"{fileName}\" {arguments}";
fileName = Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
#else
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Path.Join(binpath, $"Runner.Client{IOUtil.ExeExtension}");
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Path.Join(binpath, $"Runner.Client{IOUtil.ExeExtension}");
#endif
}
return org.ExecuteAsync(workingDirectory, fileName, arguments, environment, requireExitCodeZero, outputEncoding, killProcessOnCancel, redirectStandardIn, inheritConsoleHandler, keepStandardInOpen, highPriorityProcess, cancellationToken);
} else {
return org.ExecuteAsync(workingDirectory, Path.Join(_context.GetDirectory(WellKnownDirectory.ConfigRoot), "bin", $"{queue.Prefix}.Worker{queue.Suffix}"), i == -1 ? arguments : arguments.Substring(i), environment, requireExitCodeZero, outputEncoding, killProcessOnCancel, redirectStandardIn, inheritConsoleHandler, keepStandardInOpen, highPriorityProcess, cancellationToken);
Expand All @@ -92,13 +97,18 @@ public Task<int> ExecuteAsync(string workingDirectory, string fileName, string a
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
{
var binpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if(string.IsNullOrWhiteSpace(binpath)) {
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Environment.ProcessPath;
} else {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
arguments = $"\"{Path.Join(binpath, "Runner.Client.dll")}\" spawn \"{fileName}\" {arguments}";
fileName = Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
arguments = $"\"{Path.Join(binpath, "Runner.Client.dll")}\" spawn \"{fileName}\" {arguments}";
fileName = Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
#else
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Path.Join(binpath, $"Runner.Client{IOUtil.ExeExtension}");
arguments = $"spawn \"{fileName}\" {arguments}";
fileName = Path.Join(binpath, $"Runner.Client{IOUtil.ExeExtension}");
#endif
}
return org.ExecuteAsync(workingDirectory, fileName, arguments, new Dictionary<string, string>() { {"RUNNER_SERVER_CONFIG_ROOT", _context.GetDirectory(WellKnownDirectory.ConfigRoot)} }, requireExitCodeZero, outputEncoding, killProcessOnCancel, redirectStandardIn, inheritConsoleHandler, keepStandardInOpen, highPriorityProcess, cancellationToken);
}
return org.ExecuteAsync(workingDirectory, fileName, arguments, new Dictionary<string, string>() { {"RUNNER_SERVER_CONFIG_ROOT", _context.GetDirectory(WellKnownDirectory.ConfigRoot)} }, requireExitCodeZero, outputEncoding, killProcessOnCancel, redirectStandardIn, inheritConsoleHandler, keepStandardInOpen, highPriorityProcess, cancellationToken);
Expand Down
9 changes: 8 additions & 1 deletion src/Runner.Common/HostContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ public string GetDirectory(WellKnownDirectory directory)
{
case WellKnownDirectory.Bin:
path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
if(path == null) {
path = AppContext.BaseDirectory;
}
break;

case WellKnownDirectory.Diag:
Expand All @@ -304,7 +307,11 @@ public string GetDirectory(WellKnownDirectory directory)
break;

case WellKnownDirectory.Root:
path = new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin)).Parent.FullName;
if(string.IsNullOrWhiteSpace(Assembly.GetEntryAssembly().Location)) {
path = AppContext.BaseDirectory;
} else {
path = new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin)).Parent.FullName;
}
break;

case WellKnownDirectory.ConfigRoot:
Expand Down
12 changes: 11 additions & 1 deletion src/Runner.Common/Runner.Common.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition="'$(RuntimeFrameworkVersion)' != '6.0.0'">net8.0</TargetFramework>
<TargetFramework Condition="'$(RuntimeFrameworkVersion)' == '6.0.0'">net6.0</TargetFramework>
<OutputType>Library</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
Expand All @@ -18,11 +19,20 @@
<ItemGroup>
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup Condition="'$(RuntimeFrameworkVersion)' != '6.0.0'">
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="8.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
</ItemGroup>

<ItemGroup Condition="'$(RuntimeFrameworkVersion)' == '6.0.0'">
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="6.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugType>portable</DebugType>
</PropertyGroup>
Expand Down
29 changes: 16 additions & 13 deletions src/Runner.Listener/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
Expand Down Expand Up @@ -420,20 +421,22 @@ public async Task ConfigureAsync(CommandSettings command)
_term.WriteSuccessMessage("Settings Saved.");
_term.WriteLine();

if(System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) {
// config windows service
bool runAsService = command.GetRunAsService();
if (runAsService)
{
Trace.Info("Configuring to run the agent as service");
var serviceControlManager = HostContext.GetService<IWindowsServiceControlManager>();
serviceControlManager.ConfigureService(runnerSettings, command);
}
if(!string.IsNullOrWhiteSpace(Assembly.GetExecutingAssembly().Location)) {
if(System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) {
// config windows service
bool runAsService = command.GetRunAsService();
if (runAsService)
{
Trace.Info("Configuring to run the agent as service");
var serviceControlManager = HostContext.GetService<IWindowsServiceControlManager>();
serviceControlManager.ConfigureService(runnerSettings, command);
}

} else if(System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux) || System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) {
// generate service config script for OSX and Linux, GenerateScripts() will no-opt on windows.
var serviceControlManager = HostContext.GetService<ILinuxServiceControlManager>();
serviceControlManager.GenerateScripts(runnerSettings);
} else if(System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux) || System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) {
// generate service config script for OSX and Linux, GenerateScripts() will no-opt on windows.
var serviceControlManager = HostContext.GetService<ILinuxServiceControlManager>();
serviceControlManager.GenerateScripts(runnerSettings);
}
}
}

Expand Down
21 changes: 14 additions & 7 deletions src/Runner.Listener/JobDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
Expand Down Expand Up @@ -465,18 +466,24 @@ private async Task RunAsync(Pipelines.AgentJobRequestMessage message, string orc
// Start the child process.
HostContext.WritePerfCounter("StartingWorkerProcess");
var assemblyDirectory = HostContext.GetDirectory(WellKnownDirectory.Bin);
var binpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string arguments = "spawnclient " + pipeHandleOut + " " + pipeHandleIn;
string workerFileName;
if(string.IsNullOrWhiteSpace(binpath)) {
workerFileName = Environment.ProcessPath;
} else {
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
string ext = ".dll";
string ext = ".dll";
#else
string ext = IOUtil.ExeExtension;
string ext = IOUtil.ExeExtension;
#endif
string workerFileName = Path.Combine(assemblyDirectory, $"{_workerProcessName}{ext}");
string arguments = "spawnclient " + pipeHandleOut + " " + pipeHandleIn;
workerFileName = Path.Combine(assemblyDirectory, $"{_workerProcessName}{ext}");
#if !OS_LINUX && !OS_WINDOWS && !OS_OSX && !X64 && !X86 && !ARM && !ARM64
var dotnet = global::Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
arguments = $"\"{workerFileName}\" {arguments}";
workerFileName = dotnet;
var dotnet = global::Sdk.Utils.DotNetMuxer.MuxerPath ?? WhichUtil.Which("dotnet", true);
arguments = $"\"{workerFileName}\" {arguments}";
workerFileName = dotnet;
#endif
}
workerProcessTask = processInvoker.ExecuteAsync(
workingDirectory: assemblyDirectory,
fileName: workerFileName,
Expand Down
Loading

0 comments on commit d92536b

Please sign in to comment.