Skip to main content

AI agent that builds, signs, and ships Flutter apps — APK/AAB/IPA — from the terminal

Project description

🚀 FlutterShip

An AI agent that builds, signs, and ships your Flutter app — APK, App Bundle, and IPA — from one terminal. Talk to it in plain English.

fluttership "build apk aab ipa for DEV and LIVE"

One command. Parallel builds. No forgotten version bumps, no wrong keystore passwords, no babysitting.


Table of contents


What is FlutterShip?

FlutterShip is a Python CLI with an AI agent at its core. You point it at your Flutter project and tell it what you want — "build a LIVE apk", "release 2.0.0 to TestFlight" — and it does the rest:

  • Reads your project automatically — version, flavors, dart-define keys, bundle id, signing config. No config file to write.
  • Detects your build pattern — flavors, --dart-define, --dart-define-from-file, or plain. It figures out the right flutter build command for you.
  • Builds in parallel — APK + AAB + IPA across multiple flavors at once, each in an isolated sandbox.
  • Signs and submits — uploads AAB to Google Play and IPA to TestFlight/App Store, with credentials kept in an encrypted vault the AI never sees.
  • Explains failures in plain English — when a build breaks, it reads the log and tells you exactly what to fix.
  • Keeps a release history — every build and upload is logged outside your repo.

You can drive it conversationally (the agent decides which tools to run) or with plain subcommands (fluttership doctor, fluttership status, …).


Quick start

FlutterShip needs an LLM API key to power the agent. The easiest free option is Google Gemini — the free tier is plenty for normal use.

1. Get a free Gemini API key

  1. Go to aistudio.google.com and sign in.
  2. Click Get API keyCreate API key.
  3. Copy the key (looks like [YOUR_GEMINI_API_KEY]).

Prefer Claude or GPT? FlutterShip also supports anthropic (console.anthropic.com) and openai (platform.openai.com). Pick your provider during setup.

2. Install FlutterShip

pip install fluttership

That's it — the fluttership command is now on your PATH.

Install from source (for development)
git clone https://github.com/AscEmon/fluttership.git
cd fluttership

python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

pip install -e .

3. First run — the setup wizard

From inside any Flutter project, run:

cd /path/to/your/flutter/app
fluttership

On first run a ~30-second wizard walks you through:

  • Mode — solo (just you) or team (a lead shares credentials).
  • AI provider + model — pick gemini and the default model.
  • Your API key — paste it and FlutterShip saves it to ~/.fluttership/.env (permissions 600), or set it yourself (see below).

After that, you're talking to the agent. That's it.

Setting the API key manually (optional)

Instead of pasting it into the wizard, you can put it in a .env file in your project root, or in ~/.fluttership/.env:

# Pick one, matching your chosen provider
GEMINI_API_KEY=[YOUR_GEMINI_API_KEY]
# ANTHROPIC_API_KEY=[YOUR_ANTHROPIC_API_KEY]
# OPENAI_API_KEY=[YOUR_OPENAI_API_KEY]

# Optional — override provider/model without re-running the wizard
# LLM_PROVIDER=gemini
# GEMINI_MODEL=gemini-2.5-flash

Project .env wins; ~/.fluttership/.env fills the gaps. Both are git-ignored.

Verify everything is wired up:

fluttership doctor

How you actually use it

There are two ways to drive FlutterShip — mix them however you like.

A) Talk to the agent (natural language)

Just run fluttership and type what you want. Or pass it inline:

fluttership "build LIVE apk"
fluttership "build apk aab ipa for DEV and LIVE"     # parallel matrix
fluttership "release version 2.0.0 to production"
fluttership "what was the last release?"

The agent reads your project, shows a short build plan, asks for confirmation, builds, and offers the right next step (e.g. "Submit to TestFlight?" only after an IPA is built).

Inside an interactive session, type / to open the command palette (/status, /doctor, /vault, /mode, /new, /exit, …). Press Esc to interrupt the agent mid-thought and redirect it.

B) Plain subcommands (no LLM involved)

fluttership status      # version, bundle id, detected build pattern
fluttership doctor      # health checks — tools, signing, vault, API key
fluttership history     # build & release history for this project
fluttership clean       # delete build artifacts (fluttership-dist/)

