gha_cli
A command-line tool for generating GitHub Actions workflows using Dart code.
Installation
From your Dart project root:
dart pub global activate --source path pkgs/gha_cli
Or run directly from the workspace:
dart run gha_cli <command>
Quick Start
1. Initialize workflow scripts
# Initialize with CI template (default)
dart run gha_cli init
# Initialize with publish workflow template
dart run gha_cli init publish
This creates individual Dart files in .github/workflows/
directory:
.github/workflows/ci.dart
- CI workflow script.github/workflows/publish.dart
- Publish workflow script
2. Customize your workflows
Edit the generated Dart files in .github/workflows/
. For example, .github/workflows/ci.dart
:
import 'package:gha/gha.dart';
void main() {
final workflow = Workflow(
name: 'CI',
on: WorkflowTriggers.simple(['push', 'pull_request']),
jobs: {
'build': Job(
name: 'Build and Test',
runsOn: RunnerSpec.single('ubuntu-latest'),
steps: [
checkout(),
Step(
name: 'Setup Dart',
uses: 'dart-lang/setup-dart@v1',
withArguments: {'sdk': 'stable'},
),
Step(name: 'Install dependencies', run: 'dart pub get'),
Step(name: 'Analyze', run: 'dart analyze'),
Step(name: 'Run tests', run: 'dart test'),
],
),
},
);
// Save workflow to .github/workflows/ci.generated.yaml
workflow.save();
}
3. Generate workflow YAML files
dart run gha_cli generate
This executes all .dart
files in .github/workflows/
and generates corresponding .generated.yaml
files.
Commands
init [workflow-name]
Initialize a new workflow script in .github/workflows/
.
Usage:
dart run gha_cli init [workflow-name] [options]
Templates:
ci
(default) - Simple CI workflow with build and testpublish
- Pub.dev publishing workflow
Options:
-f, --force
- Overwrite existing file
Examples:
# Create CI workflow (default)
dart run gha_cli init
# Create publish workflow
dart run gha_cli init publish
# Create custom workflow
dart run gha_cli init deploy
# Overwrite existing file
dart run gha_cli init ci --force
generate
Generate GitHub Actions workflow YAML files from Dart scripts.
Usage:
dart run gha_cli generate [options]
Options:
-d, --dir <path>
- Directory containing workflow scripts (default:.github/workflows
)-v, --verbose
- Show verbose output
Examples:
# Generate all workflows
dart run gha_cli generate
# Generate with verbose output
dart run gha_cli generate --verbose
# Generate from custom directory
dart run gha_cli generate --dir custom/workflows
Project Structure
When you use the CLI, your project will have this structure:
.github/
└── workflows/
├── ci.dart # Source: CI workflow definition
├── ci.generated.yaml # Generated: CI workflow YAML
├── publish.dart # Source: Publish workflow definition
└── publish.generated.yaml # Generated: Publish workflow YAML
.dart
files: Your workflow definitions using thegha
package.generated.yaml
files: Auto-generated YAML files used by GitHub Actions
Multiple Workflows
Create multiple workflow files by running init
multiple times:
dart run gha_cli init ci
dart run gha_cli init publish
dart run gha_cli init deploy
Each workflow is its own Dart file that generates its own YAML file:
.github/workflows/ci.dart:
import 'package:gha/gha.dart';
void main() {
final workflow = Workflow(name: 'CI', /* ... */);
workflow.save();
}
.github/workflows/deploy.dart:
import 'package:gha/gha.dart';
void main() {
final workflow = Workflow(name: 'Deploy', /* ... */);
workflow.save();
}
Run dart run gha_cli generate
to generate YAML for all workflows.
Custom Filenames and Directories
You can customize where individual workflows are saved using the save()
method:
import 'package:gha/gha.dart';
void main() {
final workflow = Workflow(name: 'CI', /* ... */);
// Default: .github/workflows/ci.generated.yaml
workflow.save();
// Custom filename
workflow.save(filename: 'my-workflow.yaml');
// Custom directory
workflow.save(directory: 'custom/workflows');
// Both
workflow.save(directory: 'workflows', filename: 'build.yaml');
}
Integration with CI
Add this to your workflow to ensure generated workflows stay in sync:
- name: Check workflows are up to date
run: |
dart run gha_cli generate
if ! git diff --exit-code .github/workflows/*.yaml; then
echo "Workflows are out of sync. Run 'dart run gha_cli generate'"
exit 1
fi
Best Practices
- Version Control: Commit both
.dart
and.generated.yaml
files - One Workflow Per File: Keep each workflow in its own Dart file for clarity
- Code Reuse: Create helper functions for common job configurations
- Type Safety: Leverage Dart's type system to catch errors at compile time
- Naming Convention: Use descriptive names for workflow files (e.g.,
ci.dart
,publish.dart
,deploy.dart
)
Tips
Sharing Common Steps
Create helper functions in a separate file:
// .github/workflows/common.dart
import 'package:gha/gha.dart';
List<Step> dartSetup() => [
checkout(),
Step(uses: 'dart-lang/setup-dart@v1', withArguments: {'sdk': 'stable'}),
Step(run: 'dart pub get'),
];
Then import and use in your workflows:
// .github/workflows/ci.dart
import 'package:gha/gha.dart';
import 'common.dart';
void main() {
final workflow = Workflow(
name: 'CI',
on: WorkflowTriggers.simple(['push']),
jobs: {
'test': Job(
runsOn: RunnerSpec.single('ubuntu-latest'),
steps: [...dartSetup(), Step(run: 'dart test')],
),
},
);
workflow.save();
}
Custom Workflows
For workflows not covered by templates, use init
with any name and then edit:
dart run gha_cli init deploy
# Edit .github/workflows/deploy.dart
dart run gha_cli generate
Examples
See the gha package examples for more workflow patterns.
Troubleshooting
No workflows found
Error: No workflow scripts found in .github/workflows/
Solution: Run dart run gha_cli init
to create a workflow script.
Script execution failed
✗ Error executing ci.dart
Solution: Check for syntax errors in your Dart file:
dart analyze .github/workflows/ci.dart
License
MIT License - see LICENSE file for details.
Libraries
- commands/generate_command
- commands/init_command
- gha_cli
- CLI library for GitHub Actions workflow generation
- templates/templates
- Templates for workflow generation scripts