Automated multi-branch release system — 3 bug fixes + 1 UX improvement per branch, every hour, on every branch.
20 branches 24h cooldown 1 release/hour
Full source: github.com/unclehowell/datro/tree/cnei/flywheel
A cron job on an AWS EC2 instance cycles through 20 git branches, running 4 automated fix passes on each, then cuts a GitHub release with structured release notes.
multi-branch-release.sh): Bash script, runs via cron at minute 0 of every hourintelligence.py): Python, tries AI bug-finding (timeout 60), falls through to rg-based static analysisrelease-state.json): JSON, tracks rotation index, cooldown timestamps, and per-branch release counters{branch}.datro.pages.dev / {branch}.datro.xyz| Pass | Type | Pattern |
|---|---|---|
| 1 | Bug | console\.(log|debug) — remove debug logging |
| 2 | Bug | ^\s*//\s+(if|for|while|...) — remove stale comments |
| 3 | Bug | \s+$ — trailing whitespace cleanup |
| 4 | UX | Add lang="en", viewport meta, loading="lazy", alt="" |
# Launch Ubuntu 24.04 EC2 instance (t3.small or larger)
# Install dependencies
sudo apt update && sudo apt install -y git python3 ripgrep nodejs npm
npm install -g wrangler
# Install GitHub CLI and authenticate
sudo apt install -y gh
gh auth login # Use OAuth device flow
git clone https://github.com/YOUR_USER/YOUR_REPO.git ~/repo
mkdir -p ~/.fcukproxy
# Copy multi-branch-release.sh and intelligence.py to ~/.fcukproxy/
ln -s ~/.fcukproxy/multi-branch-release.sh ~/multi-branch-release.sh
Edit the BRANCHES array in multi-branch-release.sh to list your repository's branches:
BRANCHES=(
"main"
"develop"
"feature/foo"
# ... your branches here
)
GITHUB_REPO="YOUR_USER/YOUR_REPO"
crontab -e
# Add:
0 * * * * /home/ubuntu/.fcukproxy/multi-branch-release.sh
mkdir -p ~/logs
bash ~/.fcukproxy/multi-branch-release.sh 2>&1 | tee ~/logs/first-run.log
# Verify: gh release list --repo YOUR_USER/YOUR_REPO
Tags follow {branch}-v0.0.{patch}.{build:02d} where the release number encodes directly:
release_number = total_releases[branch] + 1
patch = release_number / 100 # increments every 100 releases
build = release_number % 100 # 0–99, zero-padded to 2 digits
version = 0.0.{patch}.{build:02d}
Each branch has a 24-hour cooldown enforced by comparing the timestamp of its last GitHub release against the current time. If all 20 branches are on cooldown simultaneously, the script finds the branch closest to expiring and waits (up to 1 hour).
After each release, only the 3 most recent GitHub releases per branch are kept. Older releases and their tags are deleted automatically.
Each branch auto-deploys to Cloudflare Pages. The flywheel verifies the deployment after each release using curl. If the deploy fails, it tries inner-loop fixes (e.g., adding _redirects for SPA routing).
Each GitHub release has a structured body with two sections:
### Fixed
- fix(branch): remove debugging console.log (2 file(s): src/app.ts, src/utils.ts)
- fix(branch): clean up trailing whitespace (1 file(s): src/styles.css)
- fix(branch): remove stale commented-out code (3 file(s): ...)
### Changed
- ux(branch): improve website UX - lang, viewport (1 file(s): index.html)
The file ~/.fcukproxy/release-state.json maintains all mutable state:
{
"rotation_index": 4,
"last_release": {
"main": 1779500000,
"develop": 1779503600
},
"total_releases": {
"main": 42,
"develop": 13
}
}
~/.fcukproxy/.env or environment variablestimeout guards (60s for AI, 30s for git)MIT — use freely, adapt for your own repos.
Generated by the cnei branch — source