agentsclimarketplace

Fastlane setup

Skill almasumdev/awesome-mobile-release-agent-skills/.github/skills/ci_cd/fastlane-setup

Agent skills for mobile release engineering: signing, versioning, store submissions, and rollouts.

Install
npx -y skills add almasumdev/awesome-mobile-release-agent-skills --skill fastlane-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Set up a complete Fastlane pipeline — Fastfile structure, lanes, match, pilot, supply. Use this when introducing Fastlane to an iOS or Android project.

SKILL.md

5.5 KB, as published. Nobody here has run it

Fastlane Setup

Instructions

Fastlane is the lingua franca of mobile release automation. This skill covers the minimum viable Fastfile for iOS + Android, set up so every lane runs identically on a developer laptop and on CI.

1. Install Fastlane

Pin the version in a Gemfile at the repo root:

source "https://rubygems.org"
gem "fastlane", "~> 2.220"
plugins_path = File.join(File.dirname(__FILE__), "fastlane", "Pluginfile")
eval_gemfile(plugins_path) if File.exist?(plugins_path)
bundle config set --local path "vendor/bundle"
bundle install

Run as bundle exec fastlane ... everywhere.

2. Directory Layout

ios/
  fastlane/
    Appfile
    Fastfile
    Matchfile
    Pluginfile
    metadata/
    screenshots/
android/
  fastlane/
    Appfile
    Fastfile
    Pluginfile
    metadata/

Separate fastlane/ dirs per platform keep lanes tidy and allow platform-only lane runs from platform CI jobs.

3. Appfile (iOS)

app_identifier("com.acme.app")
apple_id("[email protected]")
team_id("ABCDE12345")
itc_team_id("109876543")

4. Appfile (Android)

json_key_file("")   # provided via env var PLAY_SERVICE_ACCOUNT_JSON_PATH
package_name("com.acme.app")

5. iOS Fastfile

default_platform(:ios)

platform :ios do
  before_all { setup_ci }

  desc "Install certs & profiles via match"
  lane :certs do
    match(type: "development", readonly: true)
    match(type: "appstore", readonly: true)
  end

  desc "Build and upload to TestFlight"
  lane :beta do
    api_key = asc_api_key
    match(type: "appstore", readonly: true, api_key: api_key)
    build_app(
      workspace: "Runner.xcworkspace",
      scheme: "Runner",
      export_method: "app-store",
      export_options: "ExportOptions.plist",
    )
    upload_to_testflight(
      api_key: api_key,
      skip_waiting_for_build_processing: true,
      changelog: File.read("../CHANGELOG_CURRENT.txt"),
    )
    upload_symbols_to_crashlytics(gsp_path: "Runner/GoogleService-Info.plist")
  end

  desc "Submit latest TestFlight build to App Store Review"
  lane :release do
    deliver(
      api_key: asc_api_key,
      submit_for_review: true,
      automatic_release: false,
      phased_release: true,
      force: true,
      precheck_include_in_app_purchases: false,
    )
  end

  def asc_api_key
    app_store_connect_api_key(
      key_id: ENV["APP_STORE_CONNECT_KEY_ID"],
      issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
      key_content: ENV["APP_STORE_CONNECT_KEY_CONTENT"],
      is_key_content_base64: true,
      duration: 1200,
    )
  end
end

6. Android Fastfile

default_platform(:android)

platform :android do
  desc "Build AAB and upload to Play internal track"
  lane :internal do
    gradle(task: "bundleRelease",
           properties: {
             "versionName" => ENV["VERSION_NAME"],
             "versionCode" => ENV["GITHUB_RUN_NUMBER"],
           })
    upload_to_play_store(
      track: "internal",
      aab: "app/build/outputs/bundle/release/app-release.aab",
      json_key_data: ENV["PLAY_SERVICE_ACCOUNT_JSON"],
      release_status: "completed",
    )
  end

  desc "Promote internal to production at 5%"
  lane :promote_to_production do |options|
    upload_to_play_store(
      track: "internal",
      track_promote_to: "production",
      rollout: options[:rollout] || "0.05",
      skip_upload_aab: true,
      json_key_data: ENV["PLAY_SERVICE_ACCOUNT_JSON"],
    )
  end
end

7. Matchfile

git_url("[email protected]:acme/certificates.git")
storage_mode("git")
type("appstore")
app_identifier(["com.acme.app"])

Encrypted with MATCH_PASSWORD. Store the password in CI secrets.

8. Environment Variables on CI

Minimum env set for a release run:

  • APP_STORE_CONNECT_KEY_ID
  • APP_STORE_CONNECT_ISSUER_ID
  • APP_STORE_CONNECT_KEY_CONTENT (base64 .p8)
  • MATCH_PASSWORD
  • MATCH_GIT_BASIC_AUTHORIZATION or SSH deploy key
  • PLAY_SERVICE_ACCOUNT_JSON
  • KEYSTORE_PATH / KEYSTORE_PASSWORD / KEY_ALIAS / KEY_PASSWORD

9. Common Plugins

ios/fastlane/Pluginfile:

gem "fastlane-plugin-versioning"
gem "fastlane-plugin-firebase_app_distribution"
gem "fastlane-plugin-sentry"

Install: bundle exec fastlane add_plugin firebase_app_distribution.

10. Running Locally vs CI

  • Locally: bundle exec fastlane ios beta — uses your keychain, real Apple ID.
  • CI: the same command — setup_ci creates a scoped temporary keychain; match --readonly never writes to the certs repo.

This parity is the main reason to use Fastlane. Do not introduce CI-only scripts that bypass lanes.

11. Anti-Patterns

  • One giant Fastfile at the repo root mixing platforms.
  • Using --generate_apple_certs in CI (can regenerate the distribution cert and break other teams).
  • Hardcoding paths to build artefacts; use Fastlane variables (SharedValues::IPA_OUTPUT_PATH).
  • Running match in force mode on CI. Always readonly: true.

12. Checklist

  • Gemfile + Gemfile.lock committed; Fastlane pinned.
  • Per-platform fastlane/ directories with Appfile, Fastfile, Matchfile.
  • ASC API key used, not Apple ID + password.
  • match readonly: true in every CI lane.
  • setup_ci called before signing on CI.
  • Same lane names run locally and in CI, producing identical artefacts.
  • Required env vars documented in docs/release-env.md.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.