A production-ready template for creating JavaScript-based GitHub Actions with built-in testing, building, and release automation.
- Modern JavaScript: Built with Node.js 24 runtime
- Bundling: Uses Rollup to bundle dependencies into a single distributable file
- Testing: Jasmine test framework pre-configured
- GitHub Actions SDK: Pre-installed
@actions/coreand@actions/github - Command Execution: Utility function for safe command execution
- Formatting: Prettier integration for code formatting
- Release Automation: Built-in release script with npm publishing and GitHub releases
- Version Control: Automatic version bump checking
- Node.js (version 20 or higher recommended)
- npm
- GitHub CLI (
gh) - for releases - Git
Click the "Use this template" button on GitHub to create a new repository from this template, or clone it directly:
git clone <your-repo-url>
cd <your-repo-name>
npm installAfter creating your repository from this template, you need to update several files:
Update the action metadata:
- Line 3: Change action name from
My Template Actionto your action's name - Line 4: Update the description to describe what your action does
- Lines 6-10: Modify inputs to match your action's requirements (add, remove, or change as needed)
- Lines 12-20: Update or remove the example inputs (
github-token,repo-owner,repo-name) based on your needs
Update package information:
- Line 2: Change
namefrommy-actionto your action's package name - Line 4: Update
descriptionto match your action's purpose - Lines 13-17: Update or replace
keywordsto reflect your action - Line 19: Update
authorwith your name and email
- Update with your GitHub username or team to receive notifications for changes
Replace the example logic with your action's implementation:
- Keep the structure but replace
myHelpFunctionandmainwith your actual logic - The
mainfunction receives inputs and contains your action's core logic
Update the input handling:
- Line 6: Change
example-inputto match your actual input names fromaction.yml - Add additional
core.getInput()calls for each input your action needs
Replace example tests with tests for your actual functionality
- Line 1: Replace
@fabriciobastianwith your actual GitHub username or organization - Example:
@your-username:registry=https://npm.pkg.github.com - See the Configuring npm Publishing section for complete setup instructions
- Line 2: Update the package
namefrom@fabriciobastian/javascript-gh-action-templateto match your username/org - Example:
"name": "@your-username/your-action-name" - Line 5: Update
authorwith your name and email - Line 11: Update the repository
urlto match your repository - Lines 13-17: Update
keywordsto reflect your action
- Update with appropriate license information if needed
Search for TO BE UPDATED comments throughout the codebase and address them.
.
├── .github/
│ └── workflows/
│ ├── ci.yml # Continuous Integration workflow
│ └── cd.yml # Continuous Delivery workflow (release automation)
├── .npmrc # npm registry configuration (for GitHub Packages)
├── action.yml # GitHub Action metadata and configuration
├── CODEOWNERS # Code ownership configuration
├── dist/
│ └── index.js # Bundled action code (generated)
├── jasmine.json # Jasmine test configuration
├── LICENSE # License file
├── package.json # Node.js dependencies and scripts
├── README.md # This file
├── rollup.config.js # Rollup bundler configuration for action
├── rollup-package.config.js # Rollup configuration for npm package
├── src/
│ ├── index.js # Action entry point
│ ├── main.js # Main action logic
│ ├── main.spec.js # Tests for main logic
│ ├── safe-exec.js # Utility for safe command execution
│ └── package/ # NPM package configuration (if publishing)
│ ├── package-exec.js # Package entry point
│ └── package.json # Package metadata
└── tools/
├── check-version-bump.js # Version bump validation
├── exec-command.js # Command execution utility
└── release.js # Automated release script
npm testTests are configured to run all *.spec.js files in the src/ directory using Jasmine.
Check formatting:
npm run format:checkAuto-fix formatting:
npm run format:writeBuild the action bundle:
npm run buildThis creates/updates dist/index.js which is the file GitHub Actions will execute.
Important: Always run npm run build and commit the updated dist/index.js before pushing changes. GitHub Actions runs the bundled code, not the source files directly.
If you plan to publish your action as an npm package:
npm run build:packageThis creates a dist-package/ directory with the bundled package ready for npm publishing.
Releases are fully automated via GitHub workflows. When you update the version in package.json and push your changes, the configured workflows handle everything automatically.
The GitHub workflows orchestrate the release process using the included automation scripts. Here's what happens automatically:
- Version Detection: Reads the version from
package.json - Tag Verification: Checks if the release tag already exists (skips if it does)
- Building: Runs
npm run build:packageto bundle the action - Version Sync: Updates
dist-package/package.jsonwith the current version - Publishing: Publishes to npm (if configured)
- GitHub Release: Creates a GitHub release with auto-generated notes
- Tag Management: Updates the major version tag (e.g.,
v1,v2) to point to the latest release
By default, the release workflow is configured to publish your action as an npm package to GitHub Package Registry. The workflow uses the built-in GITHUB_TOKEN which automatically has the necessary permissions - no additional secrets needed!
-
Update
.npmrc(line 1):- Replace
@fabriciobastianwith your GitHub username or organization name - Example:
@your-username:registry=https://npm.pkg.github.com
- Replace
-
Update
src/package/package.json:- Line 2: Change the package name to
@your-username/your-action-name - Line 11: Update the repository URL to match your repository
- Ensure the package name matches the scope in
.npmrc
- Line 2: Change the package name to
-
That's it! The workflow is already configured with the necessary permissions:
permissions: contents: write # For creating releases packages: write # For publishing to GitHub Packages
The built-in GITHUB_TOKEN is automatically provided by GitHub Actions and has all the permissions configured in the workflow file - no manual token creation needed!
If you want to publish to the public npm registry instead of GitHub Packages:
-
Update
.npmrc:- Remove the scoped registry configuration
- Replace with:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
-
Create an npm token:
- Log in to npmjs.com
- Go to Access Tokens → Generate New Token
- Choose "Automation" type
- Add it as a repository secret named
NPM_TOKEN
-
Update
.github/workflows/cd.yml:- Change the environment variable from
GITHUB_TOKENtoNPM_TOKEN
- Change the environment variable from
If you only want to create GitHub releases without publishing any npm package:
-
Edit
tools/release.js:- Comment out or remove lines 62-85 (the npm publish section):
// Step 3: Run npm run build:package // Step 4: Set version on dist-package/package.json // Step 5: Run npm publish
-
Update
.github/workflows/cd.yml:- Remove the
.npmrcmove command (line 37):
- name: Release shell: bash run: | # mv .npmrc ~/.npmrc <- Remove this line node tools/release.js
- Remove the
-
Delete
.npmrcandsrc/package/(optional):- If you're not publishing to npm at all, you can delete these files
Note: Even without npm publishing, the workflow will still create GitHub releases and manage version tags automatically.
While workflows handle releases automatically, you can manually trigger the release script if needed:
node tools/release.jsNote: This is typically only needed for testing or troubleshooting the release process outside of CI/CD.
The template includes helper scripts in the tools/ directory that the workflows use:
tools/release.js: Main release orchestration scripttools/check-version-bump.js: Validates version bumps in pull requeststools/exec-command.js: Utility for executing shell commands with error handling
These scripts are designed to run in CI/CD environments and handle all the automation behind the scenes.
The template includes a safeExec utility for running shell commands safely:
const { safeExec } = require('./safe-exec');
// Basic usage
await safeExec('echo "Hello World"');
// With options
await safeExec('some-command', {
failOnStdErr: true, // Fail if command writes to stderr (default: true)
verbose: true // Log command execution (default: false)
});Features:
- Promise-based API
- Configurable stderr handling
- Large output buffer (200MB default, configurable via
SAFE_EXEC_MAX_BUFFER) - Verbose logging option
Once published, users can reference your action in their workflows:
- uses: your-username/your-action-name@v1
with:
example-input: 'some-value'
github-token: ${{ secrets.GITHUB_TOKEN }}- uses: your-username/your-action-name@v1.2.3
with:
example-input: 'some-value'- uses: your-username/your-action-name@abc123
with:
example-input: 'some-value'- Always bundle before committing: Run
npm run buildand commitdist/index.js - Write tests: Add tests for your action logic in
*.spec.jsfiles - Use semantic versioning: Follow semver for version numbers
- Document inputs/outputs: Keep
action.ymldocumentation clear and up-to-date - Handle errors gracefully: Use try-catch blocks and
core.setFailed()for errors - Validate inputs: Check required inputs and provide meaningful error messages
- Test locally: Test your action in a test repository before releasing
- Keep dependencies minimal: Only include necessary dependencies to reduce bundle size
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See the LICENSE file for license rights and limitations.
- GitHub Actions Documentation
- GitHub Actions Toolkit
- Creating JavaScript Actions
- Publishing Actions to Marketplace
If you encounter any issues or have questions, please open an issue on GitHub.
Happy Action Building! 🚀