
Gpc Migrate Fastlane
- 23 installs
- 1 repo stars
- Updated August 1, 2026
- yasserstudio/gpc-skills
Helps with ai & agent building tasks.
About
gpc-migrate-fastlane is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- gpc-migrate-fastlane
- AI & Agent Building
- AI-coding skill
Gpc Migrate Fastlane by the numbers
- 23 all-time installs (skills.sh)
- Ranked #10,032 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yasserstudio/gpc-skills --skill gpc-migrate-fastlaneAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 23 |
|---|---|
| repo stars | ★ 1 |
| Last updated | August 1, 2026 |
| Repository | yasserstudio/gpc-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
gpc-migrate-fastlane
Complete guide for migrating from Fastlane supply to GPC.
When to use
- Migrating from Fastlane supply to GPC (partial or full)
- Running GPC alongside Fastlane during a transition period
- Comparing Fastlane and GPC commands
- Converting Fastlane CI workflows to GPC
- Understanding metadata directory compatibility
Inputs required
- Existing Fastlane setup — Fastfile, Appfile, metadata directory
- Service account key — same key file works for both tools
- App package name — from Appfile or Fastfile configuration
Procedure
1. Assess current Fastlane usage
Identify which Fastlane supply features you use:
# Check your Fastfile for supply lanes
cat fastlane/Fastfile | grep -A 10 'supply'
# Check metadata directory
ls fastlane/metadata/android/
# Check Appfile for config
cat fastlane/Appfile2. Install GPC (keep Fastlane installed)
npm install -g @gpc-cli/cliBoth tools can coexist — they share the same service account keys and metadata directory structure.
3. Authenticate with the same service account
# Use the same key file from Fastlane
gpc auth login --service-account path/to/play-store-key.json
# Or set via environment variable (same as SUPPLY_JSON_KEY)
export GPC_SERVICE_ACCOUNT=$(cat path/to/play-store-key.json)
# Configure default app (from your Appfile)
gpc config set app com.example.app
# Verify
gpc doctor4. Map your Fastlane commands to GPC
Read: references/command-mapping.md for the complete command mapping table.
Key mappings:
# Upload AAB
# Fastlane: fastlane supply --aab app.aab --track beta
# GPC:
gpc releases upload app.aab --track beta
# Upload with rollout
# Fastlane: fastlane supply --aab app.aab --track production --rollout 0.1
# GPC: (note: percentage, not decimal)
gpc releases upload app.aab --track production --rollout 10
# Download metadata
# Fastlane: fastlane supply --download_metadata --metadata_path metadata/
# GPC:
gpc listings pull --dir metadata/
# Push metadata
# Fastlane: fastlane supply --skip_upload_aab --metadata_path metadata/
# GPC:
gpc listings push --dir metadata/
# Upload screenshots (one-shot)
# Fastlane: fastlane supply --skip_upload_aab --skip_upload_metadata
# GPC:
gpc listings images upload --lang en-US --type phoneScreenshots *.png
# Sync screenshots from a directory (v0.9.69+ — equivalent to Fastlane's sync_image_upload)
# SHA-256 content hashing: only uploads new/changed files; --delete removes extras remotely.
gpc listings images sync --lang en-US --type phoneScreenshots --dir ./screenshots/en-US/ --delete
# In-app update priority (v0.9.70+ — equivalent to Fastlane's in_app_update_priority)
# Fastlane: supply(in_app_update_priority: 3)
# GPC:
gpc releases upload app.aab --track production --in-app-update-priority 3
# Retain previous version codes (v0.9.70+)
# Fastlane: supply(version_codes_to_retain: [40, 41])
# GPC:
gpc releases upload app.aab --track internal --retain-version-codes 40,41
# Fastlane-style versioned changelogs (v0.9.70+)
# If your changelogs/ directory uses the Fastlane layout:
# changelogs/en-US/42.txt, changelogs/en-US/default.txt, changelogs/ja-JP/default.txt
# GPC auto-detects the structure. Reads {versionCode}.txt first, falls back to default.txt.
gpc releases upload app.aab --track production --notes-dir changelogs/5. Test with dry-run
Before switching any CI pipeline, verify GPC produces the same results:
# Preview metadata push (no changes applied)
gpc listings push --dir fastlane/metadata/android/ --dry-run
# Preview upload (validates AAB without uploading)
gpc validate app.aab
# Compare listing output
gpc listings view --lang en-US --json6. Migrate CI configuration
Read: references/ci-migration.md for platform-specific CI migration examples.
Replace Fastlane supply calls in your CI with GPC equivalents:
# Before (GitHub Actions with Fastlane)
- name: Deploy to beta
run: bundle exec fastlane supply --aab app.aab --track beta
# After (GitHub Actions with GPC)
- name: Deploy to beta
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SA_KEY }}
GPC_APP: com.example.app
run: npx @gpc-cli/cli releases upload app.aab --track beta7. Clean up Fastlane (optional)
Once fully migrated and confident:
# Remove Fastlane files
rm -rf fastlane/Fastfile fastlane/Appfile fastlane/Pluginfile
rm Gemfile Gemfile.lock
# Keep metadata directory — GPC uses the same structure
# fastlane/metadata/android/ → works with both toolsNote: The metadata directory (fastlane/metadata/android/) is fully compatible. You can rename it if you want (e.g., metadata/) — just update the --dir flag.
Verification
gpc doctorpasses all checksgpc listings push --dir fastlane/metadata/android/ --dry-runshows no errorsgpc releases upload app.aab --track internal --dry-runvalidates the bundle- CI pipeline runs successfully with GPC commands
- Metadata and screenshots match what was uploaded via Fastlane
Failure modes / debugging
| Symptom | Likely Cause | Fix |
|---|---|---|
| Auth fails with same key | Key path differs between tools | Use absolute path or GPC_SERVICE_ACCOUNT env var |
| Metadata push shows no changes | GPC already matches Play Store | This is expected — both tools read the same source |
| Rollout percentage wrong | Fastlane uses decimal (0.1), GPC uses percentage (10) | Convert: multiply Fastlane value by 100 |
| Screenshots missing after push | GPC listings push doesn't push images | Use gpc listings images upload separately |
| CI slower than Fastlane | Ruby/Bundler vs Node.js startup | Use npx @gpc-cli/cli or pre-install globally; both are fast |
EDIT_CONFLICT error | Fastlane and GPC both have open edits | Don't run both tools simultaneously on the same app |
changesNotSentForReview 403 on commit | App has a rejected update — was Fastlane supply's #1 failure point | v0.9.69+: gpc releases commit auto-rescues this by retrying with the correct flag. No manual intervention needed. |
Related skills
- gpc-setup — initial authentication and configuration
- gpc-metadata-sync — detailed metadata management beyond migration
- gpc-release-flow — full release lifecycle with GPC
- gpc-ci-integration — CI/CD pipeline setup with GPC
{
"skill_name": "gpc-migrate-fastlane",
"evals": [
{
"id": 1,
"prompt": "We currently use Fastlane supply in our GitHub Actions workflow to upload AABs to the beta track. The workflow uses SUPPLY_JSON_KEY_DATA secret and runs bundle exec fastlane supply --aab app.aab --track beta. How do I switch this to gpc without changing our service account?",
"expected_output": "Shows the GPC equivalent workflow replacing Fastlane, using the same service account key",
"files": [],
"expectations": [
"Maps SUPPLY_JSON_KEY_DATA to GPC_SERVICE_ACCOUNT env var",
"Replaces bundle exec fastlane supply with npx gpc releases upload",
"Shows a complete GitHub Actions YAML snippet with GPC",
"Mentions that the same service account key file works for both tools",
"Removes Ruby/Bundler setup steps and replaces with Node.js"
]
},
{
"id": 2,
"prompt": "I want to use gpc but keep Fastlane around for a while as a fallback. Our metadata is at fastlane/metadata/android/ with 8 languages. Can both tools work with the same metadata directory? What should I test first?",
"expected_output": "Confirms directory compatibility and shows how to test GPC with existing Fastlane metadata",
"files": [],
"expectations": [
"Confirms GPC reads the same Fastlane metadata directory structure natively",
"Shows gpc listings push --dir fastlane/metadata/android/ --dry-run for safe testing",
"Explains both tools can coexist without conflicts",
"Warns about not running both tools simultaneously (edit conflicts)",
"Suggests gpc doctor to verify the setup before switching"
]
},
{
"id": 3,
"prompt": "Our Fastlane setup does: upload AAB to beta, wait for QA approval, then promote to production at 10% rollout. The rollout uses --rollout 0.1 in Fastlane. I also want to add crash rate checking before promotion which Fastlane can't do. How does this translate to gpc?",
"expected_output": "Shows complete pipeline with upload, vitals check, and promotion with correct rollout percentage",
"files": [],
"expectations": [
"Shows gpc releases upload with --track beta",
"Notes rollout difference: Fastlane 0.1 = GPC 10 (percentage vs decimal)",
"Shows gpc vitals crashes --threshold with a recommended value",
"Shows gpc releases promote --from beta --to production --rollout 10",
"Highlights this as a capability GPC has that Fastlane doesn't"
]
}
]
}
CI Migration: Fastlane → GPC
Platform-specific examples for replacing Fastlane supply with GPC in CI pipelines.
GitHub Actions
Before (Fastlane)
name: Deploy
on:
push:
tags: ['v*']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Deploy to beta
env:
SUPPLY_JSON_KEY_DATA: ${{ secrets.PLAY_SA_KEY }}
run: bundle exec fastlane supply --aab app.aab --track betaAfter (GPC)
name: Deploy
on:
push:
tags: ['v*']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Deploy to beta
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.PLAY_SA_KEY }}
GPC_APP: com.example.app
run: npx @gpc-cli/cli releases upload app.aab --track betaKey differences:
- No Ruby/Bundler setup needed
SUPPLY_JSON_KEY_DATA→GPC_SERVICE_ACCOUNTbundle exec fastlane supply→npx @gpc-cli/cli releases upload- Add
GPC_APP(Fastlane reads from Appfile)
GitLab CI
Before (Fastlane)
deploy:
image: ruby:3.2
stage: deploy
only: [tags]
before_script:
- bundle install
script:
- bundle exec fastlane supply --aab app.aab --track betaAfter (GPC)
deploy:
image: node:20
stage: deploy
only: [tags]
variables:
GPC_SERVICE_ACCOUNT: $PLAY_SA_KEY
GPC_APP: com.example.app
script:
- npx @gpc-cli/cli releases upload app.aab --track betaBitbucket Pipelines
Before (Fastlane)
pipelines:
tags:
'v*':
- step:
image: ruby:3.2
script:
- bundle install
- bundle exec fastlane supply --aab app.aab --track betaAfter (GPC)
pipelines:
tags:
'v*':
- step:
image: node:20
script:
- npx @gpc-cli/cli releases upload app.aab --track betaSecrets migration
| CI Platform | Fastlane Secret | GPC Secret |
|---|---|---|
| GitHub Actions | PLAY_SA_KEY (as SUPPLY_JSON_KEY_DATA) | PLAY_SA_KEY (as GPC_SERVICE_ACCOUNT) |
| GitLab CI | PLAY_SA_KEY variable | PLAY_SA_KEY variable |
| Bitbucket | PLAY_SA_KEY repository variable | PLAY_SA_KEY repository variable |
The same secret value works — just change the environment variable name.
Added benefits after migration
Once on GPC, you can add these capabilities that Fastlane doesn't have:
# Vitals gating before production promotion
- name: Check vitals
run: npx @gpc-cli/cli vitals crashes --threshold 1.5
# Staged rollout with percentage control
- name: Promote with rollout
run: npx @gpc-cli/cli releases promote --from beta --to production --rollout 10
# Step summary in GitHub Actions (via plugin-ci)
- name: Upload with summary
run: npx @gpc-cli/cli releases upload app.aab --track beta
# Automatically writes to $GITHUB_STEP_SUMMARYFastlane → GPC Command Mapping
Complete mapping of Fastlane supply commands to GPC equivalents.
Uploads and releases
| Fastlane | GPC |
|---|---|
supply --aab app.aab --track internal | gpc releases upload app.aab --track internal |
supply --aab app.aab --track beta | gpc releases upload app.aab --track beta |
supply --aab app.aab --track production | gpc releases upload app.aab --track production |
supply --aab app.aab --track production --rollout 0.1 | gpc releases upload app.aab --track production --rollout 10 |
supply --apk app.apk --track beta | gpc releases upload app.apk --track beta |
Rollout difference: Fastlane uses decimal (0.0–1.0), GPC uses percentage (0–100).
Metadata
| Fastlane | GPC |
|---|---|
supply --download_metadata --metadata_path dir/ | gpc listings pull --dir dir/ |
supply --skip_upload_aab --metadata_path dir/ | gpc listings push --dir dir/ |
supply --skip_upload_aab --skip_upload_metadata | gpc listings images upload --lang en-US --type phoneScreenshots *.png |
Track promotion
| Fastlane | GPC |
|---|---|
supply --track_promote_to production --track beta | gpc releases promote --from beta --to production |
| (no direct equivalent) | gpc releases rollout increase --track production --rollout 50 |
| (no direct equivalent) | gpc releases rollout halt --track production |
| (no direct equivalent) | gpc releases rollout complete --track production |
GPC provides granular rollout control that Fastlane doesn't support natively.
Release notes
| Fastlane | GPC |
|---|---|
supply --aab app.aab --track beta --release_notes "..." | gpc releases upload app.aab --track beta --release-notes "en-US=..." |
Changelogs in metadata/android/en-US/changelogs/142.txt | gpc releases upload --release-notes-dir release-notes/ |
Release-notes automation (v0.9.62+): Fastlane users manage per-locale metadata/android/<lang>/changelogs/<version>.txt files by hand. GPC v0.9.62+ can generate them from your git log:
gpc changelog generate --target play-store --locales auto --format json --app com.example.appPair with --ai (v0.9.63+) for automatic LLM translation and --apply (v0.9.64+) to write translated notes directly into the draft release. End-to-end: gpc changelog generate --target play-store --locales auto --ai --apply.
App information
| Fastlane | GPC |
|---|---|
supply --validate_only | gpc validate app.aab |
supply --json_key key.json | gpc auth login --service-account key.json |
supply --package_name com.example.app | gpc config set app com.example.app or --app com.example.app |
Environment variables
| Fastlane | GPC |
|---|---|
SUPPLY_JSON_KEY | GPC_SERVICE_ACCOUNT |
SUPPLY_JSON_KEY_DATA | GPC_SERVICE_ACCOUNT (accepts JSON content directly) |
SUPPLY_PACKAGE_NAME | GPC_APP |
| (no equivalent) | GPC_TIMEOUT, GPC_MAX_RETRIES, GPC_BASE_DELAY |
| (no equivalent) | GPC_DEBUG=1 |
Features GPC has that Fastlane doesn't
| Feature | GPC Command |
|---|---|
| Validate bundle | gpc validate app.aab |
| Staged rollout control | gpc releases rollout increase/halt/complete |
| Vitals monitoring | gpc vitals crashes/anr --threshold |
| Review management | gpc reviews list/reply |
| Subscription management | gpc subscriptions create/update |
| IAP sync | gpc iap sync --dir |
| User/tester management | gpc users invite, gpc testers add |
| Dry-run mode | --dry-run on all write commands |
| JSON output | --json on all commands |
| Plugin system | @gpc-cli/plugin-sdk |
| Threshold-gated CI | Exit code 6 on vitals breach |
#!/usr/bin/env node
/**
* Detection script for GPC CLI.
* Returns JSON with installation status, version, auth state, and config.
* Used by Claude Code skill system for deterministic environment detection.
*
* Exit codes:
* 0 — GPC detected (may or may not be authenticated)
* 1 — GPC not found
*/
import { execSync } from "node:child_process";
import { existsSync } from "node:fs";
import { join } from "node:path";
function run(cmd) {
try {
return execSync(cmd, { encoding: "utf-8", timeout: 10000 }).trim();
} catch {
return null;
}
}
const result = {
installed: false,
version: null,
installMethod: null,
authStatus: null,
authMethod: null,
profile: null,
envAuth: false,
defaultApp: null,
configFile: null,
nodeVersion: process.version,
};
// Check if gpc is installed globally
const versionOutput = run("gpc --version");
if (!versionOutput) {
// Try npx
const npxVersion = run("npx gpc --version 2>/dev/null");
if (!npxVersion) {
console.log(JSON.stringify(result, null, 2));
process.exit(1);
}
result.version = npxVersion;
result.installed = true;
result.installMethod = "npx";
} else {
result.version = versionOutput;
result.installed = true;
result.installMethod = "global";
}
// Check auth status
const authOutput = run("gpc auth status --json 2>/dev/null");
if (authOutput) {
try {
const auth = JSON.parse(authOutput);
result.authStatus = auth.status || "unknown";
result.authMethod = auth.method || null;
result.profile = auth.profile || null;
} catch {
result.authStatus = "parse_error";
}
}
// Check for env-based auth
if (process.env.GPC_SERVICE_ACCOUNT) {
result.envAuth = true;
}
// Check default app
const configOutput = run("gpc config get app --json 2>/dev/null");
if (configOutput) {
try {
const config = JSON.parse(configOutput);
result.defaultApp = config.value || config.app || null;
} catch {
result.defaultApp = configOutput || null;
}
}
// Check for .gpcrc.json in current directory
const rcPath = join(process.cwd(), ".gpcrc.json");
if (existsSync(rcPath)) {
result.configFile = rcPath;
}
console.log(JSON.stringify(result, null, 2));
process.exit(0);