Skip to content

Add typescript support for script files. #294

Description

@ST-DDT

Is your feature request related to a problem? Please describe.

All my source is typescript except for the ones for githup-script.

Describe the solution you'd like

Add support for loading typescript files.

Describe alternatives you've considered

Run the typescript compiler to convert the ts file to a js file before executing it with this action.

Additional context

Activity

  1. nomeata commented on Dec 14, 2023

    @nomeata

    This would also allow to statically check these scripts before running, e.g. help with rhysd/actionlint#55. This would have prevented plenty of mishaps that I caused…

  2. Flydiverny commented on Dec 14, 2023

    @Flydiverny

    As a PoC I made a wrapper around github-script to use typescript sources https://github.com/Flydiverny/github-typescript it adds a small overhead as it uses esbuild binary to convert into JS.

  3. kf6kjg commented on Jun 27, 2024

    @kf6kjg

    Also the tsx project allows for doing some workarounds, and might lead to a solution here:

            uses: actions/github-script@v7
            with:
              github-token: ${{ secrets.github_token }}
              script: |
                const { tsImport } = await import('tsx/esm/api');
                const { main } = await tsImport('./report.ts', '${{ github.workspace }}/');
                await main(github, context, '${{ job.status }}');
    

    In this I'm using tsx's programmatic API to load another file that's typescript.

    Only caveat is that it can't find tsx in order to import it... So I'm solving that problem...

  4. cscleison commented on Jul 4, 2024

    @cscleison

    Only caveat is that it can't find tsx in order to import it... So I'm solving that problem...

    @kf6kjg thanks for you suggestion! I managed to make it work with:

    const { tsImport } = await import('${{ github.workspace }}/.github/node_modules/tsx/dist/esm/api/index.cjs');
    const { myFn } = await tsImport('./.github/scripts/my-file.ts', '${{ github.workspace }}/');
  5. kf6kjg commented on Jul 6, 2024

    @kf6kjg

    Just put in #477 with what is unit testing as a functional support for TypeScript!

  6. fpapado commented on Sep 10, 2025

    @fpapado

    With the recent v8 release of this action being on Node 24 (and v7 if Node >=22.18.0), one can get TypeScript support out of the box, via Node's native type stripping (which, even though in the "Release candidate" stage, is turned on by default).

    So this should work:

      testing:
        steps:
          - uses: actions/checkout@v5 # or whichever way you prefer, to access your scripts
          - uses: actions/github-script@v8
            with:
              script: |
                const mod = await import('${{ github.workspace }}/path/to/your/file.ts');
                // use mod as you wish

    There are some small syntax limitations, that you can configure tsc to catch. Refer to the Node and TypeScript docs for those:

    So I have a hunch that this issue can be closed 😌

  7. nomeata commented on Sep 10, 2025

    @nomeata

    I think there is still the usecase of having the typescript code inline in the action - or can that be achieved as well now?

  8. ST-DDT commented on Sep 10, 2025

    @ST-DDT
    Author

    IMO If you read through the limitations, there are plenty of things that will still require proper TS handling.

  9. fpapado commented on Sep 10, 2025

    @fpapado

    IMO If you read through the limitations, there are plenty of things that will still require proper TS handling.

    Could you list out the limitations that are affecting your code? I am particularly wondering what "proper" is in this case. For example, the lack of enum is notable, but the rest of the syntax (namespace etc.) is exceedingly rare in userland code, in my experience.

    I often think of tsc as modelling the environment that code runs in. In that sense, erasableSyntaxOnly and verbatimModuleSyntax is fairly scalable, especially for the script cases that actions/github-script is aimed for.

    I think there is still the usecase of having the typescript code inline in the action - or can that be achieved as well now?

    I got curious about this, and tested it in a small repo. It seems that inline typescript is a no-go :(

    We've typically been using external script files via the import() pattern above, as a way to get full typecheck/format/lint/test support, without needing to do that against inline YAML. So I haven't personally felt this pain.

    To be clear, your usecases may be valid, I don't want to argue them 😌

  10. ST-DDT commented on Sep 10, 2025

    @ST-DDT
    Author

    My usecase is collecting env/build/release information (including some gh api calls) and using that to trigger the api docs generation/diff and push resulting comments. The api docs generation uses TS-AST under the hood to do its job, so it requires a lot of things outside of my control including enums.
    Currently, I defer to tsx/tsup/other wrappers + CI switches/overrides to run the ts code for me. Bleeding built-time/actions' constraints into my main code is not acceptable for me. Though I can understand if you consider full TS support a non goal.

  11. int128 commented on Aug 14, 2026

    @int128

    We can directly import a TypeScript file in actions/github-script. For example,

        steps:
          - uses: actions/github-script@v9
            with:
              script: |
                return await require('./index.ts').main({ core, context, github })

    The type checking is available with @actions packages.

    import type * as core from '@actions/core'
    import type * as github from '@actions/github'
    
    type GitHubScriptContext = {
      core: typeof core
      context: typeof github.context
      github: ReturnType<typeof github.getOctokit>
    }
    
    export const main = async ({ core, context, github }: GitHubScriptContext) => {
      // The type checking is available here!
      core.info('Hello from TypeScript!')
    
      await github.rest.issues.createComment({
        owner: context.repo.owner,
        repo: context.repo.repo,
        issue_number: context.issue.number,
        body: `Hi`,
      })
    }

    Note that it needs to set up tsconfig.json to run TypeScript directly in Node.js.

      "compilerOptions": {
        "allowImportingTsExtensions": true,
        "noEmit": true
      }

    Here is an example at https://github.com/int128/github-script-typescript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions