Skip to content

Fix CI failures in dependency PRs + apply all pending dependency upgrades#4393

Open
Copilot wants to merge 4 commits intomainfrom
copilot/fix-ci-issues-and-upgrade-dependencies
Open

Fix CI failures in dependency PRs + apply all pending dependency upgrades#4393
Copilot wants to merge 4 commits intomainfrom
copilot/fix-ci-issues-and-upgrade-dependencies

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

Six RunnerL0 tests were failing on GitHub-hosted runners because PR #4233 added ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED env var support, which is set in the hosted CI environment and silently changes runOnce=true for all tests.

Test fixes (RunnerL0.cs)

  • TestRunAsync: env var forced runOnce=true but RunOnceJobCompleted was never mocked → NullReferenceException. Fixed by clearing the env var at test start so non-ephemeral behavior is environment-independent.
  • 5 run-once tests (TestRunOnce, TestRunOnceOnlyTakeOneJobMessage, TestRunnerJobRequestMessageFromPipeline, TestRunnerJobRequestMessageFromRunService, TestRunnerJobRequestMessageFromRunService_AuthMigrationFallback): when env var is set, return code is TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded) (100) not 0. Updated assertions to accept both.

Dependency upgrades (consolidates PRs #4363, #4364, #4369, #4375, #4376, #4381, #4382)

Package From To
System.Security.Cryptography.Pkcs 10.0.6 10.0.7
System.Formats.Asn1 10.0.6 10.0.7
System.Security.Cryptography.ProtectedData 10.0.3 10.0.6
System.Text.Encoding.CodePages 10.0.3 10.0.6
System.ServiceProcess.ServiceController 10.0.3 10.0.7
Microsoft.DevTunnels.Connections 1.3.39 1.3.43
@typescript-eslint/eslint-plugin ^8.59.0 ^8.59.1
@typescript-eslint/parser ^8.59.0 ^8.59.1

ProtectedData and CodePages are bumped across all referencing projects to avoid NU1605 package downgrade errors (transitive constraint from Sdk.csproj / Runner.Sdk.csproj).

Pre-existing hashFiles tooling fixes

  • .eslintrc.json: @stylistic/func-call-spacing@stylistic/function-call-spacing (rule renamed in @stylistic/eslint-plugin v5)
  • tsconfig.json: added "types": ["node"] required by TypeScript 6

- Fix 6 failing RunnerL0 tests caused by ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED
  env var being set on GitHub-hosted runners (introduced by PR #4233):
  - TestRunAsync: clear env var so non-ephemeral test runs with runOnce=false
  - 5 run-once tests: accept both return code 0 and 100 (TaskResult.Succeeded)
- Bump System.Security.Cryptography.Pkcs 10.0.6->10.0.7 (PR #4369)
- Bump System.Formats.Asn1 10.0.6->10.0.7 (PR #4369)
- Bump System.Security.Cryptography.ProtectedData 10.0.3->10.0.6 (PRs #4363)
- Bump System.Text.Encoding.CodePages 10.0.3->10.0.6 (PR #4364)
- Bump System.ServiceProcess.ServiceController 10.0.3->10.0.7 (PR #4376)
- Bump Microsoft.DevTunnels.Connections 1.3.39->1.3.43 (PR #4375)
- Bump @typescript-eslint/eslint-plugin ^8.59.0->^8.59.1 (PR #4382)
- Bump @typescript-eslint/parser ^8.59.0->^8.59.1 (PR #4381)
- Fix @stylistic/func-call-spacing -> function-call-spacing in eslintrc
- Add types:[node] to tsconfig.json for TypeScript 6 compatibility

Agent-Logs-Url: https://github.com/actions/runner/sessions/4df39c13-5067-4ae3-bcbc-eacf08a30722
@salmanmkc salmanmkc marked this pull request as ready for review April 29, 2026 14:39
Copilot AI review requested due to automatic review settings April 29, 2026 14:40
@salmanmkc salmanmkc requested a review from a team as a code owner April 29, 2026 14:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to (1) make RunnerL0 tests resilient to GitHub-hosted runner environment defaults introduced by PR #4233, and (2) consolidate a batch of dependency/tooling upgrades (NuGet + the hashFiles TypeScript toolchain + regenerated layoutbin output).

Changes:

  • Update RunnerL0 tests to be less sensitive to ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED (clear it for a non-ephemeral test; relax several run-once return-code assertions).
  • Apply pending NuGet dependency bumps across multiple projects to resolve downgrades and keep versions aligned.
  • Update hashFiles tooling configuration (ESLint rule rename, TS node types) and refresh the generated layoutbin/hashFiles artifact.
Show a summary per file
File Description
src/Test/L0/Listener/RunnerL0.cs Adjusts tests to avoid hosted-env behavior changes impacting expectations (env var handling + return code assertions).
src/Sdk/Sdk.csproj Bumps crypto-related NuGet dependencies.
src/Runner.Worker/Runner.Worker.csproj Bumps ProtectedData, ServiceController, and DevTunnels packages.
src/Runner.Sdk/Runner.Sdk.csproj Bumps CodePages to avoid downgrades.
src/Runner.Listener/Runner.Listener.csproj Bumps ProtectedData.
src/Runner.Common/Runner.Common.csproj Bumps ProtectedData + CodePages to keep versions consistent.
src/Misc/layoutbin/hashFiles/index.js Regenerated bundled JS for the hashFiles tool.
src/Misc/expressionFunc/hashFiles/tsconfig.json Adds Node types for TS6 compatibility.
src/Misc/expressionFunc/hashFiles/package.json Bumps @typescript-eslint/* patch versions.
src/Misc/expressionFunc/hashFiles/package-lock.json Lockfile updates for the dependency bumps.
src/Misc/expressionFunc/hashFiles/.eslintrc.json Updates renamed stylistic rule.

Copilot's findings

Files not reviewed (1)
  • src/Misc/expressionFunc/hashFiles/package-lock.json: Language not supported
Comments suppressed due to low confidence (4)

src/Test/L0/Listener/RunnerL0.cs:452

  • This assertion now accepts either return code 0 or the hosted-only translated return code (e.g., 100). Since test parallelization is disabled for this test assembly, prefer making the test deterministic by explicitly setting/restoring ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED for this test and asserting a single expected return code (or having two explicit tests for the two env var states).
                    int returnCode = await runnerTask;
                    Assert.True(
                        returnCode == Constants.Runner.ReturnCode.Success || returnCode == TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded),
                        $"Expected return code {Constants.Runner.ReturnCode.Success} or {TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded)}, but got {returnCode}");

src/Test/L0/Listener/RunnerL0.cs:776

  • This assertion now accepts either return code 0 or the hosted-only translated return code (e.g., 100). To avoid masking regressions, consider explicitly controlling ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED within the test (save/restore) and asserting the single expected return code, or splitting into two explicit test cases for env var set vs unset.
                    int returnCode = await runnerTask;
                    Assert.True(
                        returnCode == Constants.Runner.ReturnCode.Success || returnCode == TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded),
                        $"Expected return code {Constants.Runner.ReturnCode.Success} or {TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded)}, but got {returnCode}");

src/Test/L0/Listener/RunnerL0.cs:880

  • This assertion now accepts either return code 0 or the hosted-only translated return code (e.g., 100). Since the env var is global state, it’s better for the test to set/restore ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED explicitly and assert the single expected value (or add a second test case for the hosted behavior) rather than allowing both.
                    int returnCode = await runnerTask;
                    Assert.True(
                        returnCode == Constants.Runner.ReturnCode.Success || returnCode == TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded),
                        $"Expected return code {Constants.Runner.ReturnCode.Success} or {TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded)}, but got {returnCode}");

src/Test/L0/Listener/RunnerL0.cs:1003

  • This assertion now accepts either return code 0 or the hosted-only translated return code (e.g., 100). To keep the test strict and environment-independent, explicitly set/restore ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED for this test and assert the single expected return code (or split into two explicit tests for the two env var states).
                    int returnCode = await runnerTask;
                    Assert.True(
                        returnCode == Constants.Runner.ReturnCode.Success || returnCode == TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded),
                        $"Expected return code {Constants.Runner.ReturnCode.Success} or {TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded)}, but got {returnCode}");
  • Files reviewed: 9/11 changed files
  • Comments generated: 3

Comment thread src/Misc/layoutbin/hashFiles/index.js Outdated
Comment on lines 144 to 145
module.exports = require("@actions/glob");

Comment thread src/Test/L0/Listener/RunnerL0.cs Outdated
Comment on lines +114 to +121
if (0 == messages.Count)
{
signalWorkerComplete.Release();
await Task.Delay(2000, hc.RunnerShutdownToken);
}

return messages.Dequeue();
});
Comment thread src/Test/L0/Listener/RunnerL0.cs Outdated
Comment on lines +340 to +345
int returnCode = await runnerTask;
// Accept Success (0) or TaskResult.Succeeded offset (100) - the latter occurs when
// ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED is set in the hosted runner environment.
Assert.True(
returnCode == Constants.Runner.ReturnCode.Success || returnCode == TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded),
$"Expected return code {Constants.Runner.ReturnCode.Success} or {TaskResultUtil.TranslateToReturnCode(TaskResult.Succeeded)}, but got {returnCode}");
Comment thread src/Test/L0/Listener/RunnerL0.cs Outdated
// regardless of the environment (e.g. ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED is set on
// GitHub-hosted runners which would otherwise force runOnce=true).
var savedEnvVar = Environment.GetEnvironmentVariable("ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED");
Environment.SetEnvironmentVariable("ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED", null);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot is there anyway we can unset the ENV for the entire test file?
so we don't have to change these many test code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes — done in fabb136. RunnerL0 now implements IDisposable: the constructor saves and clears ACTIONS_RUNNER_RETURN_JOB_RESULT_FOR_HOSTED, and Dispose() restores it. Since xUnit creates a fresh class instance per test, every test in the file automatically runs with the env var unset — no per-test changes needed. Reverted the per-test try/finally from TestRunAsync and the 5 run-once tests back to plain Assert.Equal(Constants.Runner.ReturnCode.Success, ...).

…lass level

Implement IDisposable on RunnerL0 to save/clear the env var in the
constructor and restore it in Dispose(). This means each xUnit test
instance (which gets its own RunnerL0 instance) automatically runs
with the env var unset, making all tests environment-independent.

Remove the per-test try/finally from TestRunAsync and revert the 5
run-once tests back to plain Assert.Equal(Success) assertions.

Agent-Logs-Url: https://github.com/actions/runner/sessions/210e24f3-d6ee-4270-81e5-34774fd75bc4

Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
@salmanmkc
Copy link
Copy Markdown
Contributor

@copilot check the copilot comments too

…sageAsync mock

- Restore src/Misc/layoutbin/hashFiles/index.js from commit b06c585 so
  @actions/glob is bundled inline by ncc rather than externalized. The
  previous regeneration was done without running npm install first, causing
  ncc to fall back to require("@actions/glob") which is not available at
  runtime.

- Fix flaky GetNextMessageAsync mock in TestRunAsync: after Task.Delay
  resolves (either by timeout or cancellation) return null when the queue
  is empty instead of calling Dequeue() on an empty queue which would
  throw InvalidOperationException.

Agent-Logs-Url: https://github.com/actions/runner/sessions/9ceb7e98-b518-4b84-b302-29b0ed28500b
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 29, 2026

@copilot check the copilot comments too

Both remaining Copilot comments addressed in 9825a12:

  1. index.js@actions/glob externalised: Restored the properly-bundled layoutbin/hashFiles/index.js from before my changes. The broken bundle was produced by running ncc build without npm install first; @actions/glob is now bundled inline again (5 400+ line bundle, Node.js built-ins only as externals).

  2. GetNextMessageAsync flaky dequeue: Added return null after await Task.Delay(…) so when the delay completes before the shutdown token fires the mock returns null instead of calling Dequeue() on an empty queue (InvalidOperationException).

Copilot AI requested a review from salmanmkc April 29, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants