Claude-skill-registry android-fastlane-setup

Setup Fastlane for Play Store deployment with supply and screengrab

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/android-fastlane-setup" ~/.claude/skills/majiayu000-claude-skill-registry-android-fastlane-setup && rm -rf "$T"
manifest: skills/data/android-fastlane-setup/SKILL.md
source content

Android Fastlane Setup

Configures Fastlane with

supply
for Play Store deployment and
screengrab
for screenshot automation.

Prerequisites

  • Ruby 2.7+ installed
  • Android project
  • Play Store service account JSON

Inputs

InputRequiredDefaultDescription
package_nameYes-Android app package name (e.g., com.example.app)
service_account_pathYes-Path to service account JSON file

Process

Step 1: Check Ruby Installation

# Check Ruby version
ruby --version || echo "❌ Ruby not found. Please install Ruby 2.7+ first."

# Install Bundler if needed
gem install bundler --no-document

Step 2: Create Gemfile

Create

./Gemfile
:

source "https://rubygems.org"

gem "fastlane"
gem "screengrab"

Step 3: Install Dependencies

bundle install

This will create

Gemfile.lock
and install all dependencies.

Step 4: Create Fastlane Directory Structure

mkdir -p fastlane
mkdir -p fastlane/metadata/android/en-US/images/phoneScreenshots
mkdir -p fastlane/metadata/android/en-US/images/sevenInchScreenshots
mkdir -p fastlane/metadata/android/en-US/images/tenInchScreenshots
mkdir -p fastlane/metadata/android/en-US/changelogs

Step 5: Create Appfile

Create

./fastlane/Appfile
:

# Path to service account JSON for Play Store API
json_key_file(ENV['PLAY_STORE_SERVICE_ACCOUNT'] || "service-account.json")

# Your app's package name
package_name("{PACKAGE_NAME}")

Important: Replace

{PACKAGE_NAME}
with the actual package name.

Step 6: Create Fastfile

Create

./fastlane/Fastfile
with comprehensive deployment lanes:

default_platform(:android)

