Command-line tool for Flutter project setup, GitHub repository management, iOS/Android deployment automation, and CI/CD configuration.
Current method (before first release):
# Clone and install
git clone https://github.com/sushidev-team/ft.git
cd ft
./setup.shAfter first release (coming soon):
# One-line install
curl -fsSL https://raw.githubusercontent.com/sushidev-team/ft/main/install.sh | bashThe installer will:
- ✅ Download the latest release binary
- ✅ Install to
/usr/local/bin - ✅ Check for GitHub CLI
- ✅ Auto-update if already installed
# Authenticate with GitHub
gh auth login
# Create new Flutter project
ft new
# Setup everything interactively
ft fastlane:setup
ft match:setup
ft android:keystore
ft actions:setup# Update to latest version
curl -fsSL https://raw.githubusercontent.com/sushidev-team/ft/main/install.sh | bash
# Or install specific version
curl -fsSL https://raw.githubusercontent.com/sushidev-team/ft/main/install.sh | bash -s -- v1.0.0- macOS or Linux (Windows coming soon)
- GitHub CLI (gh) - auto-installed by installer
- Flutter (optional) - for Flutter projects
- Ruby/Bundler (optional) - for Fastlane
Build from source
Method 1: Using Makefile (recommended)
# Clone repository
git clone https://github.com/sushidev-team/ft.git
cd ft
# Build with automatic version from git tags
make build
# Install to /usr/local/bin
make install
# Or just build without installing
make buildMethod 2: Using setup.sh
# Clone repository
git clone https://github.com/sushidev-team/ft.git
cd ft
# Run setup script (builds and offers to install)
./setup.shMethod 3: Manual build
# Clone repository
git clone https://github.com/sushidev-team/ft.git
cd ft
# Build with version injection
VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
go build -ldflags "-X main.version=${VERSION}" -o ft .
# Install manually
sudo mv ft /usr/local/bin/Requirements:
- Go 1.16+
- Git (for automatic version detection)
How versioning works:
- Version is automatically set from git tags at build time
- Format:
v1.0.0(release),v1.0.0-4-g341cd1a(development) - No need to manually update version numbers in code
ft new - Create new GitHub repository
- Detects existing repos
- Auto-clones or creates new
- Offers Flutter project setup
- Configures secrets, Fastlane, Match, Android keystore, GraphQL, GitHub Actions
ft secrets:sync - Sync .env to GitHub Secrets
- Parses .env file
- Uploads all values as repository secrets
- Handles _FILE variables (reads file content)
- Skips GITHUB_ prefix (reserved)
ft fastlane:setup - Setup Fastlane
- Creates fastlane directory
- Copies Fastfile, Appfile, Matchfile templates
- Replaces [KEY] placeholders with .env values
- Installs dependencies with Bundler
ft fastlane:update - Update Fastlane files
- Re-replaces placeholders with current .env values
- Use after updating .env
ft match:password - Generate MATCH_PASSWORD
- Creates secure 20-character password
- Updates .env file
- Offers GitHub secrets sync
ft match:setup - Setup Match certificates repository
- Creates {repo-name}-cert repository on GitHub
- Updates .env with MATCH_GIT_URL
- Generates MATCH_GIT_BASIC_AUTHORIZATION
- Syncs secrets to GitHub
- Creates iOS App Store certificates
ft match:test - Test Match setup
- Verifies .env configuration
- Clones Match repository
- Shows certificates, profiles, git log
- Triggers match:setup on failure
ft android:keystore - Create Android keystore
- Prompts for password (min 6 chars)
- Generates key.jks using keytool
- Creates key.properties file
- Base64-encodes keystore for GitHub Secret
- Adds to .gitignore
- Offers GitHub secrets sync
ft identifier:sync - Sync app identifier
- Reads IDENTIFIER from .env
- Updates iOS PRODUCT_BUNDLE_IDENTIFIER
- Updates Android applicationId
- Creates backups before changes
ft install:ios - Install iOS CocoaPods dependencies
- Runs pod install in ios/ directory
- Creates Podfile from template if not exists
- Updates Pods and dependencies
ft update:check - Check for available updates
- Compares current version with latest GitHub release
- Shows update information and release notes
- Offers to install update automatically
- Runs install.sh script if confirmed
ft build:ios - Build iOS IPA locally
- Simulates GitHub Actions environment
- Creates temporary keychain
- Runs fastlane ios build_ipa_adhoc
- Outputs to ios_build_local.log
- Cleans up keychain after build
ft prebuild - Run Flutter build_runner
- Generates code using build_runner
- Deletes conflicting outputs automatically
ft gql:setup - Setup GraphQL code generation
- Copies build.yaml template
- Replaces [APP] placeholder
- Installs Ferry dependencies
- Creates lib/graphql directory
ft gql:fetch - Fetch GraphQL schema
- Shows list of available schemas
- Allows custom URL input
- Auto-installs get-graphql-schema (npm)
- Saves to lib/graphql/schema.graphql
- Runs build_runner after fetch
ft actions:setup - Setup GitHub Actions workflow
- Creates .github/workflows directory
- Copies build-and-deploy.yml template
- Replaces [APP] placeholders
- Configures Android/iOS builds
- Sets up TestFlight/Play Store deployment
- Includes Slack notifications (success/failure)
ft env:refresh - Refresh .env from template
- Updates .env.example in repository
- Copies embedded template from ft binary
- Preserves existing values from current .env
- Removes corrupted/invalid entries
- Only keeps keys defined in template
- Shows table of all environment variables with status
- Offers to sync secrets to GitHub
All commands support:
--path=<dir>- Target directory (default: current directory)--help- Show command-specific help
Additional flags:
gql:setup --app=<name>- App name for GraphQL setupactions:setup --app=<name>- App name for GitHub Actions
# 1. Install ft
curl -fsSL https://raw.githubusercontent.com/sushidev-team/ft/main/install.sh | bash
# 2. Authenticate
gh auth login
# 3. Create repository
ft new
# Enter: my-app
# Select: Personal account
# Choose: Private
# Confirm: Yes to Flutter, Yes to all setup steps
# 4. Project is now ready with:
# ✓ Flutter project with CocoaPods installed
# ✓ .env file
# ✓ Fastlane configured
# ✓ Match certificates created
# ✓ Android keystore generated
# ✓ GraphQL setup (optional)
# ✓ GitHub Actions workflow
# ✓ All secrets synced to GitHub
# 5. Optional: Add Slack notifications
echo "SLACK_WEBHOOK_URL=https://hooks.slack.com/..." >> .env
ft secrets:sync
# 6. Make changes and commit
git add .
git commit -m "Initial setup"
git push
# 7. GitHub Actions automatically builds and deploys!APP_NAME=myapp
IDENTIFIER=com.example.myapp
TEAM_ID=ABCD123456
TEAM_ID_ITC=ABCD123456
APPLE_ID=user@example.com
MATCH_GIT_URL=https://github.com/user/repo-cert.git
MATCH_PASSWORD=secure_password
MATCH_GIT_BASIC_AUTHORIZATION=base64_encoded_token
GH_USERNAME=username
GH_TOKEN=ghp_xxxxx
APP_STORE_CONNECT_API_KEY_ID=KEYID123
APP_STORE_CONNECT_ISSUER_ID=xxxxx-xxxxx
APP_STORE_CONNECT_API_KEY_FILE=~/Downloads/AuthKey_XXX.p8
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_FILE=~/Downloads/service-account.json
ANDROID_KEYSTORE_BASE64=base64_encoded_keystore
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URLMATCH_PASSWORDMATCH_GIT_URLMATCH_GIT_BASIC_AUTHORIZATIONAPP_STORE_CONNECT_API_KEY_IDAPP_STORE_CONNECT_ISSUER_IDAPP_STORE_CONNECT_API_KEY_CONTENTGOOGLE_PLAY_SERVICE_ACCOUNT_JSONANDROID_KEYSTORE_BASE64ANDROID_KEY_PROPERTIESSLACK_WEBHOOK_URL(optional, for build notifications)
ft/
├── main.go # Main command routing
├── github.go # GitHub, GraphQL, secrets management
├── fastlane.go # iOS/Android build, Match, keystore
├── android.go # Android keystore creation
├── env.go # Environment variable management
├── prompts.go # Interactive prompts
├── install.sh # One-line installer
├── templates/
│ ├── app/.env.example
│ ├── ios/Podfile # CocoaPods configuration
│ ├── fastlane/ # Fastfile, Appfile, Matchfile, Gemfile
│ ├── gql/build.yaml
│ └── github/build-and-deploy.yml
└── README.md
# Install/update iOS dependencies
ft install:ios
# Auto-creates Podfile if missing
# Uses optimized template with COCOAPODS_DISABLE_STATS
# Perfect for CI/CD environmentsft build:ios
# Simulates GitHub Actions locally
# Check: ios_build_local.logft match:test
# Shows certificates, profiles, git history
# Offers to run match:setup if failed# Refresh .env from template (preserves values)
ft env:refresh
# Shows table of all variables with status
# ✅ Set or ⚠️ Empty
# Offers to sync to GitHub
# Update specific values
echo "IDENTIFIER=com.newapp.id" >> .env
ft identifier:sync # Updates all iOS/Android configs
ft secrets:sync # Sync to GitHub# Check if newer version is available
ft update:check
# If update available:
# - Shows current and latest version
# - Displays release date and notes
# - Offers to install update automatically
# - Runs install.sh script if confirmed
# Example output when update available:
# 🎉 Update available!
# Released: 2025-10-14
# View release: https://github.com/...
#
# Install update now? (Y/n):The GitHub Actions workflow includes optional Slack notifications for build success/failure.
1. Create Slack Incoming Webhook:
1. Go to https://api.slack.com/apps
2. Create new app or select existing
3. Enable "Incoming Webhooks"
4. Add new webhook to workspace
5. Copy webhook URL
2. Add to GitHub Secrets:
# Add SLACK_WEBHOOK_URL to .env
echo "SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL" >> .env
# Sync to GitHub
ft secrets:sync3. Notification Format:
- ✅ Success: Shows build details, branch, commit, author, "View Workflow" button
- ❌ Failure: Shows which platform failed (Android/iOS), details, red "View Workflow" button
GitHub CLI not authenticated:
gh auth loginMatch certificates failed:
ft match:test # Run diagnostics
ft match:setup # Recreate certificatesiOS build failed locally:
tail -100 ios_build_local.log
# Check for:
# - Provisioning profile mismatch
# - Code signing identity not found
# - Xcode version mismatchAndroid keystore exists:
- Command will prompt for overwrite
- Backup is created automatically
# Build
go build -o ft .
# Run directly
go run . new
# Test specific command
./ft match:test --path=./test-projectMIT