Platform Workshop
Franky CLI
A single Go binary that runs the entire mobile build–test–scan–deploy pipeline for iOS, Android, and Flutter.
Problem
Mobile CI stitched together a fragile chain of tools — a Swift CLI for secrets, rbenv/FVM for versions, Fastlane for signing, SonarQube for scans — each configured per machine, per pipeline.
Solution
Rebuilt it in Go (Cobra) as one binary driven by a franky.yml file: build, test, lint, security-scan, deploy, Vault-backed secrets, and a `doctor --setup` that bootstraps a fresh machine. The Go successor to the Swift Uniite CLI.
Role
Designed and built the tool, config format, and command surface in Go, porting and extending the prior Swift CLI’s capabilities.
Impact
- One command surface for build, test, scan, and deploy across three platforms
- Bootstraps a full mobile dev environment from scratch (`doctor --setup`)
- Small static binary with self-update — chosen partly for AI-maintainability
- Replaces the fragmented Jenkins tool-chain and the legacy Swift CLI
Visual metaphor
A single robot that replaces a whole workbench of one-off tools.
Highlights
Context
Mobile CI at Mekari was a relay race between tools. A Jenkins pipeline had to pull secrets with one CLI, pin Ruby and Flutter versions with rbenv and FVM, sign and upload with Fastlane, and scan with SonarQube — each configured per machine, per pipeline. The chain worked, but every new project re-derived it, and every broken link failed a build.
The first version of this was Uniite, a Swift CLI. Franky is the rewrite that learned from it.
Approach
Franky is a single Go binary built on Cobra, driven by one franky.yml per
project. Three ideas shaped it:
- One binary, one config. Everything a pipeline needs — build, test, lint, scan, deploy, secrets — lives behind one tool reading one declarative file, instead of a stack of shell steps.
- Go for reach and maintainability. A small static binary that runs anywhere, starts fast, self-updates — and, deliberately, is easy for an AI agent to read and extend. Swift was fine on macOS; Go goes everywhere the CI does.
- Bootstrap, don't document.
franky doctor --setupinstalls and pins the whole toolchain on a fresh machine, so onboarding a runner isn't a wiki page.
How it works
A developer or Jenkins stage calls one command:
franky build --config staging --platform flutter --vault
Franky handles the rest — pulling secrets from Vault, pinning the right tool
versions, running the platform build, and preparing artifacts. The command
surface covers build, test, lint, security, sonar-scan, deploy,
env, version, and doctor, with a franky.yml that each project owns.
Outcome
- One command surface for build, test, scan, and deploy across iOS, Android, and Flutter.
- A fresh machine goes from empty to build-ready with a single
doctor --setup. - A small, self-updating binary that replaced both the fragmented Jenkins tool-chain and the legacy Swift CLI.
What I'd build next
Native Vault integration to drop the last subprocess dependency, richer
security scanning, and per-command telemetry so I can see which parts of the
pipeline actually cost time.