Skip to main content
Learn how to debug custom JavaScript GitHub Actions step by step. We’ll use workflow commands and the @actions/core toolkit to inspect annotations, logs, summaries, and properly handle failures. By the end, you’ll be able to:
  • Read inputs and set outputs
  • Log at different levels (info, notice, warning, error)
  • Mask secrets and export environment variables
  • Generate job summaries
  • Fail actions with descriptive exit codes

Table of Contents

  1. Importing and Cloning the Repository
  2. Reviewing action.yaml
  3. Examining package.json
  4. Business Logic in index.js
  5. Building the Action
  6. Testing with a Workflow
  7. Enabling Actions and Running the Workflow
    7.1 Viewing Annotations
    7.2 Inspecting Logs
  8. Error Scenario: Invalid Phone Number
  9. Setting Failure Exit Codes
  10. Conclusion
  11. Links & References

1. Importing and Cloning the Repository

First, import the sample project into your GitHub account. Choose TroubleshootingJS-Actions, set visibility to Public, and click Import.
The image shows a GitHub page for importing a project, with fields for entering the old repository's URL and setting details for the new repository. Options for making the repository public or private are also visible.
Then clone it locally:

2. Reviewing action.yaml

Open action.yaml, the manifest that defines inputs, outputs, and runtime:

3. Examining package.json

The package.json file lists dependencies for your action bundle:
  • @actions/core: Toolkit for inputs, outputs, logging, secret masking
  • @vercel/ncc: Bundles your JavaScript into a single file
The image shows a GitHub repository interface with a file directory on the left and a list of files and folders on the right, focusing on the core package.
Refer to the actions toolkit documentation for examples such as:

4. Business Logic in index.js

The main script reads inputs, logs messages, masks secrets, exports variables, and builds a summary:
The core.setSecret() method masks sensitive values in logs. Use it whenever you log or store secrets.

5. Building the Action

Install dependencies and bundle into dist/index.js:
This creates dist/index.js with all required modules included.

6. Testing with a Workflow

Create .github/workflows/test.yml to trigger the action manually:

7. Enabling Actions and Running the Workflow

Imported repositories have Actions disabled by default. Enable them before running:
  1. Go to Settings → Actions → General
  2. Under Actions permissions, select Allow all actions and reusable workflows
The image shows a GitHub settings page for general repository actions settings, displaying options to disable or allow GitHub Actions.
The image shows a GitHub settings page for actions permissions, where options for allowing or disabling actions and workflows are displayed. It also includes settings for artifact and log retention and fork pull request workflows.
core.error() logs an error but does not fail the step. To stop the job on error, use core.setFailed().
Once enabled, trigger the workflow via Actions → Run workflow with default inputs. The job should succeed.

7.1 Viewing Annotations

GitHub UI displays annotations from different logging levels:
The image shows a GitHub Actions interface with a successful run of a "custom-action" job, displaying annotations including an error, warnings, and a notice.

7.2 Inspecting Logs

Detailed logs show messages and confirm that secrets are masked:
The image shows a GitHub Actions interface with a successful run of a custom action, displaying logs and messages related to a greeting action, including information, notice, warning, and error messages.

8. Error Scenario: Invalid Phone Number

If the phone number is shorter than 10 digits, you’ll see the logged error but the job remains green (until you opt to fail it):
The image shows a GitHub Actions interface with a job named "custom-action" that has succeeded. It includes log messages indicating information, notice, warning, and error messages related to a phone number.

9. Setting Failure Exit Codes

To mark the step as failed and stop downstream jobs, uncomment core.setFailed():
Rebuild and commit, then rerun. A short number now causes the action to fail and skip subsequent steps.
The image shows a GitHub Docs page about setting exit codes for actions, explaining how exit codes determine the success or failure status of an action.
After failure is enabled, the logs will clearly indicate a non-zero exit:
The image shows a GitHub Actions interface with a job named "custom-action" that has succeeded, displaying logs and messages related to a phone number.

10. Conclusion

You’ve covered essential patterns for debugging JavaScript Actions:
  • Use @actions/core for inputs, outputs, logs, secrets, and summaries
  • Bundle with ncc for single-file distribution
  • Write workflows to validate functionality
  • View annotations and logs directly in the GitHub UI
  • Fail actions properly with core.setFailed()
Apply these techniques to create maintainable, self-documented, and debuggable GitHub Actions.

Watch Video