π― Template Repository: Use this template to create your own Kestra GitOps repository with automatic validation and deployment.
Boilerplate for versioning Kestra flows with local Docker validation and automatic deployment via GitHub Actions.
- Docker installed and running
- Node.js and npm (for automatic Git hooks)
- A Kestra instance (self-hosted or cloud)
Note: This is a template repository. After creating your repo from this template, replace example flows in
kestra/flows/company/with your own flows.
# Clone the repository
git clone <your-repo>
cd kestra-gitops
# Install dependencies (automatically configures hooks)
npm install
# Validate everything is OK
npm run validateAfter npm install, the pre-commit hook is automatically installed via Husky. Every time you commit, validation (scripts/validate.sh) runs automatically.
Before pushing to prod branch, configure the Production environment in GitHub:
- Go to your repository Settings β Environments β New environment
- Create environment named:
Production - Add the following secrets:
KESTRA_HOST: Your Kestra server URL (e.g.,https://kestra.example.com)KESTRA_USER: Email or username for authenticationKESTRA_PASSWORD: Password for authentication
Without these secrets configured, deployments will fail. This is expected behavior - the template requires you to configure your own Kestra instance.
For detailed instructions, see: docs/adding-environments.md
kestra-gitops/
βββ bin/
β βββ kestra.sh # Docker wrapper for Kestra CLI
βββ scripts/
β βββ validate.sh # Validation script (pre-commit)
βββ kestra/
β βββ flows/ # Flows organized by namespace
β β βββ company/
β β βββ hello_world.yml # Example flow (replace with yours)
β βββ files/ # Namespace files (optional)
β βββ company/
β βββ example.txt # Example file (replace with yours)
βββ .husky/
β βββ pre-commit # Automatic validation hook
βββ .github/
β βββ workflows/
β βββ kestra-deploy.yml # Deployment pipeline
βββ docs/
β βββ adding-environments.md # How to add new environments
β βββ adding-flows.md # How to add new flows
βββ docker-compose.kestra.yml # Local Kestra (development)
βββ package.json # npm/Husky configuration
βββ README.MD
The folder structure automatically determines the flow namespace:
kestra/flows/company/hello_world.yml
βββββββ βββββββββββ
namespace flow id
(/ becomes .)
In the flow YAML:
id: hello_world
namespace: companyThe scripts/validate.sh script validates:
- Structure:
idandnamespacematch file path/name - Syntax: executes
flow validate --localin ephemeral Docker container
Full validation (validates all flows):
npm run validate
# or
./scripts/validate.shSelective validation (validates only specific files):
./scripts/validate.sh --files kestra/flows/company/example.yml kestra/flows/company/other.ymlPerformance optimization: The pre-commit hook automatically validates only the files you changed, making commits much faster. Full validation runs in CI/CD.
How selective validation works:
- Pre-commit hook detects staged
.yml/.yamlfiles inkestra/flows/ - Passes only those files to the validation script
- Skips files structure validation (runs only in full mode)
- Significantly faster for development workflow
After configuring the GitHub Environment (see Initial Setup):
- Push to
prodbranch β automatic deployment to Production - Pull requests β validation only (no deployment)
- Only changed namespaces are deployed (optimized for performance)
# Validate all flows (runs complete validation)
npm run validate
# Validate specific files only (much faster for development)
./scripts/validate.sh --files kestra/flows/company/example.yml
# Validate multiple specific files
./scripts/validate.sh --files \
kestra/flows/company/flow1.yml \
kestra/flows/company/flow2.ymlThe project uses Husky to run automatic validation before each commit:
- β Validates folder/namespace structure
- β Validates YAML syntax of flows
- β‘ Only validates files you changed (fast!)
- β Blocks commit if there are errors
To bypass (use with caution):
git commit --no-verify -m "message"./bin/kestra.sh flow validate --local kestra/flows/company/hello_world.ymldocker compose -f docker-compose.kestra.yml up -dAccess at: http://localhost:8080
alias kestra='./bin/kestra.sh'
kestra --version- Push to
prodbranch β automatic deployment to Production environment - Pull requests β validation only (no deployment)
- The workflow dynamically discovers changed namespaces and deploys only what changed
To add staging, dev, or other environments, see: docs/adding-environments.md
Follow the folder convention and see the complete guide at: docs/adding-flows.md
Quick example:
# 1. Create structure
mkdir -p kestra/flows/company/pipelines
# 2. Create flow
cat > kestra/flows/company/pipelines/daily_sync.yml << 'EOF'
id: daily_sync
namespace: company.pipelines
tasks:
- id: sync
type: io.kestra.plugin.core.log.Log
message: "Syncing..."
EOF
# 3. Validate
./scripts/validate.sh
# 4. Commit
git add kestra/flows/company/pipelines/daily_sync.yml
git commit -m "Add daily sync pipeline"
git push origin prod- Adding Environments - How to create staging, dev, etc
- Adding Flows - Conventions and best practices
There is no environment separation by folders in the repository. The same code is deployed to different servers, determined by the GitHub Environment of the branch:
Repository (same flow structure)
β
ββ branch prod βββββββ Kestra Production (via environment Production)
β
ββ branch staging ββββ Kestra Staging (via environment Staging, when created)
Initial setup: validate everything works by running npm run validate β
Contributions are welcome! See CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.