Skip to content
Deployment
Skill

/flame-harness-build

Phase 8 — bootstrap signing credentials, generate fastlane config from templates, and build + upload signed IPA (TestFlight) and AAB (internal track).

From plugin
flutter-flame-harness
6114 skills1 hook

Claude Code

$ npx -y skills add tjdrhs90/flutter-flame-harness --skill flame-harness-build --agent claude-code

SKILL.md

flame-harness-build.SKILL.md
name: flame-harness-build
description: Phase 8 — bootstrap signing credentials, generate fastlane config from templates, and build + upload signed IPA (TestFlight) and AAB (internal track).
argument-hint: ""
allowed-tools: [Read, Write, Edit, Bash, Glob]

flame-harness-build

Phase 8 of the flutter-flame-harness pipeline. Bootstraps signing credentials into the generated game, generates fastlane config from the Task 3 templates, then builds and uploads a signed IPA to TestFlight and a signed AAB to the Play Store internal track.

All file schemas (`config.md`, `state.md`, `pipeline-log.md`) and the phase transition table are defined in `docs/harness-protocol.md` — that document is the single source of truth (§1 for `config.md` including `credentials_dir`, `ios`, and `android` blocks; §2 for `state.md`; §6 for log schemas; §7 for the `build → screenshot` transition and the `status: running` rule). Do not redefine schemas here.

**Prerequisites:** An App Store Connect app record and a Google Play Console app must already exist (created once manually). The upload lanes will fail without them. Fastlane and Ruby must be installed on the developer's macOS machine (Xcode and the flutter CLI are assumed present).

---

Input — Read Inputs

Before any action, load:

1. `docs/harness/config.md` — extract `app_slug`, `bundle_id`, `app_name`, and `credentials_dir` (per protocol §1). Also read `ios.asc_key_id` and `android.key_alias`. 2. `docs/harness/state.md` — confirm `next_role: build` (per protocol §2).

Derive the game root path: `<projects-dir>/<app_slug>/`.

---

Phase 1 — Credential Bootstrap

Copy signing credentials from the shared `credentials_dir` (per protocol §1 — skills must not hard-code credential paths; always read `credentials_dir` from `config.md`) into the game's platform directories.

iOS credentials

mkdir -p <game>/ios/fastlane/certs
cp <credentials_dir>/AuthKey_<asc-key-id>.p8 <game>/ios/fastlane/

The `.p8` filename encodes the ASC key ID from `config.md` `ios.asc_key_id`. The `certs/` directory holds the downloaded distribution certificate and provisioning profile (written by `fastlane certs`).

Android credentials

mkdir -p <game>/android/fastlane
cp <credentials_dir>/play-store-key.json <game>/android/fastlane/

Android keystore

Check whether `<credentials_dir>/upload-keystore.jks` exists.

  • **If it exists:** copy it.
  cp <credentials_dir>/upload-keystore.jks <game>/android/upload-keystore.jks
  • **If it is missing:** generate a new keystore with `keytool`. Use the alias and password

defined in `config.md` `android.key_alias` (default: `upload`). Store and key passwords are both `<keystore-password>`.

  keytool -genkey -v \
    -keystore <game>/android/upload-keystore.jks \
    -alias upload \
    -keyalg RSA -keysize 2048 -validity 10000 \
    -storepass <keystore-password> -keypass <keystore-password> \
    -dname "CN=<company>, OU=Dev, O=<company>, L=Seoul, S=Seoul, C=KR"

android/key.properties

Write `<game>/android/key.properties` by substituting the `templates/key.properties.template` values (placeholders are already concrete — the template uses literal values matching the keystore generated above):

storePassword=<keystore-password>
keyPassword=<keystore-password>
keyAlias=upload
storeFile=upload-keystore.jks

The `storeFile` path is relative to the `android/` directory, which is where Gradle reads it.

---

Phase 2 — Fastlane Config Generation

Generate fastlane `Appfile` and `Fastfile` for both platforms by substituting the following placeholders in the templates located at `templates/fastlane/`:

| Placeholder | Value | |---|---| | `__APP_ID__` | `bundle_id` from `config.md` | | `__PACKAGE__` | `bundle_id` from `config.md` | | `__IPA_NAME__` | `<app_name>.ipa` (spaces allowed; use the value of `app_name` verbatim) | | `__PROFILE_NAME__` | `<bundle_id> AppStore` (e.g. `com.<company>.mygame AppStore`) |

Note: `__PROFILE_NAME__` is used both as the Xcode code-signing profile name and as the `.mobileprovision` filename (with `.mobileprovision` appended by fastlane). Spaces are acceptable.

iOS fastlane

mkdir -p <game>/ios/fastlane/certs
# Write Appfile
sed -e 's/__APP_ID__/<bundle_id>/g' \
    templates/fastlane/ios-Appfile.template \
    > <game>/ios/fastlane/Appfile
# Write Fastfile
sed -e 's/__APP_ID__/<bundle_id>/g' \
    -e 's/__IPA_NAME__/<app_name>.ipa/g' \
    -e 's/__PROFILE_NAME__/<bundle_id> AppStore/g' \
    templates/fastlane/ios-Fastfile.template \
    > <game>/ios/fastlane/Fastfile

Android fastlane

mkdir -p <game>/android/fastlane
# Write Appfile
sed -e 's/__PACKAGE__/<bundle_id>/g' \
    templates/fastlane/android-Appfile.template \
    > <game>/android/fastlane/Appfile
# Write Fastfile
sed -e 's/__PACKAGE__/<bundle_id>/g' \
    templates/fastlane/android-Fastfile.template \
    > <game>/android/fastlane/Fastfile

After substitution, verify with `grep '__' <game>/ios/fastlane/Appfile <game>/ios/fastlane/Fastfile <game>/android/fastlane/Appfile <game>/android/fastlane/Fastfile` — output must be empty (no unresolved placeholders).

---

Phase 3 — Build and Upload

Run all build commands from the game root (`<projects-dir>/<app_slug>/`).

Pre-build platform requirements

Before building, ensure the platform items in `docs/game-gotchas.md` (Build/platform + Store rejections) are in place — these are submit-blockers if missing: iOS `PrivacyInfo.xcprivacy` registered (iOS 17+), Android `minSdk = 23` + core-library desugaring, iOS `Podfile` platform bumped, `Info.plist` ATT + `SKAdNetworkItems`, and `ITSAppUsesNonExemptEncryption = false` (skip the export-compliance prompt). **Bump the build number on every upload** — App Store Connect rejects a duplicate build number, so increment it (don't reuse `1`).

**Re-run / resume safety (store uploads are NOT idempotent):** if this phase is re-entered after a pa

Read more
@tjdrhs90
Ships withflutter-flame-harness

An autonomous game launch harness for Claude Code, Google Antigravity, and OpenAI Codex that takes a Flutter/Flame game from raw idea all the way to the app stores.

Stars on GitHub

Momentum

stars in total
61
Star history of tjdrhs90/flutter-flame-harness on GitHub, a chart by star-history.com

Other skills on flutter-flame-harness.

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify10d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel12d16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

pinme2mo3.8k
@glitternetwork@glitternetworkInstall Skill

Questions about flame-harness-build.

Which coding agents can use flame-harness-build?
flame-harness-build installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.