Command reference

Command What it does
fluttership Start the interactive AI agent
fluttership "<request>" Run a one-off request, e.g. "build LIVE apk"
fluttership setup Re-run the setup wizard (mode / provider / model)
fluttership mode Show or switch solo/team mode
fluttership mode solo Switch to solo mode
fluttership mode team lead|member Switch to team mode with a role
fluttership config Show current configuration
fluttership doctor Environment + project health checks
fluttership status Project info — version, bundle id, build pattern
fluttership history Build & release history
fluttership clean Delete build artifacts (fluttership-dist/)
fluttership vault setup Create the encrypted credentials vault (team: lead only)
fluttership vault verify Test the vault password + show what's configured
fluttership vault status Vault info (no password needed)
fluttership vault log Credential-access audit log
fluttership vault export [dest] Share the encrypted vault with your team (lead only)
fluttership vault import <file> Install a vault shared by your team lead
fluttership help Full usage

Slash commands (inside an interactive session): /status, /history, /doctor, /clean, /mode, /config, /vault, /setup, /new, /exit.


⚡ Parallel builds

FlutterShip's headline feature. Ask for several targets and/or flavors at once and it builds them concurrently, each job in its own isolated git worktree sandbox:

fluttership "build apk aab ipa for DEV and LIVE"

A live dashboard shows every job's status as it runs:

⚡ Building 6 jobs · v2.0.0+9
┌──────────────┬──────────────┬────────┬──────────────────────────────┐
│ Job          │ Status       │   Time │ Detail                       │
├──────────────┼──────────────┼────────┼──────────────────────────────┤
│ apk·DEV      │ ✅ done      │  1m42s │ myapp_DEV_2.0.0(9).apk       │
│ apk·LIVE     │ ✅ done      │  1m48s │ myapp_LIVE_2.0.0(9).apk      │
│ aab·LIVE     │ 🔨 building  │  0m55s │ logs/aab-LIVE.log            │
│ ipa·LIVE     │ 🍎 archiving │  2m10s │ logs/ipa-LIVE.log            │
└──────────────┴──────────────┴────────┴──────────────────────────────┘

Why it's worth it:

  • Faster releases — wall-clock time is your slowest build, not the sum of all of them.
  • No collisions — each job runs in a fresh, isolated worktree, so Gradle's project lock and the shared build/ directory never clash. iOS archives are automatically serialized (Xcode's global state can't take two Runner archives at once), while Android builds stay fully parallel.
  • One shared version — every artifact in a run carries the same version+build number, so a matrix release is consistent.
  • Artifacts collected safely — finished builds land in fluttership-dist/ (outside build/), so flutter clean can't wipe what you just built. Per-job logs go to build/fluttership-logs/.
  • Different flavors per platform"LIVE and DEV apk, plus LIVE ipa only" builds exactly those pairs, no wasted builds.

Run fluttership clean to reclaim space from fluttership-dist/ when you're done (your release history, kept in ~/.fluttership, is never touched).


🔐 The secure vault

Store credentials (App Store .p8 key, Play Store service-account JSON, IDs) are sensitive. FlutterShip keeps them in an encrypted vault — never in your repo, never in plain text, and never shown to the AI model.

How it's protected:

  • AES-256-GCM encryption with PBKDF2 key derivation (200,000 iterations).
  • Lives in ~/.fluttership/vault.enc (chmod 600) — outside your project.
  • Files are base64-encoded before encryption — not human-readable.
  • Decrypted in memory only; temp files written to /tmp (chmod 600) are deleted immediately after each upload.
  • The LLM only ever sees success/fail status — never a key, password, or token.
  • Every access is written to an audit log (fluttership vault log).

Set it up once:

fluttership vault setup

It asks for your Play Store service-account JSON, App Store .p8 key, and the matching IDs (see the next section for how to get those), then asks you to set a vault password.

fluttership vault verify    # test your password + see what's configured
fluttership vault status    # info only — no password needed

Choose a strong vault password and store it in a password manager. If you share the vault with a team, never send the password over chat or email — use a shared password-manager item.


📦 Publishing to the stores

To upload builds, FlutterShip needs store credentials in the vault. Here's exactly what to download and where to get each piece. Run fluttership vault setup and have these ready.

