A production-ready TypeScript template for creating GitHub Actions with modern tooling and best practices.
This template provides everything you need to build, test, and publish TypeScript-based GitHub Actions. It includes comprehensive tooling for development, testing, linting, and automated publishing workflows.
- TypeScript First - Full TypeScript support with strict type checking
- Modern Tooling - ESLint, Prettier, and Vitest for development workflow
- Automated Building - Uses
tsupfor fast, optimized bundling - Comprehensive Testing - Unit tests with Vitest and integration testing setup
- CI/CD Ready - GitHub Actions workflow for testing and validation
- Zero Dependencies Runtime - Only uses
@actions/corefor minimal footprint
Click "Use this template" to create a new repository from this template, or clone it directly:
git clone https://github.com/bfra-me/github-action.git my-action
cd my-actionpnpm installUpdate action.yaml with your action's metadata:
name: Your Action Namedescription: Your action descriptionauthor: Your Nameinputs:
your-input:
description: Input descriptionrequired: truedefault: default valueoutputs:
your-output:
description: Output descriptionruns:
using: node20main: dist/index.jsReplace the example code in src/main.ts:
import*ascorefrom'@actions/core'asyncfunctionrun(){try{constinput=core.getInput('your-input')// Your action logic hereconstresult=`Processed: ${input}`core.setOutput('your-output',result)}catch(error){if(errorinstanceofError){core.setFailed(error.message)}}}awaitrun()# Development build
pnpm run build
# Production build with minification
pnpm run build-release# Run all tests
pnpm test# Type checking
pnpm run check-types
# Linting
pnpm run lint
# Auto-fix linting issues
pnpm run fixTest your action locally by setting environment variables and running the built code:
# Build the action
pnpm run build
# Set input environment variablesexport INPUT_MILLISECONDS=1000
# Run the action
node dist/index.jsOnce published, your action can be used in workflows like this:
name: Example Workflowon: [push, pull_request]jobs:
test:
runs-on: ubuntu-lateststeps:
- name: Checkoutuses: actions/checkout@v4
- name: Run Custom Actionuses: your-username/your-action@v1with:
milliseconds: 2000Update package.json with your action's information:
{
"name": "your-action-name",
"description": "Your action description",
"repository": {
"type": "git",
"url": "git+https://github.com/your-username/your-action.git"
}
}# Build for production
pnpm run build-release
# Commit the dist folder
git add dist/
git commit -m "Add distribution files"
git push# Tag your release
git tag -a v1.0.0 -m "Initial release"
git push origin v1.0.0
# Create major version tag for easier referencing
git tag -a v1 -m "Version 1"
git push origin v1Tip
Users can reference your action using @v1 for the latest v1.x.x release, or @v1.0.0 for a specific version.
├── src/
│ ├── main.ts # Main action entry point
│ └── wait.ts # Example utility function
├── __tests__/
│ └── main.test.ts # Test files
├── dist/ # Built distribution files (auto-generated)
├── action.yaml # Action metadata
├── package.json # Node.js dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── tsup.config.ts # Build configuration
└── eslint.config.ts # ESLint configuration
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run the test suite:
pnpm test - Commit your changes:
git commit -m "Add my feature" - Push to the branch:
git push origin feature/my-feature - Submit a pull request
This template includes a simple example action that waits for a specified number of milliseconds. This demonstrates:
- Input handling with
@actions/core - Async operations
- Output setting
- Error handling
- TypeScript best practices
You can test it immediately:
- name: Wait Exampleuses: ./with:
milliseconds: 1000