Video Thumbnail for Lesson
6.4: JavaScript and TypeScript Actions

JavaScript & TypeScript actions

JavaScript-based actions are first-class citizens on GitHub: you can import @actions/core to read inputs, emit logs, set outputs, or fail the run. Even TypeScript actions must be compiled to JavaScript before publishing, so a typical project contains a build step that bundles your sources into dist/index.js.

name: 'Wait Timer'
inputs:
  milliseconds:
    description: 'Duration to wait before finishing'
    required: true
runs:
  using: node20
  main: dist/index.js
import * as core from '@actions/core'
import { wait } from './wait.js'

/**
 * The main function for the action.
 *
 * @returns Resolves when the action is complete.
 */
export async function run(): Promise<void> {
  try {
    const ms: string = core.getInput('milliseconds')

    // Debug logs are only output if the `ACTIONS_STEP_DEBUG` secret is true
    core.debug(`Waiting ${ms} milliseconds ...`)

    core.info('hello, this is another info level log!')

    // Log the current timestamp, wait, then log the new timestamp
    core.debug(new Date().toTimeString())
    await wait(parseInt(ms, 10))
    core.debug(new Date().toTimeString())

    // Set outputs for other workflow steps to use
    core.setOutput('time', new Date().toTimeString())
  } catch (error) {
    // Fail the workflow run if an error occurs
    if (error instanceof Error) core.setFailed(error.message)
  }
}

Run npm run package (from the template directory) to transpile and bundle the action. The JavaScript and TypeScript examples in the companion repo demonstrate three variants:

  1. A “no build” JavaScript action that commits node_modules (handy for demos but hard to maintain).
  2. A JavaScript action that relies on a build step before committing the bundled artifacts.
  3. A TypeScript action that compiles to JavaScript and benefits from static typing.