@savvy-web/github-action-builder
Build a GitHub Action from TypeScript source without writing build config. The builder bundles your code with @rsbuild/core (rspack under the hood) and checks action.yml against GitHub's published metadata schema. The output is a single Node.js 24 file you commit to your repo.
Features
- No build config required - Picks up entry points from
src/main.ts,src/pre.ts,src/post.tson its own - Node.js 24 - Emits ESM actions that run on the
node24GitHub Actions runtime - Schema validation - Validates
action.ymlagainst GitHub's official metadata specification - Single-file bundles - All npm dependencies inlined via rsbuild;
node:builtins externalized; user-configuredexternalsandignoreoptions for optional or native modules - Local testing - Auto-persists build output for testing with nektos/act
- CI-aware - Strict validation in CI, warnings-only locally
Quick start
Scaffold a new GitHub Action project, then build it:
npx @savvy-web/github-action-builder init my-action
cd my-action
npm install
npm run buildThe init command lays down the project:
my-action/
├── src/
│ ├── main.ts # Main action entry point
│ ├── pre.ts # Pre-action hook
│ └── post.ts # Post-action cleanup
├── action.yml # GitHub Action metadata
├── action.config.ts # Build configuration
├── package.json # Dependencies and scripts
└── tsconfig.json # TypeScript configuration
Put your action logic in src/main.ts and run npm run build again. The bundled action lands at dist/main.js — commit that file to your repo.
Basic usage
Initialize
Create a new GitHub Action project:
npx @savvy-web/github-action-builder init my-actionBuild
Bundle all entry points into dist/:
npm run build
# or directly:
npx @savvy-web/github-action-builder buildValidate
Check your action.yml and configuration without building:
npm run validate
# or directly:
npx @savvy-web/github-action-builder validateProject structure
The builder expects this structure:
my-action/
├── src/
│ ├── main.ts # Required - main action entry point
│ ├── pre.ts # Optional - runs before main
│ └── post.ts # Optional - runs after main (cleanup)
├── action.yml # GitHub Action metadata (runs.using: "node24")
├── action.config.ts # Optional configuration
└── package.json
Configuration
Customize action.config.ts for your project:
import { GitHubAction } from "@savvy-web/github-action-builder";
export default GitHubAction.create({
entries: {
main: "src/main.ts",
post: "src/cleanup.ts",
},
build: {
minify: true,
sourceMap: false,
},
});action.yml requirements
Your action.yml must use Node.js 24:
name: "My Action"
description: "Does something useful"
runs:
using: "node24"
main: "dist/main.js"
post: "dist/post.js" # OptionalDocumentation
- Getting started - Installation and first build
- Configuration - All configuration options
- Local testing - Testing with nektos/act
- CLI reference - Complete command reference
- Architecture - How it works internally
- Troubleshooting - Common issues and solutions
Programmatic API
Use the builder programmatically in your scripts:
import { GitHubAction } from "@savvy-web/github-action-builder";
const action = GitHubAction.create();
const result = await action.build();
if (result.success) {
console.log(`Built ${result.build?.entries.length} entry points`);
// e.g. "Built 3 entry points"
}Shared TypeScript configuration
The package exports a base tsconfig.json for GitHub Action projects:
{
"extends": ["@savvy-web/github-action-builder/tsconfig/action.json"]
}It sets up Node.js 24 ESM actions with strict mode, an ES2022 target and bundler module resolution. Override any of it in your own tsconfig.json.
Requirements
- Node.js 24+
- TypeScript source files
action.ymlwithruns.using: "node24"
License
MIT