platform :android do
  # ============================================
  # Build Lanes
  # ============================================

  desc "Build debug APK and test APK for screenshots"
  lane :build_for_screenshots do
    gradle(task: "clean")
    gradle(task: "assembleDebug")
    gradle(task: "assembleAndroidTest")
  end

  desc "Build release bundle"
  lane :build_release do
    gradle(task: "clean")
    gradle(task: "bundleRelease")
  end

  # ============================================
  # Screenshot Lane
  # ============================================

  desc "Capture screenshots for Play Store"
  lane :screenshots do
    build_for_screenshots
    capture_android_screenshots
  end

  # ============================================
  # Deployment Lanes
  # ============================================

  desc "Deploy to internal testing track"
  lane :deploy_internal do
    build_release
    upload_to_play_store(
      track: "internal",
      release_status: "completed",
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end

  desc "Deploy to beta/closed testing track"
  lane :deploy_beta do |options|
    build_release

    # Support staged rollout
    rollout = options[:rollout] || 1.0

    upload_to_play_store(
      track: "beta",
      release_status: rollout < 1.0 ? "inProgress" : "completed",
      rollout: rollout < 1.0 ? rollout.to_s : nil,
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end

  desc "Deploy to production track"
  lane :deploy_production do |options|
    build_release

    # Default to 10% staged rollout for safety
    rollout = options[:rollout] || 0.1

    upload_to_play_store(
      track: "production",
      release_status: rollout < 1.0 ? "inProgress" : "completed",
      rollout: rollout < 1.0 ? rollout.to_s : nil,
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end

  desc "Increase production rollout percentage"
  lane :increase_rollout do |options|
    rollout = options[:rollout] || 0.5

    upload_to_play_store(
      track: "production",
      release_status: rollout < 1.0 ? "inProgress" : "completed",
      rollout: rollout < 1.0 ? rollout.to_s : nil,
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true
    )
  end

  desc "Halt production rollout"
  lane :halt_rollout do
    upload_to_play_store(
      track: "production",
      release_status: "halted",
      skip_upload_aab: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true
    )
  end

  # ============================================
  # Metadata Lanes
  # ============================================

  desc "Upload metadata only (no APK/AAB)"
  lane :upload_metadata do
    upload_to_play_store(
      skip_upload_aab: true,
      skip_upload_apk: true
    )
  end

  desc "Upload screenshots only"
  lane :upload_screenshots do
    upload_to_play_store(
      skip_upload_aab: true,
      skip_upload_apk: true,
      skip_upload_metadata: true
    )
  end

  # ============================================
  # Version Management
  # ============================================

  desc "Get current version from version.properties"
  lane :get_version do
    version_file = "../version.properties"
    if File.exist?(version_file)
      props = {}
      File.readlines(version_file).each do |line|
        key, value = line.strip.split("=")
        props[key] = value if key && value
      end
      UI.message("Version: #{props['VERSION_NAME']} (#{props['VERSION_CODE']})")
      props
    else
      UI.user_error!("version.properties not found. Run /devtools:version-management first.")
    end
  end

  # ============================================
  # Full Release Workflows
  # ============================================

  desc "Full internal release: screenshots + build + deploy"
  lane :release_internal do
    screenshots
    deploy_internal
  end

  desc "Full beta release: build + deploy"
  lane :release_beta do |options|
    deploy_beta(rollout: options[:rollout])
  end

  desc "Full production release: build + deploy with staged rollout"
  lane :release_production do |options|
    deploy_production(rollout: options[:rollout])
  end
end

Step 7: Create Screengrabfile

Create

./fastlane/Screengrabfile
:

# App package name
app_package_name("{PACKAGE_NAME}")

# Test instrumentation runner (AndroidX)
test_instrumentation_runner("androidx.test.runner.AndroidJUnitRunner")

# APK paths
app_apk_path("app/build/outputs/apk/debug/app-debug.apk")
tests_apk_path("app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk")

# Locales to capture (add more as needed)
locales(["en-US"])

# Output directory (matches supply's expected structure)
output_directory("fastlane/metadata/android")

# Clear old screenshots
clear_previous_screenshots(true)

# Use specific test class for screenshots
use_tests_in_classes(["{PACKAGE_NAME}.screenshots.ScreenshotTest"])

# Ending locale (restore device to this locale after)
ending_locale("en-US")

Important: Replace

{PACKAGE_NAME}
with the actual package name.

Step 8: Create Metadata Templates

Create initial metadata files:

fastlane/metadata/android/en-US/title.txt
:

Your App Name

fastlane/metadata/android/en-US/short_description.txt
:

Short description (max 80 characters)

fastlane/metadata/android/en-US/full_description.txt
:

Full description of your app.

Features:
• Feature 1
• Feature 2
• Feature 3

For more information, visit our website.

fastlane/metadata/android/en-US/changelogs/default.txt
:

• Bug fixes and performance improvements

fastlane/metadata/android/en-US/video.txt
:

(Empty file - add YouTube URL if you have a promo video)

Step 9: Update .gitignore

Add to

.gitignore
:

# Fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
vendor/bundle

# Don't ignore metadata (we want to track store listing)
!fastlane/metadata/

Verification

MANDATORY: Run these commands:

# Verify Fastlane installed
bundle exec fastlane --version

# Verify lanes are available
bundle exec fastlane lanes

# Test service account connection (optional, requires service account JSON)
# bundle exec fastlane run validate_play_store_json_key

Expected output:

  • Fastlane version number
  • List of all lanes (deploy_internal, deploy_beta, etc.)

Completion Criteria

  • Gemfile
    exists with fastlane and screengrab
  • bundle install
    succeeds
  • fastlane/Appfile
    configured with package name
  • fastlane/Fastfile
    has all deployment lanes
  • fastlane/Screengrabfile
    configured
  • Metadata directory structure created
  • Metadata template files created
  • .gitignore
    updated
  • bundle exec fastlane lanes
    shows all lanes

Outputs

OutputLocationDescription
Gemfile./GemfileRuby dependencies
Gemfile.lock./Gemfile.lockLocked dependency versions
Appfile./fastlane/AppfileFastlane app configuration
Fastfile./fastlane/FastfileFastlane lanes
Screengrabfile./fastlane/ScreengrabfileScreenshot configuration
Metadata./fastlane/metadata/android/en-US/Store listing metadata

Troubleshooting

"Ruby not found"

Cause: Ruby not installed Fix: Install Ruby 2.7+ (use rbenv, rvm, or system package manager)

"bundle: command not found"

Cause: Bundler not installed Fix: Run

gem install bundler --no-document

"Fastlane lanes don't show"

Cause: Fastfile has syntax errors Fix: Run

bundle exec fastlane lanes
and check for Ruby syntax errors

"Service account validation fails"

Cause: Invalid or missing service account JSON Fix: Ensure JSON file exists and has correct permissions in Play Console

Next Steps

After completing this skill:

  1. Run
    /devtools:android-app-icon
    to generate app icon
  2. Run
    /devtools:android-screenshot-automation
    to setup screenshot capture
  3. Run
    /devtools:android-store-listing
    to create feature graphic and metadata
  4. Run
    /devtools:android-workflow-internal
    to setup GitHub Actions