Skip to content

Platform Workshop

Franky CLI

A single Go binary that runs the entire mobile build–test–scan–deploy pipeline for iOS, Android, and Flutter.

GoCobraFastlaneHashiCorp VaultSonarQubeFirebase App Distribution

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

franky.yml config
doctor --setup bootstrap
Vault secrets integration

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 --setup installs 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.