diff --git a/.github/fixtures/script-file/all-args.js b/.github/fixtures/script-file/all-args.js new file mode 100644 index 00000000..99c87104 --- /dev/null +++ b/.github/fixtures/script-file/all-args.js @@ -0,0 +1,5 @@ +module.exports = async ({github, octokit, getOctokit, context, core, exec, glob, io, require}) => { + return [github, octokit, getOctokit, context, core, exec, glob, io, require] + .map(arg => typeof arg) + .every(t => t === 'function' || t === 'object') +} diff --git a/.github/fixtures/script-file/basic.js b/.github/fixtures/script-file/basic.js new file mode 100644 index 00000000..ead074a6 --- /dev/null +++ b/.github/fixtures/script-file/basic.js @@ -0,0 +1 @@ +module.exports = async () => 'hello from script-file' diff --git a/.github/fixtures/script-file/json-return.js b/.github/fixtures/script-file/json-return.js new file mode 100644 index 00000000..d434845c --- /dev/null +++ b/.github/fixtures/script-file/json-return.js @@ -0,0 +1 @@ +module.exports = async ({context}) => ({repo: context.repo.repo, owner: context.repo.owner}) diff --git a/.github/fixtures/script-file/not-a-function.js b/.github/fixtures/script-file/not-a-function.js new file mode 100644 index 00000000..a8653a9c --- /dev/null +++ b/.github/fixtures/script-file/not-a-function.js @@ -0,0 +1 @@ +module.exports = 42 diff --git a/.github/fixtures/script-file/sibling-caller.js b/.github/fixtures/script-file/sibling-caller.js new file mode 100644 index 00000000..87b24859 --- /dev/null +++ b/.github/fixtures/script-file/sibling-caller.js @@ -0,0 +1 @@ +module.exports = async ({require}) => require('./sibling-module').value diff --git a/.github/fixtures/script-file/sibling-module.js b/.github/fixtures/script-file/sibling-module.js new file mode 100644 index 00000000..4e8b6b88 --- /dev/null +++ b/.github/fixtures/script-file/sibling-module.js @@ -0,0 +1 @@ +module.exports = {value: 'loaded-by-require'} diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 8f93cf76..e9e2a3b6 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -361,3 +361,174 @@ jobs: echo $'::error::\u274C' "Expected base-url to equal '$expected', got $actual" exit 1 fi + + test-script-file-basic: + name: 'Integration test: script-file - relative path, string return' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + uses: ./ + with: + script-file: .github/fixtures/script-file/basic.js + result-encoding: string + - run: | + expected="hello from script-file" + if [[ "${{ steps.act.outputs.result }}" != "$expected" ]]; then + echo $'::error::❌' "Expected '$expected', got ${{ steps.act.outputs.result }}" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-absolute-path: + name: 'Integration test: script-file - absolute path' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + uses: ./ + with: + script-file: ${{ github.workspace }}/.github/fixtures/script-file/basic.js + result-encoding: string + - run: | + expected="hello from script-file" + if [[ "${{ steps.act.outputs.result }}" != "$expected" ]]; then + echo $'::error::❌' "Expected '$expected', got ${{ steps.act.outputs.result }}" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-all-ioc-args: + name: 'Integration test: script-file - all IoC args available' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + uses: ./ + with: + script-file: .github/fixtures/script-file/all-args.js + - run: | + if [[ "${{ steps.act.outputs.result }}" != "true" ]]; then + echo $'::error::❌' "Expected all IoC args to be present, got ${{ steps.act.outputs.result }}" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-result-encoding-json: + name: 'Integration test: script-file - result-encoding json' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + uses: ./ + with: + script-file: .github/fixtures/script-file/json-return.js + - run: | + expected='{"repo":"${{ github.event.repository.name }}","owner":"${{ github.repository_owner }}"}' + if [[ "${{ steps.act.outputs.result }}" != "$expected" ]]; then + echo $'::error::❌' "Expected '$expected', got ${{ steps.act.outputs.result }}" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-require-in-file: + name: 'Integration test: script-file - require inside script file' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + uses: ./ + with: + script-file: .github/fixtures/script-file/sibling-caller.js + result-encoding: string + - run: | + expected="loaded-by-require" + if [[ "${{ steps.act.outputs.result }}" != "$expected" ]]; then + echo $'::error::❌' "Expected '$expected', got ${{ steps.act.outputs.result }}" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-conflict-both: + name: 'Integration test: script-file - fails when both script and script-file are set' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + continue-on-error: true + uses: ./ + with: + script: return 1 + script-file: .github/fixtures/script-file/basic.js + - run: | + if [[ "${{ steps.act.outcome }}" != "failure" ]]; then + echo $'::error::❌' "Expected step to fail when both inputs are set" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-conflict-neither: + name: 'Integration test: script-file - fails when neither script nor script-file is set' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + continue-on-error: true + uses: ./ + - run: | + if [[ "${{ steps.act.outcome }}" != "failure" ]]; then + echo $'::error::❌' "Expected step to fail when no input is set" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-nonexistent-file: + name: 'Integration test: script-file - fails on nonexistent file' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + continue-on-error: true + uses: ./ + with: + script-file: .github/fixtures/script-file/does-not-exist.js + - run: | + if [[ "${{ steps.act.outcome }}" != "failure" ]]; then + echo $'::error::❌' "Expected step to fail for nonexistent file" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-non-function-export: + name: 'Integration test: script-file - fails when file does not export a function' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + continue-on-error: true + uses: ./ + with: + script-file: .github/fixtures/script-file/not-a-function.js + - run: | + if [[ "${{ steps.act.outcome }}" != "failure" ]]; then + echo $'::error::❌' "Expected step to fail for non-function export" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY + + test-script-file-file-protocol-rejected: + name: 'Integration test: script-file - fails for file:// protocol' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - id: act + continue-on-error: true + uses: ./ + with: + script-file: file://${{ github.workspace }}/.github/fixtures/script-file/basic.js + - run: | + if [[ "${{ steps.act.outcome }}" != "failure" ]]; then + echo $'::error::❌' "Expected step to fail for file:// protocol" + exit 1 + fi + echo $'✅ Test passed' | tee -a $GITHUB_STEP_SUMMARY diff --git a/README.md b/README.md index bbae14e0..626ab185 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ You are welcome to still raise bugs in this repo. ### This action -To use this action, provide an input named `script` that contains the body of an asynchronous JavaScript function call. -The following arguments will be provided: +To use this action, provide either a `script` input (the body of an async function, inline in your workflow YAML) or a `script-file` input (a path to a JS file that `module.exports` an async function). Exactly one of the two must be provided. + +The following arguments are available to both forms: - `github` A pre-authenticated [octokit/rest.js](https://octokit.github.io/rest.js) client with pagination plugins @@ -201,6 +202,56 @@ By default, the following status codes will not be retried: `400, 401, 403, 404, These retries are implemented using the [octokit/plugin-retry.js](https://github.com/octokit/plugin-retry.js) plugin. The retries use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) to space out retries. ([source](https://github.com/octokit/plugin-retry.js/blob/9a2443746c350b3beedec35cf26e197ea318a261/src/error-request.ts#L13)) +## Script file + +Coding long JS logic in yaml is not linted as JS/TS. +Instead of providing the `script` inline, you can use `script-file` to point to a JS file in your repository. The file must proide `module.exports` as an function (that may be async) — making it a proper module that linters and IDEs can fully analyse. + +The action handler is called with a single [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) dependency bag (defined in [`src/args.ts`](src/args.ts)). Its members are the same as those available to the inline `script`: + +| Name | Description | +| --- | --- | +| `github` | Pre-authenticated [octokit/rest.js](https://octokit.github.io/rest.js) client | +| `octokit` | Alias for `github` | +| `getOctokit` | Factory for additional authenticated Octokit clients (see [Creating additional clients](#creating-additional-clients-with-getoctokit)) | +| `context` | [Workflow run context](https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts) | +| `core` | [@actions/core](https://github.com/actions/toolkit/tree/main/packages/core) | +| `exec` | [@actions/exec](https://github.com/actions/toolkit/tree/main/packages/exec) | +| `glob` | [@actions/glob](https://github.com/actions/toolkit/tree/main/packages/glob) | +| `io` | [@actions/io](https://github.com/actions/toolkit/tree/main/packages/io) | +| `require` | Wrapped `require` that resolves relative paths and local `node_modules` | + +**Path resolution:** relative paths are resolved against `$GITHUB_WORKSPACE`; absolute paths are used as-is. The `file://` protocol is not supported. + +`script` and `script-file` are mutually exclusive — exactly one must be provided. + +```yaml +- uses: actions/checkout@v4 +- uses: actions/github-script@v9 + with: + script-file: .github/scripts/my-script.js +``` + +The action handler: + +JS: `.github/scripts/my-script.js` + +```js +module.exports = async ({github, context, core /* destructure what you need */}) => { + // your logic here +} +``` + +or TS: `.github/scripts/my-script.ts` + +```ts +import type {AsyncFunctionArguments} from '@actions/github-script' + +module.exports = async ({github, context, core /* destructure what you need */}: AsyncFunctionArguments) => { + // your logic here +} +``` + ## Examples Note that `github-token` is optional in this action, and the input is there @@ -377,52 +428,19 @@ jobs: - uses: actions/checkout@v4 - uses: actions/github-script@v9 with: - script: | - const script = require('./path/to/script.js') - console.log(script({github, context})) + script-file: ./path/to/script.js + ``` And then export a function from your module: ```javascript -module.exports = ({github, context}) => { +module.exports = ({github, context }) => { return context.payload.client_payload.value } ``` -Note that because you can't `require` things like the GitHub context or -Actions Toolkit libraries, you'll want to pass them as arguments to your -external function. - -Additionally, you'll want to use the [checkout -action](https://github.com/actions/checkout) to make sure your script file is -available. - -### Run a separate file with an async function - -You can also use async functions in this manner, as long as you `await` it in -the inline script. - -In your workflow: - -```yaml -on: push - -jobs: - echo-input: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/github-script@v9 - env: - SHA: '${{env.parentSHA}}' - with: - script: | - const script = require('./path/to/script.js') - await script({github, context, core}) -``` - -And then export an async function from your module: +The exported function may be async if you like: ```javascript module.exports = async ({github, context, core}) => { @@ -436,6 +454,14 @@ module.exports = async ({github, context, core}) => { } ``` +Note that because you can't `require` things like the GitHub context or +Actions Toolkit libraries, you'll want to accept them as arguments to your +external function: Your action is called with an [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) dependency bag - destructure from it whatever you need. Check the docs above in the **Script file** section. + +Additionally, you'll want to use the [checkout +action](https://github.com/actions/checkout) to make sure your script file is +available. + ### Use npm packages Like importing your own files above, you can also use installed modules. diff --git a/__test__/script-file.test.ts b/__test__/script-file.test.ts new file mode 100644 index 00000000..839261e7 --- /dev/null +++ b/__test__/script-file.test.ts @@ -0,0 +1,133 @@ +import * as path from 'node:path' +import * as os from 'node:os' +import * as fs from 'node:fs' +import {callScriptFile, resolveScriptFilePath} from '../src/script-file' + +const fullArgs = { + github: {}, + octokit: {}, + getOctokit: () => null, + context: {}, + core: {}, + exec: {}, + glob: {}, + io: {}, + // eslint-disable-next-line @typescript-eslint/no-require-imports + require: require, + // eslint-disable-next-line @typescript-eslint/no-require-imports + __original_require__: require +} + +describe('resolveScriptFilePath', () => { + test('rejects file:// protocol', () => { + expect(() => resolveScriptFilePath('file:///some/path.js')).toThrow( + '"script-file" must not use the "file://" protocol' + ) + }) + + test('returns absolute path as-is', () => { + const abs = '/absolute/path/to/script.js' + expect(resolveScriptFilePath(abs)).toEqual(abs) + }) + + test('resolves relative path against GITHUB_WORKSPACE when set', () => { + const original = process.env['GITHUB_WORKSPACE'] + process.env['GITHUB_WORKSPACE'] = '/workspace' + try { + expect(resolveScriptFilePath('scripts/run.js')).toEqual( + '/workspace/scripts/run.js' + ) + } finally { + if (original === undefined) { + delete process.env['GITHUB_WORKSPACE'] + } else { + process.env['GITHUB_WORKSPACE'] = original + } + } + }) +}) + +describe('callScriptFile', () => { + let tmpDir: string + + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'github-script-test-')) + }) + + afterEach(() => { + fs.rmSync(tmpDir, {recursive: true, force: true}) + }) + + test('calls the exported function with args', async () => { + const scriptPath = path.join(tmpDir, 'script.js') + fs.writeFileSync( + scriptPath, + 'module.exports = async ({core}) => core.value' + ) + + const result = await callScriptFile( + {...fullArgs, core: {value: 42}} as never, + scriptPath, + // eslint-disable-next-line @typescript-eslint/no-require-imports + require + ) + + expect(result).toEqual(42) + }) + + test('forwards all injected args to the exported function', async () => { + const scriptPath = path.join(tmpDir, 'all-args.js') + fs.writeFileSync( + scriptPath, + `module.exports = async (args) => Object.keys(args).sort()` + ) + + const result = await callScriptFile( + fullArgs as never, + scriptPath, + // eslint-disable-next-line @typescript-eslint/no-require-imports + require + ) + + expect(result).toEqual(Object.keys(fullArgs).sort()) + }) + + test('throws when file does not export a function', async () => { + const scriptPath = path.join(tmpDir, 'not-a-fn.js') + fs.writeFileSync(scriptPath, 'module.exports = 42') + + await expect( + // eslint-disable-next-line @typescript-eslint/no-require-imports + callScriptFile(fullArgs as never, scriptPath, require) + ).rejects.toThrow('"script-file" must export a function, got number') + }) + + test('throws when file does not exist', async () => { + const scriptPath = path.join(tmpDir, 'nonexistent.js') + + await expect( + // eslint-disable-next-line @typescript-eslint/no-require-imports + callScriptFile(fullArgs as never, scriptPath, require) + ).rejects.toThrow() + }) + + test('propagates rejection from the exported function', async () => { + const scriptPath = path.join(tmpDir, 'throws.js') + fs.writeFileSync( + scriptPath, + "module.exports = async () => { throw new Error('boom') }" + ) + + await expect( + // eslint-disable-next-line @typescript-eslint/no-require-imports + callScriptFile(fullArgs as never, scriptPath, require) + ).rejects.toThrow('boom') + }) + + test('rejects file:// path before loading', async () => { + await expect( + // eslint-disable-next-line @typescript-eslint/no-require-imports + callScriptFile(fullArgs as never, 'file:///some/path.js', require) + ).rejects.toThrow('"script-file" must not use the "file://" protocol') + }) +}) diff --git a/action.yml b/action.yml index 66402087..aa2a62fd 100644 --- a/action.yml +++ b/action.yml @@ -6,8 +6,15 @@ branding: icon: code inputs: script: - description: The script to run - required: true + description: The script to run (mutually exclusive with script-file) + required: false + script-file: + description: | + A path to a JS file that exports an action handler. (mutually exclusive with script) + Path may be absolute, or relative to your repo root. + The handler may be async. + The handler is called with an IoC bag with {context, core, exec, github, octokit, getOctokit, glob, io, require} - destructure what you need. + required: false github-token: description: The GitHub token used to create an authenticated client default: ${{ github.token }} diff --git a/dist/index.js b/dist/index.js index 1a6aae43..13230bd8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -65029,6 +65029,25 @@ function parseNumberArray(listString) { // EXTERNAL MODULE: external "path" var external_path_ = __nccwpck_require__(1017); +;// CONCATENATED MODULE: ./src/script-file.ts + +function resolveScriptFilePath(scriptFile) { + if (scriptFile.startsWith('file://')) { + throw new Error('"script-file" must not use the "file://" protocol'); + } + return external_path_.isAbsolute(scriptFile) + ? scriptFile + : external_path_.resolve(process.env['GITHUB_WORKSPACE'], scriptFile); +} +async function callScriptFile(args, scriptFile, requireFn) { + const resolvedPath = resolveScriptFilePath(scriptFile); + const scriptFn = requireFn(resolvedPath); + if (typeof scriptFn !== 'function') { + throw new Error(`"script-file" must export a function, got ${typeof scriptFn}`); + } + return scriptFn(args); +} + ;// CONCATENATED MODULE: ./src/wrap-require.ts const wrapRequire = new Proxy(require, { @@ -65065,6 +65084,7 @@ const wrapRequire = new Proxy(require, { + process.on('unhandledRejection', handleError); main().catch(handleError); async function main() { @@ -65091,13 +65111,20 @@ async function main() { opts.baseUrl = baseUrl; } const github = getOctokit(token, opts, retry, requestLog); - const script = core.getInput('script', { required: true }); + const scriptInline = core.getInput('script'); + const scriptFile = core.getInput('script-file'); + if (scriptInline && scriptFile) { + throw new Error('Only one of "script" or "script-file" may be provided, not both'); + } + if (!scriptInline && !scriptFile) { + throw new Error('One of "script" or "script-file" must be provided'); + } // Wrap getOctokit so secondary clients inherit retry, logging, // orchestration ID, and the action's retries input. // Deep-copy opts to prevent shared references with the primary client. const configuredGetOctokit = createConfiguredGetOctokit(getOctokit, { ...opts, retry: { ...opts.retry }, request: { ...opts.request } }, retry, requestLog); // Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors. - const result = await callAsyncFunction({ + const args = { require: wrapRequire, __original_require__: require, github, @@ -65108,7 +65135,10 @@ async function main() { exec: exec, glob: glob, io: io - }, script); + }; + const result = scriptFile + ? await callScriptFile(args, scriptFile, require) + : await callAsyncFunction(args, scriptInline); let encoding = core.getInput('result-encoding'); encoding = encoding ? encoding : 'json'; let output; diff --git a/src/args.ts b/src/args.ts new file mode 100644 index 00000000..ffee33d5 --- /dev/null +++ b/src/args.ts @@ -0,0 +1,18 @@ +import * as core from '@actions/core' +import * as exec from '@actions/exec' +import type {context, getOctokit} from '@actions/github' +import * as glob from '@actions/glob' +import * as io from '@actions/io' + +export type AsyncFunctionArguments = { + context: typeof context + core: typeof core + github: ReturnType + octokit: ReturnType + getOctokit: typeof getOctokit + exec: typeof exec + glob: typeof glob + io: typeof io + require: NodeJS.Require + __original_require__: NodeJS.Require +} diff --git a/src/async-function.ts b/src/async-function.ts index 30613f1e..16eff5aa 100644 --- a/src/async-function.ts +++ b/src/async-function.ts @@ -1,24 +1,8 @@ -import * as core from '@actions/core' -import * as exec from '@actions/exec' -import type {context, getOctokit} from '@actions/github' -import * as glob from '@actions/glob' -import * as io from '@actions/io' +import type {AsyncFunctionArguments} from './args' +export type {AsyncFunctionArguments} const AsyncFunction = Object.getPrototypeOf(async () => null).constructor -export declare type AsyncFunctionArguments = { - context: typeof context - core: typeof core - github: ReturnType - octokit: ReturnType - getOctokit: typeof getOctokit - exec: typeof exec - glob: typeof glob - io: typeof io - require: NodeRequire - __original_require__: NodeRequire -} - export function callAsyncFunction( args: AsyncFunctionArguments, source: string diff --git a/src/main.ts b/src/main.ts index 45677ff9..1eb09b13 100644 --- a/src/main.ts +++ b/src/main.ts @@ -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 {callScriptFile} from './script-file' import {wrapRequire} from './wrap-require' process.on('unhandledRejection', handleError) @@ -58,7 +59,17 @@ async function main(): Promise { } const github = getOctokit(token, opts, retry, requestLog) - const script = core.getInput('script', {required: true}) + const scriptInline = core.getInput('script') + const scriptFile = core.getInput('script-file') + + if (scriptInline && scriptFile) { + throw new Error( + 'Only one of "script" or "script-file" may be provided, not both' + ) + } + if (!scriptInline && !scriptFile) { + throw new Error('One of "script" or "script-file" must be provided') + } // Wrap getOctokit so secondary clients inherit retry, logging, // orchestration ID, and the action's retries input. @@ -71,21 +82,22 @@ async function main(): Promise { ) // Using property/value shorthand on `require` (e.g. `{require}`) causes compilation errors. - const result = await callAsyncFunction( - { - require: wrapRequire, - __original_require__: __non_webpack_require__, - github, - octokit: github, - getOctokit: configuredGetOctokit, - context, - core, - exec, - glob, - io - }, - script - ) + const args = { + require: wrapRequire, + __original_require__: __non_webpack_require__, + github, + octokit: github, + getOctokit: configuredGetOctokit, + context, + core, + exec, + glob, + io + } + + const result = scriptFile + ? await callScriptFile(args, scriptFile, __non_webpack_require__) + : await callAsyncFunction(args, scriptInline) let encoding = core.getInput('result-encoding') encoding = encoding ? encoding : 'json' diff --git a/src/script-file.ts b/src/script-file.ts new file mode 100644 index 00000000..51b99644 --- /dev/null +++ b/src/script-file.ts @@ -0,0 +1,29 @@ +import * as path from 'path' +import type {AsyncFunctionArguments} from './args' + +export function resolveScriptFilePath(scriptFile: string): string { + if (scriptFile.startsWith('file://')) { + throw new Error('"script-file" must not use the "file://" protocol') + } + + return path.isAbsolute(scriptFile) + ? scriptFile + : path.resolve(process.env['GITHUB_WORKSPACE']!, scriptFile) +} + +export async function callScriptFile( + args: AsyncFunctionArguments, + scriptFile: string, + requireFn: NodeJS.Require +): Promise { + const resolvedPath = resolveScriptFilePath(scriptFile) + const scriptFn = requireFn(resolvedPath) + + if (typeof scriptFn !== 'function') { + throw new Error( + `"script-file" must export a function, got ${typeof scriptFn}` + ) + } + + return scriptFn(args) +} diff --git a/types/args.d.ts b/types/args.d.ts new file mode 100644 index 00000000..25bb969d --- /dev/null +++ b/types/args.d.ts @@ -0,0 +1,18 @@ +/// +import * as core from '@actions/core'; +import * as exec from '@actions/exec'; +import type { context, getOctokit } from '@actions/github'; +import * as glob from '@actions/glob'; +import * as io from '@actions/io'; +export type AsyncFunctionArguments = { + context: typeof context; + core: typeof core; + github: ReturnType; + octokit: ReturnType; + getOctokit: typeof getOctokit; + exec: typeof exec; + glob: typeof glob; + io: typeof io; + require: NodeJS.Require; + __original_require__: NodeJS.Require; +}; diff --git a/types/async-function.d.ts b/types/async-function.d.ts index 772435e2..dcbcd104 100644 --- a/types/async-function.d.ts +++ b/types/async-function.d.ts @@ -1,19 +1,3 @@ -/// -import * as core from '@actions/core'; -import * as exec from '@actions/exec'; -import type { context, getOctokit } from '@actions/github'; -import * as glob from '@actions/glob'; -import * as io from '@actions/io'; -export declare type AsyncFunctionArguments = { - context: typeof context; - core: typeof core; - github: ReturnType; - octokit: ReturnType; - getOctokit: typeof getOctokit; - exec: typeof exec; - glob: typeof glob; - io: typeof io; - require: NodeRequire; - __original_require__: NodeRequire; -}; +import type { AsyncFunctionArguments } from './args'; +export type { AsyncFunctionArguments }; export declare function callAsyncFunction(args: AsyncFunctionArguments, source: string): Promise; diff --git a/types/non-webpack-require.ts b/types/non-webpack-require.ts index 71052e7a..5f169ec2 100644 --- a/types/non-webpack-require.ts +++ b/types/non-webpack-require.ts @@ -1 +1 @@ -declare const __non_webpack_require__: NodeRequire +declare const __non_webpack_require__: NodeJS.Require