Migration
This guide helps you migrate existing YAML workflows to TypeScript with gaji.
Automatic Migration
gaji can automatically convert existing YAML workflows to TypeScript:
gaji init --migrateThis will:
- Detect existing YAML workflows in
.github/workflows/ - Convert them to TypeScript in
workflows/ - Backup original YAML files (
.yml.backup) - Generate types for all actions used
Manual Migration
If you prefer to migrate manually, follow these steps:
Step 1: Analyze Your YAML
Start with a simple YAML workflow:
name: CI
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm testStep 2: Add Required Actions
gaji add actions/checkout@v4
gaji add actions/setup-node@v4Step 3: Convert to TypeScript
Create workflows/ci.ts:
import { getAction, Job, Workflow } from "../generated/index.js";
// Import actions
const checkout = getAction("actions/checkout@v4");
const setupNode = getAction("actions/setup-node@v4");
// Create job
const build = new Job("ubuntu-latest")
.addStep(checkout({}))
.addStep(setupNode({
with: {
"node-version": "20",
},
}))
.addStep({ run: "npm ci" })
.addStep({ run: "npm test" });
// Create workflow
const workflow = new Workflow({
name: "CI",
on: {
push: {
branches: ["main"],
},
},
}).addJob("build", build);
// Build YAML
workflow.build("ci");Step 4: Build and Verify
# Build TypeScript to YAML
gaji build
# Compare with original
diff .github/workflows/ci.yml .github/workflows/ci.yml.backupStep 5: Clean Up
Once verified, remove the backup:
rm .github/workflows/ci.yml.backupCommon Migration Patterns
Multiple Jobs
YAML:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
steps:
- run: npm run buildTypeScript:
const test = new Job("ubuntu-latest")
.addStep({ run: "npm test" });
const build = new Job("ubuntu-latest")
.needs(["test"])
.addStep({ run: "npm run build" });
const workflow = new Workflow({
name: "CI",
on: { push: { branches: ["main"] } },
})
.addJob("test", test)
.addJob("build", build);Matrix Strategy
YAML:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20, 22]TypeScript:
const test = new Job("${{ matrix.os }}")
.strategy({
matrix: {
os: ["ubuntu-latest", "macos-latest"],
node: ["18", "20", "22"],
},
})
.addStep(checkout({}));Environment Variables
YAML:
env:
NODE_ENV: production
jobs:
deploy:
runs-on: ubuntu-latest
env:
API_KEY: ${{ secrets.API_KEY }}TypeScript:
const deploy = new Job("ubuntu-latest")
.env({
API_KEY: "${{ secrets.API_KEY }}",
});
const workflow = new Workflow({
name: "Deploy",
on: { push: { branches: ["main"] } },
env: {
NODE_ENV: "production",
},
}).addJob("deploy", deploy);Conditional Steps
YAML:
steps:
- name: Deploy
if: github.ref == 'refs/heads/main'
run: npm run deployTypeScript:
.addStep({
name: "Deploy",
if: "github.ref == 'refs/heads/main'",
run: "npm run deploy",
})Job Outputs
YAML:
jobs:
build:
outputs:
version: ${{ steps.version.outputs.value }}
steps:
- id: version
run: echo "value=1.0.0" >> $GITHUB_OUTPUTTypeScript:
const build = new Job("ubuntu-latest")
.outputs({
version: "${{ steps.version.outputs.value }}",
})
.addStep({
id: "version",
run: 'echo "value=1.0.0" >> $GITHUB_OUTPUT',
});Migration Checklist
- Install gaji
- Initialize project
- Add all actions used in your workflows
- Convert YAML to TypeScript
- Build and verify generated YAML
- Test workflows in a branch
- Remove backup files
- Update documentation
Tips
1. Start Small
Migrate one workflow at a time, starting with the simplest one.
2. Use Automatic Migration
For complex workflows, let gaji do the initial conversion:
gaji init --migrateThen refine the generated TypeScript.
3. Test in a Branch
Always test migrated workflows in a feature branch before merging.
4. Keep Both During Transition
During migration, you can keep both YAML and TypeScript versions:
- Backup old workflows with
.backupextension (e.g.,ci.yml.backup) - New workflows: Generated from
workflows/*.tsto.github/workflows/*.yml
Troubleshooting
Types Not Generated
Make sure you've added all actions:
gaji add actions/checkout@v4
gaji devBuild Fails
Check for TypeScript errors:
npx tsc --noEmitYAML Differs from Original
Minor formatting differences are normal. Verify functionality, not formatting.
Next Steps
- Read the CLI Reference
- See Examples
