Understand how github-script works
mainsrc/main.ts.repository·main·Indexed 26 days ago
https://github.com/actions/github-scriptA GitHub Action that allows executing asynchronous JavaScript code within a workflow. It provides pre-authenticated access to the GitHub API via Octokit and the workflow context, injecting objects such as github, context, core, exec, glob, and io directly into the script context. Supports custom GraphQL queries, REST API calls, and the ability to run external JavaScript files or ESM modules.
src/main.ts.The actions/github-script action allows you to execute asynchronous JavaScript code within a GitHub Actions workflow. This code has direct access to the GitHub API and the workflow run context without needing to manually import or authenticate libraries.
To use the action, provide a script input containing the body of an asynchronous JavaScript function. The following arguments are automatically injected into your script context:
github: A pre-authenticated octokit/rest.js client with pagination plugins.context: An object containing the context of the workflow run.core: A reference to the @actions/core package.glob: A reference to the @actions/glob package.io: A reference to the @actions/io package.exec: A reference to the @actions/exec package.getOctokit: A factory function to create additional authenticated Octokit clients (useful for multi-token workflows).require: A proxy wrapper around Node.js require that allows requiring relative paths and npm packages installed in the current working directory. Use __original_require__ to access the non-wrapped version.Before the action can be used, it must be compiled from TypeScript to JavaScript using the following command:
npm run buildThe value returned by your script is stored in the step's outputs under the result key. You can specify how the result is encoded using the result-encoding input.
- uses: actions/github-script@v9
id: set-result
with:
script: return "Hello!"
result-encoding: string
- name: Get result
run: echo "${{steps.set-result.outputs.result}}"To avoid script injection vulnerabilities and SyntaxErrors caused by GitHub Actions expressions being evaluated as raw JavaScript, do not use ${{ }} expressions directly inside the script block. Instead, pass values via env variables and access them using process.env within your script.
- uses: actions/github-script@v9
env:
TITLE: ${{ github.event.pull_request.title }}
with:
script: |
const title = process.env.TITLE;
if (title.startsWith('octocat')) {
console.log("PR title starts with 'octocat'");
} else {
console.error("PR title did not start with 'octocat'");
}To use ESM import syntax, reference the script by its absolute path using ${{ github.workspace }} and ensure your repository has a package.json with "type": "module" specified.
- uses: actions/checkout@v4
- uses: actions/github-script@v9
with:
script: |
const { default: printStuff } = await import('${{ github.workspace }}/src/print-stuff.js')
await printStuff()Instead of inlining code, you can require a JavaScript module from your repository. You must use actions/checkout first to ensure the file is available. Since you cannot require the GitHub context directly, you must pass github, context, and core as arguments to your exported function.
For async functions, ensure you await the call in the inline script.
- uses: actions/checkout@v4
- uses: actions/github-script@v9
with:
script: |
const script = require('./path/to/script.js')
await script({github, context, core})External Module Example (Async):
module.exports = async ({github, context, core}) => {
const {SHA} = process.env
const commit = await github.rest.repos.getCommit({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `${SHA}`
})
core.exportVariable('author', commit.data.commit.author.email)
}To get type support and IntelliSense in your scripts, install the type declarations using npm. You can then use @ts-check and the AsyncFunctionArguments type in your jsDoc comments.
$ npm i -D @actions/github-script@github:actions/github-scriptUsage in script:
// @ts-check
/** @param {import('@actions/github-script').AsyncFunctionArguments} AsyncFunctionArguments */
export default async ({core, context}) => {
core.debug('Running something at the moment')
return context.actor
}By default, the return value of the script is JSON-encoded in the result output. If you prefer a plain string, set result-encoding to string.
- uses: actions/github-script@v9
id: my-script
with:
result-encoding: string
script: return "I will be string (not JSON) encoded!"GITHUB_TOKEN provided to your workflow. To use a different token (e.g., a Personal Access Token with broader permissions), provide it via the github-token input.You can configure the github instance to retry failed requests using the retries and retry-exempt-status-codes inputs. Retries use exponential backoff via octokit/plugin-retry.js.
retries: The number of times to retry a failed request.retry-exempt-status-codes: A comma-separated list of HTTP status codes that should NOT be retried. By default, these are 400, 401, 403, 404, 422.- uses: actions/github-script@v9
id: my-script
with:
result-encoding: string
retries: 3
retry-exempt-status-codes: 400,401
script: |
github.rest.issues.get({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
})The getOctokit(token, opts) function is injected into the script context. It allows you to create new authenticated Octokit clients using different tokens (e.g., a PAT or a GitHub App token) than the default GITHUB_TOKEN.
// Basic usage
const appOctokit = getOctokit(process.env.APP_TOKEN)
// With custom options (e.g. for GitHub Enterprise Server)
const ghes = getOctokit(process.env.GHES_TOKEN, {
baseUrl: 'https://github.example.com/api/v3'
})