refactor: extract working-directory validation into testable module

- Add src/working-directory.ts with validateWorkingDirectory()
- Add __test__/working-directory.test.ts with 4 test cases
- Update main.ts to use validation function
- Throw clear error for non-existent or non-directory paths
- Rebuild dist/index.js

Addresses review feedback on #426
This commit is contained in:
mehmet turac 2026-05-11 10:58:39 +03:00
parent 5ac99427a6
commit 7b9b30a1ea
No known key found for this signature in database
GPG key ID: 20D5F9AEE1833B0F
4 changed files with 99 additions and 4 deletions

View file

@ -0,0 +1,43 @@
import * as fs from 'fs'
import * as os from 'os'
import * as path from 'path'
import {validateWorkingDirectory} from '../src/working-directory'
describe('validateWorkingDirectory', () => {
let tmpDir: string
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'github-script-test-'))
})
afterEach(() => {
fs.rmSync(tmpDir, {recursive: true, force: true})
})
test('returns resolved path for existing directory', () => {
const result = validateWorkingDirectory(tmpDir)
expect(result).toBe(tmpDir)
})
test('resolves relative paths', () => {
const result = validateWorkingDirectory(tmpDir)
expect(path.isAbsolute(result)).toBe(true)
})
test('throws for non-existent directory', () => {
const nonExistent = path.join(tmpDir, 'does-not-exist')
expect(() => validateWorkingDirectory(nonExistent)).toThrow(
/does not exist/
)
expect(() => validateWorkingDirectory(nonExistent)).toThrow(nonExistent)
})
test('throws for file path instead of directory', () => {
const filePath = path.join(tmpDir, 'file.txt')
fs.writeFileSync(filePath, 'content')
expect(() => validateWorkingDirectory(filePath)).toThrow(
/is not a directory/
)
expect(() => validateWorkingDirectory(filePath)).toThrow(filePath)
})
})

27
dist/index.js vendored
View file

@ -65029,6 +65029,27 @@ function parseNumberArray(listString) {
// EXTERNAL MODULE: external "path"
var external_path_ = __nccwpck_require__(1017);
;// CONCATENATED MODULE: ./src/working-directory.ts
/**
* Validates that the given directory exists and is accessible.
* @param workingDirectory - The directory path to validate
* @returns The resolved absolute path
* @throws Error if the directory does not exist or is not a directory
*/
function validateWorkingDirectory(workingDirectory) {
const resolved = external_path_.resolve(workingDirectory);
if (!external_fs_.existsSync(resolved)) {
throw new Error(`working-directory "${workingDirectory}" does not exist (resolved to "${resolved}")`);
}
const stat = external_fs_.statSync(resolved);
if (!stat.isDirectory()) {
throw new Error(`working-directory "${workingDirectory}" is not a directory (resolved to "${resolved}")`);
}
return resolved;
}
;// CONCATENATED MODULE: ./src/wrap-require.ts
const wrapRequire = new Proxy(require, {
@ -65065,6 +65086,7 @@ const wrapRequire = new Proxy(require, {
process.on('unhandledRejection', handleError);
main().catch(handleError);
async function main() {
@ -65094,8 +65116,9 @@ async function main() {
const script = core.getInput('script', { required: true });
const workingDirectory = core.getInput('working-directory');
if (workingDirectory) {
core.info(`Changing working directory to ${workingDirectory}`);
process.chdir(workingDirectory);
const resolved = validateWorkingDirectory(workingDirectory);
core.info(`Changing working directory to ${resolved}`);
process.chdir(resolved);
}
// Wrap getOctokit so secondary clients inherit retry, logging,
// orchestration ID, and the action's retries input.

View file

@ -10,6 +10,7 @@ import {RequestRequestOptions} from '@octokit/types'
import {callAsyncFunction} from './async-function'
import {createConfiguredGetOctokit} from './create-configured-getoctokit'
import {RetryOptions, getRetryOptions, parseNumberArray} from './retry-options'
import {validateWorkingDirectory} from './working-directory'
import {wrapRequire} from './wrap-require'
process.on('unhandledRejection', handleError)
@ -62,8 +63,9 @@ async function main(): Promise<void> {
const workingDirectory = core.getInput('working-directory')
if (workingDirectory) {
core.info(`Changing working directory to ${workingDirectory}`)
process.chdir(workingDirectory)
const resolved = validateWorkingDirectory(workingDirectory)
core.info(`Changing working directory to ${resolved}`)
process.chdir(resolved)
}
// Wrap getOctokit so secondary clients inherit retry, logging,

27
src/working-directory.ts Normal file
View file

@ -0,0 +1,27 @@
import * as fs from 'fs'
import * as path from 'path'
/**
* Validates that the given directory exists and is accessible.
* @param workingDirectory - The directory path to validate
* @returns The resolved absolute path
* @throws Error if the directory does not exist or is not a directory
*/
export function validateWorkingDirectory(workingDirectory: string): string {
const resolved = path.resolve(workingDirectory)
if (!fs.existsSync(resolved)) {
throw new Error(
`working-directory "${workingDirectory}" does not exist (resolved to "${resolved}")`
)
}
const stat = fs.statSync(resolved)
if (!stat.isDirectory()) {
throw new Error(
`working-directory "${workingDirectory}" is not a directory (resolved to "${resolved}")`
)
}
return resolved
}