🍎 App Store / TestFlight (iOS — IPA)

You need an App Store Connect API key. Three pieces:

What Where to get it
.p8 key file App Store Connect → Users & AccessIntegrations / Keys(+) generate a key with App Manager access. Download the .p8 — it can only be downloaded once.
Key ID Shown next to the key you created (e.g. [YOUR_KEY_ID]).
Issuer ID At the top of the Keys page (e.g. [YOUR_ISSUER_ID]).
Bundle ID Your app's bundle identifier, must match your Xcode project.

The app must already exist in App Store Connect (My Apps → (+) New App) with a matching bundle ID before the first upload. Uploads go to TestFlight via xcrun altool, so iOS publishing requires macOS + Xcode.

🤖 Google Play (Android — AAB)

You need a service-account JSON with Play Developer API access:

What Where to get it
Service account JSON Google Play Console → Setup → API access → create/link a service account in Google Cloud Console, grant it release permissions, then download its JSON key.
Package name Your app's applicationId (e.g. com.example.myapp).

Play uploads default to the internal track (safest). Change it with fluttership config or by telling the agent "release to production". The Play Store rejects duplicate version codes, so FlutterShip prompts you to confirm the version + build number for every store-bound build.

Then just ask

fluttership "release 2.0.0 to TestFlight and Play Store"

FlutterShip unlocks the vault (you enter the vault password), uploads, and records it as a release in your history. A build that was only compiled — never uploaded — stays a "build", not a "release".


Solo vs Team mode

Solo — everything lives on your machine. You own the vault and the releases.

Team — a shared-vault workflow:

  • The lead runs vault setup once, then vault export to produce the encrypted fluttership-vault.enc file and hands it to members.
  • Members run vault import <file> and can build + submit, but never manage or re-export credentials.
  • The vault file is safe to share (it's AES-256-GCM encrypted and useless without the password). Share the password only through a team password manager.
fluttership mode team lead      # you manage credentials
fluttership mode team member    # you import the lead's vault

Requirements

  • Python 3.9+
  • Flutter SDK (on your PATH)
  • git and rsync (rsync powers the isolated parallel-build sandboxes)
  • For iOS builds/uploads: macOS + Xcode + CocoaPods
  • An LLM API key (Gemini free tier works great)

Run fluttership doctor any time to check all of the above.


Security model

  • Credentials are never committed — the vault lives in ~/.fluttership/, outside your repo, and .p8/.jks/.json/.env files are git-ignored by default.
  • The AI never sees secrets — it receives only success/fail status and file paths, never key material.
  • Encryption at rest — AES-256-GCM + PBKDF2; decrypted only in memory; temp files wiped after use.
  • Audit trail — vault unlocks, exports, imports, and uploads are logged.
  • Built artifacts can embed compiled code and dart-define values, so fluttership-dist/ is git-ignored automatically — never commit your builds.

If you fork or publish this repo, scrub any API keys from your git history before making it public — a key committed even once stays in the history until rewritten.


License

MIT


Built by a Flutter dev who got tired of spending 3 hours on a 10-minute release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fluttership-1.0.0.tar.gz (90.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fluttership-1.0.0-py3-none-any.whl (94.1 kB view details)

Uploaded Python 3

File details

Details for the file fluttership-1.0.0.tar.gz.

File metadata

  • Download URL: fluttership-1.0.0.tar.gz
  • Upload date:
  • Size: 90.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for fluttership-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5b67d9110fd9c76f30f33af045e4f983dad1c733c73e11906c0c6f03e32ded25
MD5 277a50976d44841471188f0b6134ddcb
BLAKE2b-256 db67c076fce6fcc5cb766c5436bce2627d5414be3a31c225924df195dc2e2dd7

See more details on using hashes here.

File details

Details for the file fluttership-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: fluttership-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 94.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for fluttership-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 255ed4cef15cb7d6b84f1c4606dda2ccba28ce6c541f558d8cc644b97006533a
MD5 2f3399e8f8ada4e240952080190aad17
BLAKE2b-256 3b5ebe8c72cdb8edd4dfa37316fe2a6db44b51e2750a50bcaa2a57240d9c52c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page