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 Name
description: Your action description
author: Your Name
inputs:
your-input:
description: Input description
required: true
default: default value
outputs:
your-output:
description: Output description
runs:
using: node20
main: dist/index.jsReplace the example code in src/main.ts:
import * as core from '@actions/core'
async function run() {
try {
const input = core.getInput('your-input')
// Your action logic here
const result = `Processed: ${input}`
core.setOutput('your-output', result)
} catch (error) {
if (error instanceof Error) {
core.setFailed(error.message)
}
}
}
await run()# 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 variables
export INPUT_MILLISECONDS=1000
# Run the action
node dist/index.jsOnce published, your action can be used in workflows like this:
name: Example Workflow
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Custom Action
uses: your-username/your-action@v1
with:
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 Example
uses: ./
with:
milliseconds: 1000