Compare commits

..

5 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 81255a9ac1 Improve test robustness with path validation and named constant
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-02-09 02:47:23 +00:00
copilot-swe-agent[bot] 4b97e637f5 Address code review feedback: remove unused import and use named constants
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-02-09 02:33:53 +00:00
copilot-swe-agent[bot] 5ba673a014 Add test for work directory creation failure during runner startup
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-02-09 02:32:09 +00:00
copilot-swe-agent[bot] a4072e71ae Initial plan 2026-02-09 02:23:58 +00:00
Tingluo Huang 8936191513 Validate work dir during runner start up. 2026-02-08 20:39:08 -05:00
8 changed files with 3802 additions and 31379 deletions
+2 -2
View File
@@ -28,8 +28,8 @@ Debian based OS (Debian, Ubuntu, Linux Mint)
- liblttng-ust1 or liblttng-ust0
- libkrb5-3
- zlib1g
- libssl3t64, libssl3, libssl1.1, libssl1.0.2 or libssl1.0.0
- libicu76, libicu75, ..., libicu66, libicu65, libicu63, libicu60, libicu57, libicu55, or libicu52
- libssl1.1, libssl1.0.2 or libssl1.0.0
- libicu63, libicu60, libicu57 or libicu55
Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7)
+40 -68
View File
@@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@actions/glob": "^0.6.1"
"@actions/glob": "^0.4.0"
},
"devDependencies": {
"@stylistic/eslint-plugin": "^3.1.0",
@@ -36,45 +36,31 @@
}
},
"node_modules/@actions/core": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": {
"@actions/exec": "^3.0.0",
"@actions/http-client": "^4.0.0"
}
},
"node_modules/@actions/exec": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
"dependencies": {
"@actions/io": "^3.0.2"
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/glob": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.6.1.tgz",
"integrity": "sha512-K4+2Ac5ILcf2ySdJCha+Pop9NcKjxqCL4xL4zI50dgB2PbXgC0+AcP011xfH4Of6b4QEJJg8dyZYv7zl4byTsw==",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.4.0.tgz",
"integrity": "sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==",
"dependencies": {
"@actions/core": "^3.0.0",
"@actions/core": "^1.9.1",
"minimatch": "^3.0.4"
}
},
"node_modules/@actions/http-client": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
"dependencies": {
"tunnel": "^0.0.6",
"undici": "^6.23.0"
"tunnel": "^0.0.6"
}
},
"node_modules/@actions/io": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="
},
"node_modules/@babel/runtime": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
@@ -4480,14 +4466,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
"engines": {
"node": ">=18.17"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
@@ -4543,6 +4521,14 @@
"punycode": "^2.1.0"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -4693,45 +4679,31 @@
"dev": true
},
"@actions/core": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"requires": {
"@actions/exec": "^3.0.0",
"@actions/http-client": "^4.0.0"
}
},
"@actions/exec": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz",
"integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==",
"requires": {
"@actions/io": "^3.0.2"
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/glob": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.6.1.tgz",
"integrity": "sha512-K4+2Ac5ILcf2ySdJCha+Pop9NcKjxqCL4xL4zI50dgB2PbXgC0+AcP011xfH4Of6b4QEJJg8dyZYv7zl4byTsw==",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.4.0.tgz",
"integrity": "sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==",
"requires": {
"@actions/core": "^3.0.0",
"@actions/core": "^1.9.1",
"minimatch": "^3.0.4"
}
},
"@actions/http-client": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
"requires": {
"tunnel": "^0.0.6",
"undici": "^6.23.0"
"tunnel": "^0.0.6"
}
},
"@actions/io": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz",
"integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="
},
"@babel/runtime": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
@@ -7688,11 +7660,6 @@
"which-boxed-primitive": "^1.0.2"
}
},
"undici": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g=="
},
"undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
@@ -7724,6 +7691,11 @@
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -2,14 +2,13 @@
"name": "hashFiles",
"version": "1.0.0",
"description": "GitHub Actions HashFiles() expression function",
"type": "module",
"main": "lib/hashFiles.js",
"scripts": {
"build": "tsc",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"lint": "eslint src/**/*.ts",
"pack": "ncc build -o ../../layoutbin/hashFiles --target es2020",
"pack": "ncc build -o ../../layoutbin/hashFiles",
"all": "npm run format && npm run lint && npm run build && npm run pack",
"prepare": "cd ../../../../ && husky"
},
@@ -33,7 +32,7 @@
"author": "GitHub Actions",
"license": "MIT",
"dependencies": {
"@actions/glob": "^0.6.1"
"@actions/glob": "^0.4.0"
},
"devDependencies": {
"@stylistic/eslint-plugin": "^3.1.0",
@@ -1,8 +1,7 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"moduleResolution": "node",
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
{
"type": "module"
}
+1 -1
View File
@@ -102,7 +102,7 @@ then
exit 1
fi
apt_get_with_fallbacks libssl3t64$ libssl3$ libssl1.1$ libssl1.0.2$ libssl1.0.0$
apt_get_with_fallbacks libssl1.1$ libssl1.0.2$ libssl1.0.0$
if [ $? -ne 0 ]
then
echo "'$apt_get' failed with exit code '$?'"
+70
View File
@@ -1076,5 +1076,75 @@ namespace GitHub.Runner.Common.Tests.Listener
Assert.True(hc.AllowAuthMigration);
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Runner")]
public async Task RunCommand_ShouldReturnTerminatedError_WhenWorkDirCreationFails()
{
using (var hostCtx = new TestHostContext(this))
{
// Setup: arrange mocks and runner instance
var runnerInstance = new Runner.Listener.Runner();
hostCtx.SetSingleton<IConfigurationManager>(_configurationManager.Object);
hostCtx.SetSingleton<IJobNotification>(_jobNotification.Object);
hostCtx.SetSingleton<IMessageListener>(_messageListener.Object);
hostCtx.SetSingleton<IPromptManager>(_promptManager.Object);
hostCtx.SetSingleton<IConfigurationStore>(_configStore.Object);
hostCtx.SetSingleton<IRunnerServer>(_runnerServer.Object);
hostCtx.EnqueueInstance<IErrorThrottler>(_acquireJobThrottler.Object);
runnerInstance.Initialize(hostCtx);
// Create a file at the work directory path to block directory creation
string workPath = hostCtx.GetDirectory(WellKnownDirectory.Work);
// Clean up any existing directory first
if (Directory.Exists(workPath))
{
Directory.Delete(workPath, recursive: true);
}
// Place a file where the work directory should be - this blocks Directory.CreateDirectory
string parentPath = Path.GetDirectoryName(workPath);
Assert.NotNull(parentPath);
Assert.NotEmpty(parentPath);
Directory.CreateDirectory(parentPath);
const string blockingFileContent = "test file blocking directory creation";
File.WriteAllText(workPath, blockingFileContent);
const int testPoolId = 12345;
const int testAgentId = 67890;
var runnerConfig = new RunnerSettings
{
PoolId = testPoolId,
AgentId = testAgentId
};
_configurationManager.Setup(m => m.LoadSettings()).Returns(runnerConfig);
_configurationManager.Setup(m => m.IsConfigured()).Returns(true);
_configStore.Setup(m => m.IsServiceConfigured()).Returns(false);
try
{
// Execute: run the command which should fail during work dir validation
var cmd = new CommandSettings(hostCtx, new string[] { "run" });
int exitCode = await runnerInstance.ExecuteCommand(cmd);
// Verify: should return TerminatedError code when dir creation fails
Assert.Equal(Constants.Runner.ReturnCode.TerminatedError, exitCode);
}
finally
{
// Cleanup: remove the blocking file
if (File.Exists(workPath))
{
File.Delete(workPath);
}
}
}
}
}
}