https://github.com/7irelo/helmforge
Helmforge is a production-grade deployment orchestrator that applies Git-declared state to remote infrastructure with idempotent reconciliation, health-aware rollouts, and release history tracking.
https://github.com/7irelo/helmforge
cli cobra-cli devops docker gitops ssh yaml zerolog
Last synced: 18 days ago
JSON representation
Helmforge is a production-grade deployment orchestrator that applies Git-declared state to remote infrastructure with idempotent reconciliation, health-aware rollouts, and release history tracking.
- Host: GitHub
- URL: https://github.com/7irelo/helmforge
- Owner: 7irelo
- License: mit
- Created: 2024-07-11T10:43:17.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2026-03-18T10:23:43.000Z (about 1 month ago)
- Last Synced: 2026-03-19T01:37:18.668Z (about 1 month ago)
- Topics: cli, cobra-cli, devops, docker, gitops, ssh, yaml, zerolog
- Language: Go
- Homepage:
- Size: 43.9 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# helmforge
A GitOps-style deployment engine that deploys apps to remote Linux hosts via SSH using Docker Compose. Uses a Git repository as the source of truth.
## Features
- **plan** — Preview deployment actions without executing anything
- **apply** — Deploy with rolling strategy, health checks, and automatic rollback on failure
- **status** — View latest release and per-host deployment status
- **drift** — Detect when remote state diverges from desired Git state
- **rollback** — Re-deploy a previous release by ID
## Install
```bash
# Build from source (requires Go 1.21+)
go build -o helmforge ./cmd/helmforge
# Or install directly
go install github.com/7irelo/helmforge/cmd/helmforge@latest
```
**Prerequisites on your local machine:**
- `git` CLI
- `ssh` / `scp` CLI (with key-based auth configured)
**Prerequisites on remote hosts:**
- Docker + `docker compose` (v2 plugin)
- SSH access for the deploy user
## Repository Layout
helmforge reads config from a Git repository with this structure:
```
repo/
environments/
staging/
apps/
reporting-service/
app.yaml # App config (required)
docker-compose.yaml # Compose file (required)
.env.example # Optional reference
prod/
apps/
reporting-service/
app.yaml
docker-compose.yaml
```
## app.yaml Schema
```yaml
app: reporting-service # Application name (required)
env: staging # Environment (required)
targets: # Deploy targets (at least one required)
- host: 10.0.1.10 # Hostname or IP (required)
user: deploy # SSH user (required)
port: 22 # SSH port (default: 22)
path: /opt/apps/reporting # Remote path for compose files (required)
- host: 10.0.1.11
user: deploy
path: /opt/apps/reporting
source:
type: compose # Must be "compose" (required)
composeFile: docker-compose.yaml # Compose file name (required)
deploy:
strategy: rolling # Deploy strategy (default: rolling)
health:
type: http # Health check type: "http" or "none"
url: http://10.0.1.10:8080/health
timeoutSeconds: 30 # Default: 30
policy:
allowedBranches: # Optional: restrict deployable branches
- main
- staging
requireCleanWorktree: true # Optional (default: false)
requireSignedCommits: false # Optional (default: false)
```
## Usage
### Plan
Preview what will happen during deployment:
```bash
helmforge plan -e staging -a reporting-service --repo git@github.com:org/infra.git
```
Sample output:
```
Deployment Plan
===============
App: reporting-service
Env: staging
Repo: git@github.com:org/infra.git
Ref: main
Commit: a1b2c3d4e5f6
Host: deploy@10.0.1.10:22
--------------------------------------------------
+ [ensure_dir] Create remote directory /opt/apps/reporting
cmd: mkdir -p /opt/apps/reporting
~ [copy_files] Copy docker-compose.yaml to 10.0.1.10:/opt/apps/reporting
> [docker_pull] Pull latest images
cmd: cd /opt/apps/reporting && docker compose pull
> [docker_up] Start/update services
cmd: cd /opt/apps/reporting && docker compose up -d --remove-orphans
? [health_check] HTTP health check http://10.0.1.10:8080/health (timeout 30s)
* [write_marker] Write release marker file
Host: deploy@10.0.1.11:22
--------------------------------------------------
...
```
JSON output for CI:
```bash
helmforge plan -e staging -a reporting-service --repo git@github.com:org/infra.git --json
```
```json
{
"env": "staging",
"app": "reporting-service",
"repo": "git@github.com:org/infra.git",
"ref": "main",
"commit_sha": "a1b2c3d4e5f6789...",
"actions": [
{
"host": "deploy@10.0.1.10:22",
"step": "ensure_dir",
"description": "Create remote directory /opt/apps/reporting",
"command": "mkdir -p /opt/apps/reporting"
},
...
]
}
```
### Apply
Execute the deployment:
```bash
# Serial deployment (default)
helmforge apply -e staging -a reporting-service --repo git@github.com:org/infra.git
# Deploy up to 3 hosts in parallel
helmforge apply -e staging -a reporting-service --repo git@github.com:org/infra.git --max-parallel 3
# Deploy a specific branch/tag/commit
helmforge apply -e staging -a reporting-service --repo git@github.com:org/infra.git --ref v1.2.3
```
Sample output:
```
Deployment Plan
===============
App: reporting-service
Env: staging
...
Executing deployment...
Release: rel-1708617234567890
Status: success
App: reporting-service
Env: staging
Commit: a1b2c3d4
Started: 2025-02-22 15:00:00 UTC
Finished: 2025-02-22 15:00:45 UTC
Duration: 45s
Host Results:
HOST STATUS ERROR
10.0.1.10 success
10.0.1.11 success
```
### Status
Check the current deployment status:
```bash
helmforge status -e staging -a reporting-service
# With drift detection (compares remote marker to current Git HEAD)
helmforge status -e staging -a reporting-service --repo git@github.com:org/infra.git
```
### Drift
Check for configuration drift across all apps in an environment:
```bash
# Check all apps
helmforge drift -e staging --repo git@github.com:org/infra.git --all
# Check specific apps
helmforge drift -e staging --repo git@github.com:org/infra.git reporting-service
```
Sample output:
```
Drift Report for staging (desired: a1b2c3d4)
===========================================
reporting-service/10.0.1.10 InSync a1b2c3d4 -> a1b2c3d4
reporting-service/10.0.1.11 OutOfSync a1b2c3d4 -> 9f8e7d6c
```
### Rollback
Roll back to a previous release:
```bash
helmforge rollback -e staging -a reporting-service --to rel-1708617234567890
```
### Global Flags
```
-v, --verbose Enable verbose/debug logging
--log-json Use structured JSON logging (for CI/log aggregation)
```
## Architecture
```
cmd/helmforge/main.go Entry point
internal/
core/
model/ Domain types (AppConfig, Release, Plan, etc.)
validate/ YAML config parsing + validation
plan/ Plan generation (read-only)
reconcile/ Apply engine (deploy, drift check)
release/ Output formatting (text, JSON)
adapters/
git/ Git operations (shells out to git CLI)
remote/ SSH execution (shells out to ssh/scp)
health/ HTTP health checking
store/ SQLite release storage
cli/
commands/ Cobra CLI commands
util/
log/ Structured logging (zerolog)
lock/ File-based deploy locking
```
All adapters are behind interfaces for testability. Core logic depends only on interfaces, not concrete implementations.
## Safety
- **Ctrl+C handling**: Cancellation stops further host deploys and marks release as cancelled
- **Deploy locking**: File-based lock prevents concurrent deploys for the same env/app
- **Rolling strategy**: Deploy host-by-host, stop on first failure
- **Release tracking**: Every deploy is recorded in local SQLite with per-host results
- **Drift detection**: Remote marker file tracks deployed commit SHA
## Secrets
For v1, helmforge does NOT manage secrets directly. Recommended approaches:
- Pre-provision `.env` files or Docker secrets on the host
- Use an external decrypt command hook
- Use a secrets manager that injects env vars at runtime
## Running Tests
```bash
go test ./...
```
## License
MIT