javascript-action

repository·main·Indexed 22 days ago

https://github.com/actions/javascript-action

A bootstrap template for creating production-ready JavaScript-based GitHub Actions. It provides a complete development lifecycle including bundling with rollup, testing with Jest, local simulation via @github/local-action, and license management. The template requires Node.js 20.x or later and includes a pre-configured ESLint Flat Config.

Tokens
2.2K
Snippets
8
Records
11
Agent score
77%

What's inside javascript-action

  1. Manage dependency licenses

    main

    This template includes a licensed.yml workflow that uses Licensed to check for non-compliant or missing licenses in your dependencies. By default, this workflow is disabled.

    Enabling License Checks

    To enable, edit .github/workflows/licensed.yml and uncomment the following lines:

    # pull_request:
    #   branches:
    #     - main
    # push:
    #   branches:
    #     - main

    Updating the License Database

    If you install or update dependencies, you may need to update the cached licenses using the Licensed CLI:

    • Update cache: licensed cache
    • Check status: licensed status
    licensed cache
    licensed status
  2. Test your action locally with @github/local-action

    main

    The @github/local-action utility simulates the GitHub Actions Toolkit, allowing you to test your action without committing and pushing to GitHub.

    Using the CLI

    Run the utility via npx by providing the path to your action.yml, your entrypoint, and a .env file containing environment variables (like inputs or event payloads).

    # Syntax: npx @github/local-action <action-yaml-path> <entrypoint> <dotenv-file>
    npx @github/local-action . src/main.js .env

    Using VS Code

    You can also use the Visual Studio Code Debugger by configuring .vscode/launch.json.

    npx @github/local-action . src/main.js .env
  3. Bootstrap a new JavaScript GitHub Action

    main

    Use this repository as a template to create a production-ready JavaScript GitHub Action. The template includes support for compilation (bundling), testing, validation workflows, and publishing guidance.

    To start:

    1. Click the Use this template button in the repository header.
    2. Create a new repository with your desired owner and name.
    3. Clone your new repository locally.

    Important: After cloning, ensure you update or remove the CODEOWNERS file to reflect your own ownership.

  4. Develop and build your action code

    main

    Your action logic resides in the src/ directory. When writing your code, remember that most GitHub Actions toolkit operations are asynchronous; your entrypoint (e.g., main.js) should use an async function.

    Development Workflow:

    1. Replace the contents of src/ with your logic.
    2. Add tests to __tests__/.
    3. Crucial Step: Run npm run all to format, test, and build the action using rollup. This step bundles your dependencies into the final JavaScript file. If you skip this, your action will not work in a workflow.
    4. Commit and push your changes to a release branch (e.g., releases/v1).
    npm run all
  5. Initial setup for JavaScript action development

    main

    After cloning the template, perform these steps to prepare your local environment. This template requires Node.js 20.x or later.

    1. Install dependencies:
      npm install
    2. Package the JavaScript for distribution (bundling):
      npm run bundle
    3. Run existing tests:
      npm test
    npm install
    npm run bundle
    npm test
  6. Use your published action in other repositories

    main

    Once your action is published and tagged (e.g., v1), other developers can use it via the uses syntax. Reference a specific version using the @ symbol.

    steps:
      - name: Checkout
        uses: actions/checkout@v4
    
      - name: Run My Action
        uses: actions/javascript-action@v1
        with:
          milliseconds: 1000
    
      - name: Print Output
        run: echo "${{ steps.test-action.outputs.time }}"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
    
      - name: Run My Action
        uses: actions/javascript-action@v1
        with:
          milliseconds: 1000
    
      - name: Print Output
        run: echo "${{ steps.test-action.outputs.time }}"
  7. Validate your action using a workflow

    main

    To verify your action works in a real GitHub environment, reference it in a workflow file within your repository using a relative path.

    steps:
      - name: Checkout
        uses: actions/checkout@v4
    
      - name: Test Local Action
        id: test-action
        uses: ./
        with:
          milliseconds: 1000
    
      - name: Print Output
        id: output
        run: echo "${{ steps.test-action.outputs.time }}"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
    
      - name: Test Local Action
        id: test-action
        uses: ./
        with:
          milliseconds: 1000
    
      - name: Print Output
        id: output
        run: echo "${{ steps.test-action.outputs.time }}"
  8. Configure ESLint for the JavaScript Action project

    main

    The project uses ESLint with the Flat Config format (eslint.config.mjs). The configuration integrates recommended rules from ESLint, Jest, and Prettier. It uses @eslint/compat to ensure compatibility with older plugin formats and @eslint/eslintrc's FlatCompat to extend existing configurations.

    Key Configuration Details:

    • Ignored Directories: **/coverage, **/dist, **/linter, and **/node_modules are excluded from linting.
    • Globals: The environment is configured for node and jest, with Atomics and SharedArrayBuffer set to readonly.
    • ECMAScript Version: Set to 2023 with sourceType: 'module'.
    • Prettier Integration: Prettier is enforced as an error via prettier/prettier: 'error'.
    import { fixupPluginRules } from '@eslint/compat'
    import { FlatCompat } from '@eslint/eslintrc'
    import js from '@eslint/js'
    // ... other imports
    
    const compat = new FlatCompat({
      baseDirectory: __dirname,
      recommendedConfig: js.configs.recommended,
      allConfig: js.configs.all
    })
    
    export default [
      {
        ignores: ['**/coverage', '**/dist', '**/linter', '**/node_modules']
      },
      ...compat.extends(
        'eslint:recommended',
        'plugin:jest/recommended',
        'plugin:prettier/recommended'
      ),
      {
        plugins: {
          import: fixupPluginRules(_import),
          jest,
          prettier
        },
        languageOptions: {
          globals: {
            ...globals.node,
            ...globals.jest,
            Atomics: 'readonly',
            SharedArrayBuffer: 'readonly'
          },
          ecmaVersion: 2023,
          sourceType: 'module'
        },
        rules: {
          camelcase: 'off',
          'eslint-comments/no-use': 'off',
          'eslint-comments/no-unused-disable': 'off',
          'i18n-text/no-en': 'off',
          'import/no-namespace': 'off',
          'no-console': 'off',
          'no-shadow': 'off',
          'no-unused-vars': 'off',
          'prettier/prettier': 'error'
        }
      }
    ]
  9. Execute the action via the run() function

    main

    The run() function is the main entrypoint for this JavaScript action. When executed, it performs the following lifecycle:

    1. Reads the milliseconds input from the GitHub Action environment.
    2. Logs debug information (only visible if ACTIONS_STEP_DEBUG is enabled).
    3. Waits for the specified number of milliseconds.
    4. Sets a time output containing the timestamp (in toTimeString() format) after the wait period.
    5. Handles errors by calling core.setFailed with the error message, which fails the GitHub Action step.

    To use this in a custom action, ensure you have an input named milliseconds defined in your action.yml.

    import { run } from './src/main.js';
    
    // This is typically called by the action runner
    await run();
  10. Reference: Action Inputs and Outputs

    main

    This action interacts with the GitHub Actions environment using the following inputs and outputs:

    Inputs

    • milliseconds: The duration to wait, provided as a string representing an integer.

    Outputs

    • time: A string representing the timestamp (via Date.prototype.toTimeString()) recorded after the wait period completes.