mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
8 Commits
users/tihu
...
chore/npm-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e75a97dba4 | ||
|
|
bca18f71d0 | ||
|
|
1b8efb99f6 | ||
|
|
0b2c71fc31 | ||
|
|
60af948051 | ||
|
|
ff775ca101 | ||
|
|
f74be39e77 | ||
|
|
1eb15f28a7 |
@@ -4,7 +4,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
||||
"ghcr.io/devcontainers/features/dotnet": {
|
||||
"version": "8.0.413"
|
||||
"version": "8.0.415"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "20"
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 🛑 Request a feature in the runner application
|
||||
url: https://github.com/orgs/community/discussions/categories/actions-and-packages
|
||||
about: If you have feature requests for GitHub Actions, please use the Actions and Packages section on the Github Product Feedback page.
|
||||
url: https://github.com/orgs/community/discussions/categories/actions
|
||||
about: If you have feature requests for GitHub Actions, please use the Actions section on the Github Product Feedback page.
|
||||
- name: ✅ Support for GitHub Actions
|
||||
url: https://github.community/c/code-to-cloud/52
|
||||
about: If you have questions about GitHub Actions or need support writing workflows, please ask in the GitHub Community Support forum.
|
||||
|
||||
2
.github/workflows/close-features-bot.yml
vendored
2
.github/workflows/close-features-bot.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
close-issue-message: "Thank you for your interest in the runner application and taking the time to provide your valuable feedback. We kindly ask you to redirect this feedback to the [GitHub Community Support Forum](https://github.com/orgs/community/discussions/categories/actions-and-packages) which our team actively monitors and would be a better place to start a discussion for new feature requests in GitHub Actions. For more information on this policy please [read our contribution guidelines](https://github.com/actions/runner#contribute). 😃"
|
||||
close-issue-message: "Thank you for your interest in the runner application and taking the time to provide your valuable feedback. We kindly ask you to redirect this feedback to the [GitHub Community Support Forum](https://github.com/orgs/community/discussions/categories/actions) which our team actively monitors and would be a better place to start a discussion for new feature requests in GitHub Actions. For more information on this policy please [read our contribution guidelines](https://github.com/actions/runner#contribute). 😃"
|
||||
exempt-issue-labels: "keep"
|
||||
stale-issue-label: "actions-feature"
|
||||
only-labels: "actions-feature"
|
||||
|
||||
2
.github/workflows/dependency-check.yml
vendored
2
.github/workflows/dependency-check.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
|
||||
2
.github/workflows/npm-audit-typescript.yml
vendored
2
.github/workflows/npm-audit-typescript.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
- name: NPM install and audit fix with TypeScript auto-repair
|
||||
|
||||
2
.github/workflows/npm-audit.yml
vendored
2
.github/workflows/npm-audit.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
|
||||
@@ -1,20 +1,43 @@
|
||||
## What's Changed
|
||||
* Update Docker to v28.3.2 and Buildx to v0.26.1 by @github-actions[bot] in https://github.com/actions/runner/pull/3953
|
||||
* Fix if statement structure in update script and variable reference by @salmanmkc in https://github.com/actions/runner/pull/3956
|
||||
* Add V2 flow for runner deletion by @Samirat in https://github.com/actions/runner/pull/3954
|
||||
* Node 20 -> Node 24 migration feature flagging, opt-in and opt-out environment variables by @salmanmkc in https://github.com/actions/runner/pull/3948
|
||||
* Update Node20 and Node24 to latest by @djs-intel in https://github.com/actions/runner/pull/3972
|
||||
* Redirect supported OS doc section to current public Docs location by @corycalahan in https://github.com/actions/runner/pull/3979
|
||||
* Bump Microsoft.NET.Test.Sdk from 17.13.0 to 17.14.1 by @dependabot[bot] in https://github.com/actions/runner/pull/3975
|
||||
* Bump Azure.Storage.Blobs from 12.24.0 to 12.25.0 by @dependabot[bot] in https://github.com/actions/runner/pull/3974
|
||||
* Bump actions/download-artifact from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/3973
|
||||
* Bump actions/checkout from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/3982
|
||||
* Update safe_sleep.sh for bug when scheduler is paused for more than 1 second by @horner in https://github.com/actions/runner/pull/3157
|
||||
* Acknowledge runner request by @ericsciple in https://github.com/actions/runner/pull/3996
|
||||
* Update Docker to v28.3.3 and Buildx to v0.27.0 by @github-actions[bot] in https://github.com/actions/runner/pull/3999
|
||||
* Update dotnet sdk to latest version @8.0.413 by @github-actions[bot] in https://github.com/actions/runner/pull/4000
|
||||
* Bump actions/attest-build-provenance from 2 to 3 by @dependabot[bot] in https://github.com/actions/runner/pull/4002
|
||||
* Bump @typescript-eslint/eslint-plugin from 6.7.2 to 8.35.0 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3920
|
||||
* Bump husky from 8.0.3 to 9.1.7 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3842
|
||||
* Bump @vercel/ncc from 0.38.0 to 0.38.3 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3841
|
||||
* Bump eslint-plugin-github from 4.10.0 to 4.10.2 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/3180
|
||||
* Bump typescript from 5.2.2 to 5.9.2 in /src/Misc/expressionFunc/hashFiles by @dependabot[bot] in https://github.com/actions/runner/pull/4007
|
||||
* chore: migrate Husky config from v8 to v9 format by @salmanmkc in https://github.com/actions/runner/pull/4003
|
||||
* Map RUNNER_TEMP for container action by @ericsciple in https://github.com/actions/runner/pull/4011
|
||||
* Break UseV2Flow into UseV2Flow and UseRunnerAdminFlow. by @TingluoHuang in https://github.com/actions/runner/pull/4013
|
||||
* Update Docker to v28.4.0 and Buildx to v0.28.0 by @github-actions[bot] in https://github.com/actions/runner/pull/4020
|
||||
* Bump node.js to latest version in runner. by @TingluoHuang in https://github.com/actions/runner/pull/4022
|
||||
* feat: add automated .NET dependency management workflow by @salmanmkc in https://github.com/actions/runner/pull/4028
|
||||
* feat: add automated Docker BuildX dependency management workflow by @salmanmkc in https://github.com/actions/runner/pull/4029
|
||||
* feat: add automated Node.js version management workflow by @salmanmkc in https://github.com/actions/runner/pull/4026
|
||||
* feat: add comprehensive NPM security management workflow by @salmanmkc in https://github.com/actions/runner/pull/4027
|
||||
* feat: add comprehensive dependency monitoring system by @salmanmkc in https://github.com/actions/runner/pull/4025
|
||||
* Use BrokerURL when using RunnerAdmin by @luketomlinson in https://github.com/actions/runner/pull/4044
|
||||
* Bump actions/github-script from 7.0.1 to 8.0.0 by @dependabot[bot] in https://github.com/actions/runner/pull/4016
|
||||
* Bump actions/stale from 9 to 10 by @dependabot[bot] in https://github.com/actions/runner/pull/4015
|
||||
* fix: prevent Node.js upgrade workflow from creating PRs with empty versions by @salmanmkc in https://github.com/actions/runner/pull/4055
|
||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4057
|
||||
* Bump actions/setup-node from 4 to 5 by @dependabot[bot] in https://github.com/actions/runner/pull/4037
|
||||
* Bump Azure.Storage.Blobs from 12.25.0 to 12.25.1 by @dependabot[bot] in https://github.com/actions/runner/pull/4058
|
||||
* Update Docker to v28.5.0 and Buildx to v0.29.1 by @github-actions[bot] in https://github.com/actions/runner/pull/4069
|
||||
* Bump github/codeql-action from 3 to 4 by @dependabot[bot] in https://github.com/actions/runner/pull/4072
|
||||
* chore: update Node versions by @github-actions[bot] in https://github.com/actions/runner/pull/4075
|
||||
* Include k8s novolume (version v0.8.0) by @nikola-jokic in https://github.com/actions/runner/pull/4063
|
||||
* Make sure runner-admin has both auth_url and auth_url_v2. by @TingluoHuang in https://github.com/actions/runner/pull/4066
|
||||
* Report job has infra failure to run-service by @TingluoHuang in https://github.com/actions/runner/pull/4073
|
||||
* Bump actions/setup-node from 5 to 6 by @dependabot[bot] in https://github.com/actions/runner/pull/4078
|
||||
|
||||
## New Contributors
|
||||
* @Samirat made their first contribution in https://github.com/actions/runner/pull/3954
|
||||
* @djs-intel made their first contribution in https://github.com/actions/runner/pull/3972
|
||||
* @horner made their first contribution in https://github.com/actions/runner/pull/3157
|
||||
|
||||
**Full Changelog**: https://github.com/actions/runner/compare/v2.327.1...v2.328.0
|
||||
**Full Changelog**: https://github.com/actions/runner/compare/v2.328.0...v2.329.0
|
||||
|
||||
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
||||
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
||||
|
||||
13
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
13
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
@@ -1815,10 +1815,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-github/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -5904,9 +5905,9 @@
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using GitHub.Runner.Sdk;
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using GitHub.Runner.Sdk;
|
||||
|
||||
namespace GitHub.Runner.Common
|
||||
{
|
||||
@@ -64,8 +64,20 @@ namespace GitHub.Runner.Common
|
||||
{
|
||||
get
|
||||
{
|
||||
// Old runners do not have this property. Hosted runners likely don't have this property either.
|
||||
return _isHostedServer ?? true;
|
||||
// If the value has been explicitly set, return it.
|
||||
if (_isHostedServer.HasValue)
|
||||
{
|
||||
return _isHostedServer.Value;
|
||||
}
|
||||
|
||||
// Otherwise, try to infer it from the GitHubUrl.
|
||||
if (!string.IsNullOrEmpty(GitHubUrl))
|
||||
{
|
||||
return UrlUtil.IsHostedServer(new UriBuilder(GitHubUrl));
|
||||
}
|
||||
|
||||
// Default to true since Hosted runners likely don't have this property set.
|
||||
return true;
|
||||
}
|
||||
|
||||
set
|
||||
|
||||
@@ -170,6 +170,8 @@ namespace GitHub.Runner.Common
|
||||
public static readonly string AddCheckRunIdToJobContext = "actions_add_check_run_id_to_job_context";
|
||||
public static readonly string DisplayHelpfulActionsDownloadErrors = "actions_display_helpful_actions_download_errors";
|
||||
public static readonly string ContainerActionRunnerTemp = "actions_container_action_runner_temp";
|
||||
public static readonly string SnapshotPreflightHostedRunnerCheck = "actions_snapshot_preflight_hosted_runner_check";
|
||||
public static readonly string SnapshotPreflightImageGenPoolCheck = "actions_snapshot_preflight_image_gen_pool_check";
|
||||
}
|
||||
|
||||
// Node version migration related constants
|
||||
|
||||
@@ -5,8 +5,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -406,12 +406,12 @@ namespace GitHub.Runner.Listener
|
||||
try
|
||||
{
|
||||
Trace.Info(nameof(RunAsync));
|
||||
|
||||
|
||||
// First try using migrated settings if available
|
||||
var configManager = HostContext.GetService<IConfigurationManager>();
|
||||
RunnerSettings migratedSettings = null;
|
||||
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
migratedSettings = configManager.LoadMigratedSettings();
|
||||
Trace.Info("Loaded migrated settings from .runner_migrated file");
|
||||
@@ -422,15 +422,15 @@ namespace GitHub.Runner.Listener
|
||||
// If migrated settings file doesn't exist or can't be loaded, we'll use the provided settings
|
||||
Trace.Info($"Failed to load migrated settings: {ex.Message}");
|
||||
}
|
||||
|
||||
|
||||
bool usedMigratedSettings = false;
|
||||
|
||||
|
||||
if (migratedSettings != null)
|
||||
{
|
||||
// Try to create session with migrated settings first
|
||||
Trace.Info("Attempting to create session using migrated settings");
|
||||
_listener = GetMessageListener(migratedSettings, isMigratedSettings: true);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
CreateSessionResult createSessionResult = await _listener.CreateSessionAsync(HostContext.RunnerShutdownToken);
|
||||
@@ -450,7 +450,7 @@ namespace GitHub.Runner.Listener
|
||||
Trace.Error($"Exception when creating session with migrated settings: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If migrated settings weren't used or session creation failed, use original settings
|
||||
if (!usedMigratedSettings)
|
||||
{
|
||||
@@ -503,7 +503,7 @@ namespace GitHub.Runner.Listener
|
||||
restartSession = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
TaskAgentMessage message = null;
|
||||
bool skipMessageDeletion = false;
|
||||
try
|
||||
@@ -653,32 +653,6 @@ namespace GitHub.Runner.Listener
|
||||
}
|
||||
else
|
||||
{
|
||||
var credMgrTmp = HostContext.GetService<ICredentialManager>();
|
||||
var authV2Cred = credMgrTmp.LoadCredentials(allowAuthUrlV2: true);
|
||||
if (authV2Cred.Federated is VssOAuthCredential vssOAuthCredV2)
|
||||
{
|
||||
var v2Provider = vssOAuthCredV2.GetTokenProvider(vssOAuthCredV2.AuthorizationUrl);
|
||||
var v2Token = await v2Provider.GetTokenAsync(null, CancellationToken.None);
|
||||
if (v2Token is VssOAuthAccessToken v2AccessToken)
|
||||
{
|
||||
Trace.Info($"V2 access token {v2AccessToken.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
var runnerRefreshConfigMessage = new RunnerRefreshConfigMessage("E_kgDNDTw/O_kgDOBAN4Bg/self-hosted/65", "credentials", "pipelines", "refresh_url");
|
||||
// var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
|
||||
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
|
||||
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
|
||||
await configUpdater.UpdateRunnerConfigAsync(
|
||||
runnerQualifiedId: runnerRefreshConfigMessage.RunnerQualifiedId,
|
||||
configType: runnerRefreshConfigMessage.ConfigType,
|
||||
serviceType: runnerRefreshConfigMessage.ServiceType,
|
||||
configRefreshUrl: runnerRefreshConfigMessage.ConfigRefreshUrl);
|
||||
|
||||
Trace.Info("Runner configuration was updated. Continue to process job request message.");
|
||||
|
||||
await Task.Delay(-1, cancellationToken: messageQueueLoopTokenSource.Token);
|
||||
|
||||
var messageRef = StringUtil.ConvertFromJson<RunnerJobRequestRef>(message.Body);
|
||||
|
||||
// Acknowledge (best-effort)
|
||||
@@ -781,8 +755,7 @@ namespace GitHub.Runner.Listener
|
||||
}
|
||||
else if (string.Equals(message.MessageType, RunnerRefreshConfigMessage.MessageType))
|
||||
{
|
||||
var runnerRefreshConfigMessage = new RunnerRefreshConfigMessage("E_kgDNDTw/O_kgDOBAN4Bg/self-hosted/64", "credentials", "pipelines", "refresh_url");
|
||||
// var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
|
||||
var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
|
||||
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
|
||||
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
|
||||
await configUpdater.UpdateRunnerConfigAsync(
|
||||
@@ -886,7 +859,7 @@ namespace GitHub.Runner.Listener
|
||||
{
|
||||
restart = false;
|
||||
returnCode = await RunAsync(settings, runOnce);
|
||||
|
||||
|
||||
if (returnCode == Constants.Runner.ReturnCode.RunnerConfigurationRefreshed)
|
||||
{
|
||||
Trace.Info("Runner configuration was refreshed, restarting session...");
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace GitHub.Runner.Listener
|
||||
Trace.Entering();
|
||||
Trace.Info($"Verifying runner qualified id: {runnerQualifiedId}");
|
||||
var idParts = runnerQualifiedId.Split("/", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (idParts.Length != 4)
|
||||
if (idParts.Length != 4 || idParts[3] != _settings.AgentId.ToString())
|
||||
{
|
||||
Trace.Error($"Runner qualified id '{runnerQualifiedId}' does not match the current runner '{_settings.AgentId}'.");
|
||||
await ReportTelemetryAsync($"Runner qualified id '{runnerQualifiedId}' does not match the current runner '{_settings.AgentId}'.");
|
||||
|
||||
@@ -400,6 +400,10 @@ namespace GitHub.Runner.Worker
|
||||
if (snapshotRequest != null)
|
||||
{
|
||||
var snapshotOperationProvider = HostContext.GetService<ISnapshotOperationProvider>();
|
||||
// Check that that runner is capable of taking a snapshot
|
||||
snapshotOperationProvider.RunSnapshotPreflightChecks(context);
|
||||
|
||||
// Add postjob step to write snapshot file
|
||||
jobContext.RegisterPostJobStep(new JobExtensionRunner(
|
||||
runAsync: (executionContext, _) => snapshotOperationProvider.CreateSnapshotRequestAsync(executionContext, snapshotRequest),
|
||||
condition: snapshotRequest.Condition,
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Runner.Worker.Handlers;
|
||||
namespace GitHub.Runner.Worker;
|
||||
|
||||
[ServiceLocator(Default = typeof(SnapshotOperationProvider))]
|
||||
public interface ISnapshotOperationProvider : IRunnerService
|
||||
{
|
||||
Task CreateSnapshotRequestAsync(IExecutionContext executionContext, Snapshot snapshotRequest);
|
||||
void RunSnapshotPreflightChecks(IExecutionContext jobContext);
|
||||
}
|
||||
|
||||
public class SnapshotOperationProvider : RunnerService, ISnapshotOperationProvider
|
||||
@@ -24,9 +28,32 @@ public class SnapshotOperationProvider : RunnerService, ISnapshotOperationProvid
|
||||
}
|
||||
|
||||
IOUtil.SaveObject(snapshotRequest, snapshotRequestFilePath);
|
||||
executionContext.Output($"Image Name: {snapshotRequest.ImageName} Version: {snapshotRequest.Version}");
|
||||
executionContext.Output($"Request written to: {snapshotRequestFilePath}");
|
||||
executionContext.Output("This request will be processed after the job completes. You will not receive any feedback on the snapshot process within the workflow logs of this job.");
|
||||
executionContext.Output("If the snapshot process is successful, you should see a new image with the requested name in the list of available custom images when creating a new GitHub-hosted Runner.");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void RunSnapshotPreflightChecks(IExecutionContext context)
|
||||
{
|
||||
var shouldCheckRunnerEnvironment = context.Global.Variables.GetBoolean(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck) ?? false;
|
||||
if (shouldCheckRunnerEnvironment &&
|
||||
context.Global.Variables.TryGetValue(WellKnownDistributedTaskVariables.RunnerEnvironment, out var runnerEnvironment) &&
|
||||
!string.IsNullOrEmpty(runnerEnvironment))
|
||||
{
|
||||
context.Debug($"Snapshot: RUNNER_ENVIRONMENT={runnerEnvironment}");
|
||||
if (!string.Equals(runnerEnvironment, "github-hosted", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Snapshot workflows must be run on a GitHub Hosted Runner");
|
||||
}
|
||||
}
|
||||
var imageGenEnabled = StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED"));
|
||||
context.Debug($"Snapshot: GITHUB_ACTIONS_IMAGE_GEN_ENABLED={imageGenEnabled}");
|
||||
var shouldCheckImageGenPool = context.Global.Variables.GetBoolean(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck) ?? false;
|
||||
if (shouldCheckImageGenPool && !imageGenEnabled)
|
||||
{
|
||||
throw new ArgumentException("Snapshot workflows must be run a hosted runner with Image Generation enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,5 +567,193 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_HostedRunnerCheck_Enabled_GitHubHosted_Success()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "github-hosted");
|
||||
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_HostedRunnerCheck_Enabled_SelfHosted_ThrowsException()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "self-hosted");
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run on a GitHub Hosted Runner", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGenEnabled_Success()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "true");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGen_False_ThrowsException()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "false");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
_jobEc.SetRunnerContext("environment", "github-hosted");
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run a hosted runner with Image Generation enabled", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_ImageGenPoolCheck_Enabled_ImageGen_Missing_ThrowsException()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ArgumentException>(() => jobExtension.InitializeJob(_jobEc, _message));
|
||||
Assert.Contains("Snapshot workflows must be run a hosted runner with Image Generation enabled", exception.Message);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task SnapshotPreflightChecks_BothChecks_Enabled_AllConditionsMet_Success()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", "true");
|
||||
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
hc.SetSingleton<ISnapshotOperationProvider>(new SnapshotOperationProvider());
|
||||
|
||||
var jobExtension = new JobExtension();
|
||||
jobExtension.Initialize(hc);
|
||||
|
||||
// Enable both preflight checks
|
||||
_jobEc.Global.Variables.Set(WellKnownDistributedTaskVariables.RunnerEnvironment, "github-hosted");
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightHostedRunnerCheck, "true");
|
||||
_jobEc.Global.Variables.Set(Constants.Runner.Features.SnapshotPreflightImageGenPoolCheck, "true");
|
||||
|
||||
var snapshot = new Pipelines.Snapshot("TestImageNameForPreflightCheck");
|
||||
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||
_message.Snapshot = imageNameValueStringToken;
|
||||
|
||||
_actionManager.Setup(x => x.PrepareActionsAsync(It.IsAny<IExecutionContext>(), It.IsAny<IEnumerable<Pipelines.JobStep>>(), It.IsAny<Guid>()))
|
||||
.Returns(Task.FromResult(new PrepareResult(new List<JobExtensionRunner>(), new Dictionary<Guid, IActionRunner>())));
|
||||
|
||||
await jobExtension.InitializeJob(_jobEc, _message);
|
||||
|
||||
var postJobSteps = _jobEc.PostJobSteps;
|
||||
Assert.Equal(1, postJobSteps.Count);
|
||||
}
|
||||
|
||||
Environment.SetEnvironmentVariable("RUNNER_ENVIRONMENT", null);
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_IMAGE_GEN_ENABLED", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public class SnapshotOperationProviderL0
|
||||
Assert.NotNull(actualSnapshot);
|
||||
Assert.Equal(expectedSnapshot.ImageName, actualSnapshot!.ImageName);
|
||||
_ec.Verify(ec => ec.Write(null, $"Request written to: {_snapshotRequestFilePath}"), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, $"Image Name: {expectedSnapshot.ImageName} Version: {expectedSnapshot.Version}"), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, "This request will be processed after the job completes. You will not receive any feedback on the snapshot process within the workflow logs of this job."), Times.Once);
|
||||
_ec.Verify(ec => ec.Write(null, "If the snapshot process is successful, you should see a new image with the requested name in the list of available custom images when creating a new GitHub-hosted Runner."), Times.Once);
|
||||
_ec.VerifyNoOtherCalls();
|
||||
|
||||
@@ -17,7 +17,7 @@ LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||
DOTNETSDK_VERSION="8.0.413"
|
||||
DOTNETSDK_VERSION="8.0.415"
|
||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||
RUNNER_VERSION=$(cat runnerversion)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.413"
|
||||
"version": "8.0.415"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.328.0
|
||||
2.329.0
|
||||
|
||||
Reference in New Issue
Block a user