From 7dc493a321c56994a5376f76366e6eea62abd0aa Mon Sep 17 00:00:00 2001 From: Rob Young Date: Mon, 22 Feb 2021 11:02:45 +0000 Subject: [PATCH] Run script in GITHUB_WORKSPACE directory Change to the GITHUB_WORKSPACE directory before running the script so that callers do not have to exlicitly use the GITHUB_WORKSPACE environment variable when requiring script files. Workflow run steps are run within the GITHUB_WORKSPACE so this seems like the expected default. --- README.md | 5 ++-- __test__/async-function.test.ts | 44 +++++++++++++++++++++++++++++++++ dist/index.js | 15 +++++++++-- src/async-function.ts | 15 +++++++++-- 4 files changed, 73 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 98b4ed6..723749f 100644 --- a/README.md +++ b/README.md @@ -243,11 +243,12 @@ jobs: - uses: actions/github-script@v3 with: script: | - const script = require(`${process.env.GITHUB_WORKSPACE}/path/to/script.js`) + const script = require(`./path/to/script.js`) console.log(script({github, context})) ``` -_Note that the script path given to `require()` must be an **absolute path** in this case, hence using [`GITHUB_WORKSPACE`](https://docs.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables)._ +The script will be run within the [`GITHUB_WORKSPACE`](https://docs.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) +directory. And then export a function from your module: diff --git a/__test__/async-function.test.ts b/__test__/async-function.test.ts index d68b302..53e607d 100644 --- a/__test__/async-function.test.ts +++ b/__test__/async-function.test.ts @@ -25,4 +25,48 @@ describe('callAsyncFunction', () => { test('can access console', async () => { await callAsyncFunction({} as any, 'console') }) + + describe('change directory', () => { + const MOCK_CWD = '/path/to/action' + const MOCK_GITHUB_WORKSPACE = '/path/to/code' + const PREV_GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE + + let chdir: jest.SpyInstance + + beforeEach(() => { + jest.resetModules() + jest.clearAllMocks() + + let cwd = MOCK_CWD + + chdir = jest.spyOn(process, 'chdir').mockImplementation(directory => { + cwd = directory + }) + jest.spyOn(process, 'cwd').mockImplementation(() => { + return cwd + }) + }) + + afterAll(() => { + process.env.GITHUB_WORKSPACE = PREV_GITHUB_WORKSPACE + }) + + test('changes to GITHUB_WORKSPACE if environment variable is set', async () => { + process.env.GITHUB_WORKSPACE = MOCK_GITHUB_WORKSPACE + + await callAsyncFunction({} as any, 'process') + + expect(chdir.mock.calls.length).toBe(2) + expect(chdir.mock.calls[0][0]).toBe(MOCK_GITHUB_WORKSPACE) + expect(chdir.mock.calls[1][0]).toBe(MOCK_CWD) + }) + + test('does not change directory if GITHUB_WORKSPACE is not set', async () => { + delete process.env.GITHUB_WORKSPACE + + await callAsyncFunction({} as any, 'process') + + expect(chdir.mock.calls.length).toBe(0) + }) + }) }) diff --git a/dist/index.js b/dist/index.js index 096668f..a8e4ce1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -6117,8 +6117,19 @@ var io = __webpack_require__(436); // CONCATENATED MODULE: ./src/async-function.ts const AsyncFunction = Object.getPrototypeOf(async () => null).constructor; function callAsyncFunction(args, source) { - const fn = new AsyncFunction(...Object.keys(args), source); - return fn(...Object.values(args)); + const previousWorkingDirectory = process.cwd(); + try { + if (process.env.GITHUB_WORKSPACE !== undefined) { + process.chdir(process.env.GITHUB_WORKSPACE); + } + const fn = new AsyncFunction(...Object.keys(args), source); + return fn(...Object.values(args)); + } + finally { + if (previousWorkingDirectory !== process.cwd()) { + process.chdir(previousWorkingDirectory); + } + } } // CONCATENATED MODULE: ./src/main.ts diff --git a/src/async-function.ts b/src/async-function.ts index 64d12ab..6305b70 100644 --- a/src/async-function.ts +++ b/src/async-function.ts @@ -19,6 +19,17 @@ export function callAsyncFunction( args: AsyncFunctionArguments, source: string ): Promise { - const fn = new AsyncFunction(...Object.keys(args), source) - return fn(...Object.values(args)) + const previousWorkingDirectory = process.cwd() + try { + if (process.env.GITHUB_WORKSPACE !== undefined) { + process.chdir(process.env.GITHUB_WORKSPACE) + } + + const fn = new AsyncFunction(...Object.keys(args), source) + return fn(...Object.values(args)) + } finally { + if (previousWorkingDirectory !== process.cwd()) { + process.chdir(previousWorkingDirectory) + } + } }