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

30-second summary

Disclosure: Anonymized case study

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.

Ownership

Designed and built the Go tool, its declarative config, and the cross-platform command surface.

Key decision

Replaced the Swift CLI and scattered shell steps with one small Go binary reading one franky.yml per project.

Result

  • One command surface covers build, test, scan, and deploy across iOS, Android, and Flutter.
  • doctor --setup bootstraps a fresh machine into a build-ready environment.

Trade-off

Chose Go for a portable, self-updating binary that reaches every CI environment instead of keeping the tool macOS-focused in Swift.

What I’d change now

Add native Vault integration, richer security scanning, and per-command telemetry to expose where pipeline time is spent.

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.