https://github.com/joeblew999?preview=true
# Initialize secret management system
task secrets:setup
# Copy and edit secrets file
cp .env.example .env
# Edit .env with your actual values
# Sync secrets to GitHub
task secrets:sync
# Test connectivity
task secrets:test
# Generate .github files from templates
task setup
# Verify generated files are current
task check
# Clean generated files
task clean
# Bootstrap NATS environment
./bootstrap.sh
# Deploy to Synadia Cloud
task nats:deploy:synadia
# Or deploy self-hosted
task nats:deploy:local
📚 Detailed Documentation:
Uses Taskfile locally and in CI for consistency:
task setup
- Generate .github files from templatestask clean
- Remove generated files
Templates auto-regenerate when changed via GitHub Actions calling same Taskfile.
All Taskfile operations are idempotent and remediate race conditions:
- Clean removes all generated files completely before setup
- Setup ensures consistent directory structure from templates
- Check validates generated files match templates exactly
This repository has a unique architecture challenge:
- Templates change → triggers GitHub Action
- Action runs
task setup
→ generates new.github
files - Action commits changes → could trigger another Action
- Potential infinite loop! 🐍
Solution: GitHub Actions use [skip-regen]
commit tags to prevent recursion.
Why GitHub CLI helps: task verify-github
lets us see inside GitHub to verify:
- Workflows are actually running
- Templates are deployed correctly
- Auto-regeneration is working
- No infinite loops occurred
This gives us observability into the "snake" to ensure it doesn't eat its own tail!
Terraform-style Idempotency: This system follows infrastructure-as-code principles:
- Declarative templates (desired state)
- Idempotent operations (same result every time)
- State reconciliation (templates → generated files)
- Plan/Apply pattern (
check
thensetup
)
NATS Controller Pattern: For complex self-modifying systems, message queues can help:
- Event-driven updates - Template changes publish events
- Controller reconciliation - Separate process handles updates
- Backpressure control - Queue prevents rapid-fire changes
- Dead letter queues - Handle failed regenerations
- Distributed coordination - Multiple repos, one controller
Both patterns solve the "snake problem" differently:
- Terraform approach: Make operations idempotent (what we implemented)
- NATS approach: Decouple triggers from actions (advanced solution)
This system is designed to work seamlessly across Windows, macOS, and Linux with intelligent platform detection and adaptive tooling.
Taskfile Variables for Cross-Platform Support:
# Taskfile automatically detects OS and sets appropriate variables
vars:
GITHUB_ORG: joeblew999
OS: "{{OS}}"
ARCH: "{{ARCH}}"
EXE_EXT: '{{if eq OS "windows"}}.exe{{end}}'
# Platform-specific binary paths
GH_BINARY: 'gh{{.EXE_EXT}}'
TERRAFORM_BINARY: 'terraform{{.EXE_EXT}}'
NATS_BINARY: 'nats{{.EXE_EXT}}'
Intelligent Tool Installation:
# GitHub CLI installation (cross-platform)
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install gh # macOS via Homebrew
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
# Linux via apt/deb packages
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
sudo apt update && sudo apt install gh
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
# Windows via Chocolatey or Scoop
choco install gh || scoop install gh
fi
Go Template Processor (Pure Go = Universal):
// Cross-platform file path handling
outPath := filepath.Join(outputDir, rel) // Works on all platforms
os.MkdirAll(outDir, 0755) // Platform-appropriate permissions
Windows Compatibility:
- PowerShell detection - Tasks work in both Command Prompt and PowerShell
- WSL support - Full compatibility with Windows Subsystem for Linux
- Path handling - Automatic conversion between Windows and Unix paths
- Service management - Windows Services for NATS controllers
macOS Features:
- Homebrew integration - Automatic installation of dependencies
- Keychain integration - Secure credential storage
- Spotlight indexing - Generated files are searchable
- Notification Center - Workflow completion notifications
Linux Optimizations:
- Systemd integration - Native service management for NATS
- Package manager detection - Supports apt, yum, pacman, etc.
- Container compatibility - Docker and Podman support
- Resource efficiency - Optimized for server deployments
GitHub Actions Cross-Platform Testing:
# .github/workflows/test-cross-platform.yml
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
go-version: [1.21]
runs-on: ${{ matrix.os }}
steps:
- name: Test Taskfile on ${{ matrix.os }}
run: task validate-all
Platform-Specific Runners:
- Linux runners: Fast, cost-effective for bulk operations
- Windows runners: Ensures compatibility with enterprise Windows environments
- macOS runners: Developer workstation compatibility
- Self-hosted runners: For NATS infrastructure testing
Universal Commands:
# These work identically on all platforms:
task setup # Generate files
task status # System health
task verify-github # GitHub state validation
task nats-deploy # Infrastructure deployment
Platform Detection:
# Automatic platform-specific behavior
task install-gh # Chooses: brew, apt, choco, or scoop
task nats-controller # Uses: systemd, launchd, or Windows Services
Editor Integration:
- VS Code: Tasks appear in Command Palette on all platforms
- IntelliJ/GoLand: Task runner integration
- Vim/Neovim: Taskfile syntax highlighting and completion
NATS Infrastructure:
- Linux servers: Primary deployment target (cost-effective)
- Windows containers: Enterprise integration scenarios
- macOS development: Local testing and development
- ARM64 support: Apple Silicon and AWS Graviton compatibility
Terraform Providers:
- AWS: Universal cloud provider support
- Azure: Windows-focused enterprise deployments
- GCP: Cross-platform Kubernetes clusters
- Local providers: Platform-specific development environments
This ensures that whether you're a Windows enterprise developer, macOS indie hacker, or Linux infrastructure engineer, the system adapts to your platform while maintaining identical functionality! 🌍✨
For large-scale organizations with hundreds of repositories, the "snake chasing its tail" problem becomes even more complex. NATS messaging provides an elegant solution that goes beyond simple loop prevention to enable sophisticated orchestration patterns.
The Problem at Scale:
- 100+ repositories with
.github
templates - Cross-repo dependencies and coordination
- Rate limiting and GitHub API quotas
- Complex approval workflows
- Multi-environment deployments
NATS Solution Architecture:
GitHub Webhooks → Synadia Cloud NATS → Controllers → Terraform → Infrastructure
↕️
JetStream Persistence
↕️
Self-Similar NATS Deployments
1. Synadia Cloud as Command Center:
- Global event bus - All GitHub events flow through Synadia
- JetStream persistence - No events lost during outages
- Subject-based routing -
github.{org}.{repo}.{event_type}
- Global state coordination - Prevent conflicts across all repos
2. GitHub Webhook Integration:
# Webhook endpoint sends to NATS
curl -X POST https://nats.synadia.com/github-events \
-H "Authorization: Bearer $SYNADIA_TOKEN" \
-d '{
"subject": "github.joeblew999.template_changed",
"data": {
"repo": ".github",
"files": ["templates/workflows/ci.yml"],
"commit": "abc123"
}
}'
3. Self-Similar Controller Pattern:
// Controllers deployed via Terraform, managed by NATS
type NATSController struct {
nc *nats.Conn
terraform *terraform.Client
scope string // "org", "region", or "global"
}
// Each controller can spawn infrastructure for new controllers
func (c *NATSController) HandleScalingEvent(msg *nats.Msg) {
// Parse scaling requirements
req := parseScalingRequest(msg.Data)
// Generate Terraform for new NATS infrastructure
tf := c.generateTerraform(req)
// Apply infrastructure
result := c.terraform.Apply(tf)
// New NATS cluster automatically connects to Synadia
}
4. Terraform-in-NATS Pattern:
# terraform/nats-cluster.tf stored in this repo
# Called by NATS controllers for self-deployment
resource "nats_account" "org_account" {
name = var.github_org
limits {
max_connections = 1000
max_streams = 100
}
}
resource "nats_stream" "github_events" {
name = "GITHUB_EVENTS_${var.github_org}"
subjects = ["github.${var.github_org}.>"]
retention = "workqueue"
max_age = "7d"
}
Temporal Decoupling:
- GitHub push → NATS event (immediate)
- NATS → Controller processing (queued)
- Controller → Regeneration (rate limited)
- Result → New GitHub state (eventual)
Backpressure Management:
// Rate limiting per organization
limiter := rate.NewLimiter(rate.Every(time.Minute), 10)
func (c *Controller) HandleTemplateChange(msg *nats.Msg) {
// Wait for rate limit clearance
limiter.Wait(context.Background())
// Process change
c.regenerateFiles(msg)
}
Conflict Resolution:
# NATS subjects prevent conflicting updates
github.joeblew999.template_changed.workflows # High priority
github.joeblew999.template_changed.docs # Low priority
github.joeblew999.regeneration_in_progress # Lock subject
Multi-Level Architecture:
- Synadia Cloud - Global coordination and persistence
- Regional NATS - Low-latency processing (deployed by Terraform)
- Organization NATS - Org-specific workflows (auto-scaled)
- Repository Controllers - Individual repo management
Auto-Scaling Example:
# When load increases, controllers request more infrastructure
nats pub github.infra.scale_request '{
"org": "joeblew999",
"current_load": 85,
"requested_capacity": "2x",
"terraform_config": "terraform/nats-regional.tf"
}'
# Infrastructure controller applies Terraform
# New NATS clusters auto-connect to Synadia
# Load automatically distributes
Phase 1: Basic Integration (Current system + NATS)
- GitHub webhooks → Synadia Cloud
- Simple event routing
- Regeneration coordination
Phase 2: Terraform Integration
- Store Terraform configs in this repo
- NATS-triggered infrastructure deployment
- Self-provisioning NATS clusters
Phase 3: Self-Similar Scaling
- Auto-scaling based on GitHub activity
- Cross-org coordination
- Intelligent conflict resolution
Phase 4: Enterprise Features
- Multi-cloud deployments
- Advanced security policies
- Compliance automation
# 1. Sign up for Synadia Cloud
# 2. Add webhook to GitHub repository settings
# 3. Deploy NATS controller
task nats-controller-deploy
# 4. Test the integration
task nats-monitor
# 5. Scale as needed
task nats-scale --org joeblew999
This architecture transforms the "snake chasing its tail" from a problem into a feature - enabling self-healing, self-scaling infrastructure that grows with your organization! 🐍➡️🚀
The bee project provides an excellent foundation for evolving our NATS-powered GitHub workflow system over time. Bee specializes in event-driven distributed systems with protobuf-based code generation, making it perfect for managing the complexity of multi-repo GitHub orchestration.
Schema Evolution: Bee's protobuf approach allows GitHub event schemas to evolve safely:
- Backward compatibility - Old controllers can still process new events
- Forward compatibility - New controllers handle old event formats gracefully
- Type safety - Compile-time validation of event structures
- Cross-language support - Controllers can be written in any language
Event-Driven Architecture: Bee's patterns align perfectly with our NATS workflow:
GitHub Event → Protobuf Message → NATS Subject → Bee Handler → Action
Current Gap: Bee doesn't yet have built-in Terraform integration for ensuring NATS infrastructure is properly configured. This is exactly what our system provides!
Our Contribution:
- NATS Infrastructure as Code - Terraform configs in this repo
- Bee-Compatible Event Schemas - Protobuf definitions for GitHub events
- Self-Terraforming Pattern - NATS controllers that deploy their own infrastructure
Our system defines protobuf schemas that bee can use for code generation:
// github_events.proto - GitHub workflow events for bee
syntax = "proto3";
package github.workflow.v1;
message TemplateChangedEvent {
string org = 1;
string repo = 2;
string commit_sha = 3;
repeated string changed_files = 4;
google.protobuf.Timestamp timestamp = 5;
}
message WorkflowStatusEvent {
string org = 1;
string repo = 2;
string workflow_name = 3;
WorkflowStatus status = 4;
string run_id = 5;
}
enum WorkflowStatus {
UNKNOWN = 0;
QUEUED = 1;
IN_PROGRESS = 2;
COMPLETED = 3;
FAILED = 4;
}
Using bee's code generation, we can create type-safe event handlers:
// Generated by bee from protobuf definitions
type TemplateChangedHandler struct {
terraform *TerraformClient
nats *nats.Conn
}
func (h *TemplateChangedHandler) Handle(ctx context.Context, event *TemplateChangedEvent) error {
// Type-safe handling of template changes
if h.shouldScaleInfrastructure(event) {
return h.terraform.ApplyScaling(ctx, event.Org)
}
return h.regenerateTemplates(ctx, event)
}
The Innovation: Bee controllers that manage their own NATS infrastructure:
# bee.yaml - Bee configuration with Terraform hooks
name: github-workflow-orchestrator
events:
- github.template_changed
- github.workflow_status
- nats.infrastructure_needed
handlers:
template_changed:
type: regeneration
terraform_hook: ensure_nats_capacity
infrastructure_needed:
type: terraform
action: apply
config: terraform/nats-regional.tf
Phase 1: Protobuf Migration (Low effort, high value)
- Define GitHub event schemas in protobuf
- Generate type-safe handlers with bee
- Maintain current NATS + Terraform architecture
Phase 2: Bee Controller Integration
- Replace custom NATS controller with bee-generated handlers
- Add bee's event sourcing and state management
- Integrate with bee's built-in observability
Phase 3: Community Contribution
- Contribute NATS Terraform provider to bee ecosystem
- Open-source our "self-terraforming" patterns
- Help bee add infrastructure management primitives
Phase 4: Bee-Native GitHub Integration
- Contribute GitHub webhook → bee event pipeline
- Add GitHub API action handlers to bee
- Create bee templates for common GitHub workflows
For Developers:
- 🔒 Type safety - Compile-time validation of all events
- 🔄 Schema evolution - Safe upgrades without breaking changes
- 🛠️ Code generation - Less boilerplate, more logic
- 🌍 Multi-language - Controllers in Go, Rust, Python, etc.
For Operations:
- 📊 Built-in observability - Metrics, tracing, logging
- 🔧 Event sourcing - Full audit trail of all changes
- 🎯 Event replay - Test and debug complex workflows
- 📈 Performance monitoring - Track event processing latency
For Organizations:
- 🏗️ Evolutionary architecture - Safe schema changes over time
- 🔧 Standardized patterns - Consistent event handling across teams
- 📋 Compliance - Built-in audit trails and governance
- 🚀 Faster innovation - Focus on business logic, not infrastructure
# 1. Install bee
go install github.com/blinkinglight/bee/cmd/bee@latest
# 2. Generate handlers from our protobuf schemas
bee generate --proto schemas/github_events.proto
# 3. Deploy with Terraform-managed NATS
task nats-deploy
# 4. Start bee controller
bee run --config bee.yaml
This bee integration represents the next evolution of our GitHub workflow system - combining the best of event-driven architecture, infrastructure as code, and type-safe distributed systems! 🐝🚀
The system now supports both Synadia Cloud and self-hosted NATS deployments with comprehensive Terraform automation, providing the flexibility to choose the right infrastructure approach for your organization.
Best for: Teams wanting managed NATS with minimal operational overhead
- ✅ Zero infrastructure management - Synadia handles scaling, updates, security
- ✅ Global connectivity - Built-in multi-region support
- ✅ Enterprise features - Advanced security, compliance, monitoring
- ✅ Predictable costs - Usage-based billing
# Deploy with Synadia Cloud
export NATS_DEPLOYMENT_TYPE="synadia_cloud"
export SYNADIA_ACCOUNT="your-account-id"
export SYNADIA_NKEY="your-nkey"
task terraform-deploy
Best for: Development, testing, or small organizations
- ✅ Full control - Complete ownership of infrastructure
- ✅ Cost-effective - Pay only for compute resources
- ✅ Customizable - Tune performance and configuration
⚠️ Operational overhead - You manage updates, scaling, monitoring
# Deploy self-hosted single node
export NATS_DEPLOYMENT_TYPE="self_hosted_single"
export KUBERNETES_NAMESPACE="nats-system"
task terraform-deploy
Best for: Production workloads requiring high availability
- ✅ High availability - Multi-node clustering with failover
- ✅ Horizontal scaling - Add nodes as load increases
- ✅ Data persistence - JetStream with persistent storage
⚠️ Complex setup - Requires Kubernetes expertise
# Deploy self-hosted cluster (3 nodes)
export NATS_DEPLOYMENT_TYPE="self_hosted_cluster"
export SELF_HOSTED_REPLICAS="3"
export JETSTREAM_ENABLED="true"
task terraform-deploy
Best for: Organizations with both cloud and on-premises requirements
- ✅ Edge computing - Local NATS for low latency
- ✅ Cloud backup - Synadia Cloud for global coordination
- ✅ Gradual migration - Start self-hosted, add cloud components
⚠️ Complex networking - Requires careful network configuration
# Deploy hybrid (cloud + self-hosted)
export NATS_DEPLOYMENT_TYPE="hybrid"
export SYNADIA_ACCOUNT="your-account"
export SELF_HOSTED_CLUSTER_NAME="github-nats-edge"
task terraform-deploy
terraform/
├── nats-github-infrastructure.tf # Main deployment logic
├── nats-regional.tf # Regional scaling
├── nats-config.template # NATS server configuration
├── terraform.tfvars.example # Configuration examples
└── nats-server-setup.sh # Server initialization
cmd/nats-controller/
├── main.go # Multi-deployment controller
├── config.example.sh # Configuration examples
└── (supports all deployment types)
schemas/
└── github_events.proto # Comprehensive event definitions
├── GitHubPushEvent
├── NATSDeploymentEvent
├── NATSHealthEvent
├── NATSScalingEvent
└── 20+ other event types
# Synadia Cloud Production
export NATS_DEPLOYMENT_TYPE="synadia_cloud"
export NATS_URLS="connect.ngs.global"
export NATS_CREDS_FILE="/etc/nats/synadia.creds"
export NATS_TLS_ENABLED="true"
# Self-Hosted Development
export NATS_DEPLOYMENT_TYPE="self_hosted"
export NATS_URLS="nats://localhost:4222"
export JETSTREAM_ENABLED="false" # Lighter setup
# Kubernetes Production
export NATS_DEPLOYMENT_TYPE="self_hosted_cluster"
export NATS_URLS="nats://github-nats.nats-system.svc.cluster.local:4222"
export JETSTREAM_STORAGE_SIZE="50Gi"
export MONITORING_ENABLED="true"
# terraform.tfvars for production cluster
github_org = "joeblew999"
deployment_type = "self_hosted_cluster"
self_hosted_replicas = 3
jetstream_enabled = true
jetstream_storage_size = "50Gi"
monitoring_enabled = true
backup_enabled = true
resource_limits = {
cpu = "2000m"
memory = "2Gi"
}
- 📊 NATS Server Metrics - Connection counts, message rates, memory usage
- 📈 JetStream Metrics - Stream health, consumer lag, storage usage
- 🔍 Controller Metrics - Event processing rates, error counts
- 🚨 Health Checks - Automated health monitoring and alerting
# Prometheus metrics endpoint
curl http://nats-server:8222/metrics
# Health check endpoint
curl http://nats-server:8222/healthz
# JetStream status
nats stream ls
nats consumer ls GITHUB_EVENTS
- 🔐 NKey Authentication - Cryptographically secure credentials
- 🎟️ JWT Tokens - Fine-grained permissions and expiration
- 🔒 TLS Everywhere - All connections encrypted
- 👥 Team Management - Role-based access control
- 🗝️ NKey Support - Same security model as Synadia Cloud
- 📜 TLS Certificates - Custom CA and certificate management
- 🛡️ Network Policies - Kubernetes-native security
- 🔐 Secret Management - Integration with vault systems
# 1. Export existing configuration
nats stream backup --all /backup/$(date +%Y%m%d)
# 2. Update deployment type
export NATS_DEPLOYMENT_TYPE="synadia_cloud"
# 3. Apply Terraform changes
task terraform-deploy
# 4. Restore data to Synadia Cloud
nats stream restore /backup/20241201
# 1. Scale up gradually
export NATS_DEPLOYMENT_TYPE="self_hosted_cluster"
export SELF_HOSTED_REPLICAS="3"
# 2. Enable data persistence
export JETSTREAM_ENABLED="true"
# 3. Apply Terraform
task terraform-deploy
- 💰 Usage-based billing - Pay for what you use
- 💸 Predictable costs - No surprise infrastructure bills
- 🎯 Total cost of ownership - Lower when factoring in operational overhead
- 💻 Infrastructure costs - EC2/GKE nodes, storage, networking
- 👨💼 Operational costs - Staff time for management and monitoring
- 📈 Scaling costs - Linear cost increase with usage
Scenario | Recommended Deployment | Why |
---|---|---|
Startup/SMB | Synadia Cloud | Minimal ops overhead |
Enterprise | Hybrid | Best of both worlds |
High Security | Self-Hosted Cluster | Full control |
Development | Self-Hosted Single | Cost-effective |
Global Scale | Synadia Cloud | Built-in global infrastructure |
This flexible architecture ensures that as your GitHub automation needs grow, your NATS infrastructure can evolve seamlessly! 🏗️✨
This repository now supports Cloudflare R2 for Terraform state storage and Cloudflare Containers for globally distributed NATS deployment, offering significant cost savings and operational benefits.
Zero egress fees and S3-compatible storage for Terraform state:
# Setup R2 backend
task cloudflare:setup:r2
# Migrate existing state
task cloudflare:migrate:state
Cost Savings: ~95% reduction vs AWS S3 (zero egress fees)
Deploy NATS on a global edge network with automatic scaling:
# Setup containers platform
task cloudflare:setup:containers
# Deploy NATS orchestrator
task cloudflare:deploy
# Test deployment
task cloudflare:test
Features:
- 🌍 Global edge deployment
- 🚀 Zero cold start (pre-provisioned)
- 📊 Built-in observability
- 💰 Pay-per-use pricing
- 🔗 Native Workers integration
View detailed cost comparison vs traditional cloud providers:
task cloudflare:cost:analysis
See CLOUDFLARE-INTEGRATION.md for comprehensive setup and migration guide.