fastlane: [App Store Connect unification] Spaceship::UnexpectedResponse: [!] Apple provided the following error info: Access Unavailable - You currently don't have access to this membership resource

New Issue Checklist

Issue Description

It looks like sigh may have broken with the recent App Store Connect role unification - https://developer.apple.com/support/teams/

This actually broken on an account that only had access to 1 team. The teamId parameter was not always getting appended to https://developerservices2.apple.com/services/QH65B2/ios/listProvisioningProfiles.action. It only got appended if the team_id was explicitly defined in the match/sigh options

Command executed

match/sigh with the wrong team_id that contained the previous “Developer Portal Team ID”

Possible solution

This actually may be a permission issue where things permission need to be changed from within App Store Connect but that is to be determined.

Complete output when running fastlane, including the stack trace and command used
ERROR [2019-02-12 15:35:05.30]: An error occurred while verifying your certificates and profiles with the Apple Developer Portal.
ERROR [2019-02-12 15:35:05.30]: If you already have your certificates stored in git, you can run `fastlane match` in readonly mode
ERROR [2019-02-12 15:35:05.30]: to just install the certificates and profiles without accessing the Dev Portal.
ERROR [2019-02-12 15:35:05.30]: To do so, just pass `readonly: true` to your match call.
WARN [2019-02-12 15:35:05.30]: Lane Context:
INFO [2019-02-12 15:35:05.30]: {:PLATFORM_NAME=>:ios, :LANE_NAME=>"ios sink_google"}
ERROR [2019-02-12 15:35:05.30]: {"responseId"=>"c84d6ef7-d54b-4b71-a144-c8cbe5f79136", "resultCode"=>1200, "resultString"=>"Access Unavailable", "userString"=>"You currently don't have access to this membership resource. Contact your team's Account Holder, Josh Holtz, or an Admin.", "creationTimestamp"=>"2019-02-12T21:35:05Z", "protocolVersion"=>"QH65B2", "userLocale"=>"en_US", "requestUrl"=>"https://developer.apple.com/services-account/QH65B2/account/ios/identifiers/listAppIds.action", "httpCode"=>200}
INFO [2019-02-12 15:35:05.30]: Successfully generated documentation at path '/Users/josh/Projects/fastlane/test-ios/fastlane/README.md'
+------+--------+-------------+
|      fastlane summary       |
+------+--------+-------------+
| Step | Action | Time (in s) |
+------+--------+-------------+
| 💥   | match  | 7           |
+------+--------+-------------+
DEBUG [2019-02-12 15:35:05.32]: All plugins are up to date
ERROR [2019-02-12 15:35:05.32]: fastlane finished with errors
Looking for related GitHub issues on fastlane/fastlane...
Search query: Apple provided the following error info:
        Access Unavailable
        You currently don't have access to this membership resource. Contact your team's Account Holder, Josh Holtz, or an Admin.
URL: https://api.github.com/search/issues?q=Apple%20provided%20the%20following%20error%20info%3A%0A%09Access%20Unavailable%0A%09You%20currently%20don%27t%20have%20access%20to%20this%20membership%20resource.%20Contact%20your%20team%27s%20Account%20Holder%2C%20Josh%20Holtz%2C%20or%20an%20Admin.+repo:fastlane/fastlane
Found no similar issues. To create a new issue, please visit:
https://github.com/fastlane/fastlane/issues/new
Run `fastlane env` to append the fastlane environment to your issue
DEBUG [2019-02-12 15:35:05.66]: All plugins are up to date
bundler: failed to load command: fastlane (/Users/josh/.gem/ruby/2.3.7/bin/fastlane)
Spaceship::UnexpectedResponse: [!] Apple provided the following error info:
        Access Unavailable
        You currently don't have access to this membership resource. Contact your team's Account Holder, Josh Holtz, or an Admin.

Environment

✅ fastlane environment ✅

Stack

Key Value
OS 10.13.6
Ruby 2.3.7
Bundler? true
Git git version 2.17.2 (Apple Git-113)
Installation Source ~/.gem/ruby/2.3.7/bin/fastlane
Host Mac OS X 10.13.6 (17G65)
Ruby Lib Dir ~/.rubies/ruby-2.3.7/lib
OpenSSL Version OpenSSL 1.0.2o 27 Mar 2018
Is contained false
Is homebrew false
Is installed via Fabric.app false
Xcode Path /Applications/Xcode-10.1.app/Contents/Developer/
Xcode Version 10.1

System Locale

Variable Value
LANG en_US.UTF-8
LC_ALL en_US.UTF-8
LANGUAGE en_US.UTF-8

fastlane files:

`./fastlane/Fastfile`
puts "PRODUCE_APP_IDENTIFIER: #{ENV['PRODUCE_APP_IDENTIFIER']}"

ENV['FASTLANE_HIDE_BACKTRACE'] = '1'

after_all do
  #debug
end

lane :do_task do |options|
  # Execute this lane for all schemes if no
  # 'SCHEME` environment variable
  if ENV['SCHEME'] == nil
    envs = options[:envs].to_s.split(",")
    execute_for_all_scheme_envs(envs) { do_task }
    next
  end

  puts "DO TASK FOR #{ENV['SCHEME']}"
end

lane :error do
  sh "ls"
  #command = "cat pizza.txt"
  command = "ionic cordova platform add pizza"
  #sh command
  sh command, log: [:command, :output]
end

# Execute a block of code for all schemes
# Scheme list is generated by file prefixed with ".env.scheme_" 
# Example: .env.scheme_dev, .env.scheme_stg, .env.scheme_prod
#
# Note: Each execution will reset environment variables
# and lane context after execution. Handle specific lane context
# values in your execution block as they will be cleared
# after block execution
def execute_for_all_scheme_envs(envs)
  # Environment and lane context cache for resetting
  env_cache = ENV.to_hash
  context_cache = Actions.lane_context.clone

  schemeList = Dir.glob(".env.scheme*")

  # Select only given envs
  if envs && !envs.empty?
    envs.map! { |e| ".env.#{e}" }
    schemeList.select! { |s| envs.include?(s) }
  end

  schemeList.each do |file|
    # Overloading environment for scheme
    Dotenv.overload(file)
    
    # Execute only if scheme
    if ENV["SCHEME"]
      yield
    else
      UI.important("No 'SCHEME' env for #{file} - Skipping...")
    end

    # Reset environment variables
    ENV.clear
    ENV.update(env_cache)

    # Reset lane context
    Actions.lane_context.clear
    Actions.lane_context.update(context_cache)
  end
end

lane :env_helper do
  sh 'echo "JOSH: $JOSH"'
  Helper.with_env_values('JOSH' => 'Heyyyyy') do
    sh 'echo "JOSH: $JOSH"'
  end


  command = 'echo "JOSH 2: $JOSH"'
  FastlaneCore::CommandExecutor.execute(command: command,
    print_all: FastlaneCore::Globals.verbose?,
    print_command: FastlaneCore::Globals.verbose?)
  Helper.with_env_values('JOSH' => 'Heyyyyy') do
    FastlaneCore::CommandExecutor.execute(command: command,
      print_all: FastlaneCore::Globals.verbose?,
      print_command: FastlaneCore::Globals.verbose?)
  end
end

lane :this do
  ensure_git_branch(branch: "^release-")
end

desc "OMG, this lanes description has"
desc "the time in it #{Date.today}"
lane :hey do
  # Your lane info goes here
  UI.message("Hey hey heyyyyy")
end

lane :fix_encrypt_but_only_do_this_once do
  require 'match'
  storage = Match::Storage.for_mode("git", { git_url: "https://github.com/joshdholtz/fastlane-match-repo.git", shallow_clone: false, git_branch: "master", clone_branch_directly: false})
  storage.download

  encryption = Match::Encryption.for_storage_mode("git", { git_url: "https://github.com/joshdholtz/fastlane-match-repo.git", working_directory: storage.working_directory})
  encryption.encrypt_files

  files_to_commit = Dir[File.join(storage.working_directory, "**", "*.{cer,p12,mobileprovision}")]
  storage.save_changes!(files_to_commit: files_to_commit)
end

lane :g do
  # git_add(path: "filedir/*.txt")
  # git_add(path: ["*.txt"])
  # git_add(path: ["filedir/*.txt", "*.txt"])
  git_add
end

lane :import_good do
  import_from_git(
    url: "git@github.com:joshdholtz/fastfiles.git",
    path: "GoodAction"
  )
end

lane :import_broken do
  import_from_git(
    url: "git@github.com:joshdholtz/fastfiles.git",
    path: "BrokenAction"
  )
  broken
end

def something
  hey = "hey"
  ho = "ho"
  return hey, ho 
end

lane :test do
  value = something
  puts value.inspect
end

lane :podpod do
  cocoapods(
    repo_update: true,
    try_repo_update_on_error: true
  )
end

lane :agree do
  UI.confirm("this?")
end

lane :da_change do
  set_changelog(
    app_identifier: "com.getpicter.Sharkagram",
    version: "3.0.0",
    # app_identifier: "com.fastlanescreencast.FastlaneScreencast", 
    # version: "1.0",
    username: "josh+dev@rokkincat.com",
    changelog: "Changelog for all Languages",
    platform: "ios"
  )
end

lane :need_log do
  thing = changelog_from_git_commits(
    commits_count: 2,
    path: "../test-swift"
  )
  puts "thing: #{thing}"
end

lane :release_tv do
  sigh(
    app_identifier: 'com.joshholtz.FastlaneTest.FastlaneTestTV',
    platform: 'tvos'
  )

  gym(
    scheme: 'FastlaneTestTV',
    export_method: 'app-store',
    export_team_id: 'WPBN76YKX2'
  )

  deliver(
    username: 'josh+dev@rokkincat.com',
    dev_portal_team_id: 'WPBN76YKX2',
    app_identifier: 'com.joshholtz.FastlaneTest.FastlaneTestTV',
    platform: 'appletvos',

    ignore_language_directory_validation: true,
    run_precheck_before_submit: false,

    #submit_for_review: true,
    #reject_if_possible: true,

    skip_metadata: true,
    skip_screenshots: true,
    skip_binary_upload: false
  )
end


platform :mac do
  lane :dude do
    puts "hey"
  end

  lane :register do
    register_devices(
      username: "josh+dev@rokkincat.com",
      devices: {
        "Josh's Mac 2" => "E70E1D93-F982-58E0-AB66-105376251B95"
      }
    )
  end

  lane :get_prof_developer_id do
    get_provisioning_profile(
      developer_id: true,
      app_identifier: 'com.joshholtz.FastlaneTestMac',
      platform: 'macos'
    )
  end

  lane :get_prof do
    get_provisioning_profile(
      app_identifier: 'com.joshholtz.FastlaneTestMac',
      platform: 'macos'
    )
  end

  lane :del do
    deliver(
      dev_portal_team_id: "WPBN76YKX2"
    )
  end
end

platform :ios do
 lane :wait do
  sleep 10
 end

  # fl produce -u 'josh+dev@rokkincat.com' -a 'com.joshholtz.fastlaneproducetest2' --team_name 'Rokkincat LLC' -q 'Fastlane Produce Test 2' -i --verbose
  lane :pro do
    produce(
      username: "josh+dev@rokkincat.com",
#      app_identifier: "com.joshholtz.fastlaneproducetest9",
#      app_name: "Fastlane Produce Test 9 edited",
#      team_name: "Rokkincat LLC",
      skip_itc: true,
      enable_services: {
        push_notification: "on"
      }
    )
  end

  lane :boom do
    raise "some error"
  end

  lane :space_env do
    sigh(
      username: "josh+dev@rokkincat.com",
      app_identifier: "com.joshholtz.FastlaneTest",
      development: true
    )
  end

  lane :tsa do
    sigh(
      username: "josh2sa@rokkincat.com",
      app_identifier: "com.joshholtz.FastlaneTest",
      development: true
    )
  end

  lane :tfa do
    sigh(
      username: "me@joshholtz.com",
      app_identifier: "com.joshholtz.FastlaneApp",
      team_name: "Josh Holtz",
      development: true
    )
  end

  lane :register do
    register_devices(
      username: "josh+dev@rokkincat.com",
      devices: {
        "Josh's iPhone 8 dude" => "6a6ed8fdac67d6695010c2ce38146d636f90ed8b"
      }
    )
  end

  lane :ugh do
    fastlane_require 'spaceship'
    Spaceship.login('josh+dev@rokkincat.com')
    Spaceship::client.team_id = '3Q54H69ZVN'
    array_profiles = Spaceship::ProvisioningProfile::InHouse.find_by_bundle_id(bundle_id: "com.jwspeaker")
    puts "hey: #{array_profiles}"
  end

  lane :pro_new_app do
    produce(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest',
      team_id: 'WPBN76YKX2',

      skip_devcenter: true,
      skip_itc: false

      # enable_services: {
      #   icloud: "cloudkit",            # Valid values: "legacy", "cloudkit"
      # }
    )
  end

  lane :test_git_add do
    git_add(
     path: "fastlane/Fastfile"
    )
  end

  lane :mail do
    mailgun(
      postmaster: "postmaster@rokkincat.mailgun.org",
      apikey: "key-5bp3i8ee3iu4gyyr2m3lc4ggmbnk2n90",
      to: "josh+1@rokkincat.com,me@joshholtz.com",
      from: "josh@rokkincat.com",
      reply_to: "josh@rokkincat.com",
      success: true,
      subject: "heyyyyy 4",
      message: "Mail Bodyddddddddyyyyyy",
      app_link: "http://www.myapplink.com",
      ci_build_link: "http://www.mycibuildlink.com",
    )
  end

  lane :mail_custom do
    mailgun(
      postmaster: "postmaster@rokkincat.mailgun.org",
      apikey: "key-5bp3i8ee3iu4gyyr2m3lc4ggmbnk2n90",
      to: "josh+1@rokkincat.com,me@joshholtz.com",
      from: "josh@rokkincat.com",
      reply_to: "josh@rokkincat.com",
      success: true,
      subject: "heyyyyy 4",
      message: "Mail Bodyddddddddyyyyyy",
      app_link: "http://www.myapplink.com",
      ci_build_link: "http://www.mycibuildlink.com",
      template_path: "./fastlane/mail.erb",
      custom_placeholders: nil
    )
  end

  lane :test do
    scan(
      scheme: "Test",
      devices: "iPhone 6 - 10.3",
      #xcpretty_args: "--no-color",
      xcpretty_args: "--tap --no-color",
      #suppress_xcode_output: false,
      #reinstall_app: true,
      #app_identifier: "com.joshholtz.FastlaneTest"
      slack_url: "https://hooks.slack.com/services/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",
      slack_channel: "bandit-is-cute",
      slack_message: "Test stuff",
      reset_simulator: true
    )
  end

  lane :test2 do
    scan(
      #devices: "iPhone 6 - 10.3",
      devices: "iPhone 8",
      fail_build: false,
      #formatter: "xcpretty-teamcity-formatter",
      formatter: "./fastlane/joshcity_formatter.rb",
      #result_bundle: true
      #output_directory: './ohmyoutputs',
      #derived_data_path: './ohmydata',
      should_zip_build_products: true
    )
  end

  lane :test0 do
    scan(
      #devices: []
      skip_detect_devices: true
      #devices: "iPhone 6 - 10.3",
      #devices: "iPhone 8",
      #fail_build: false,
      #formatter: "xcpretty-teamcity-formatter",
      #formatter: "./fastlane/joshcity_formatter.rb",
      #result_bundle: true
      #output_directory: './ohmyoutputs',
      #derived_data_path: './ohmydata',
      #should_zip_build_products: false
    )
  end

  lane :mod_ser do
    modify_services(
      username: "josh+dev@rokkincat.com",
      app_identifier: "com.joshholtz.fastlaneproducetest9",
      services: {
        wallet: "on",
        personal_vpn: "on"
      }
    )
  end

  lane :space_pro do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    Spaceship::Tunes::Application.create!(name: 'Teehee Test App', bundle_id: 'com.joshholtz.FastlaneTest2')
  end

  lane :space_testers do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'RokkinCat LLC')

    app = Spaceship::Tunes::Application.find('com.joshholtz.FastlaneTest')
    testers = Spaceship::TestFlight::Base.client.testers_for_app(app_id: app.apple_id)

    puts "testers: #{testers}"
  end

  lane :space_2fa do
    fastlane_require 'spaceship'
    Spaceship::Portal.login('me@joshholtz.com')
    Spaceship::Portal.select_team(team_name: 'Josh Holtz')
  end

  lane :space_keys do
    fastlane_require 'spaceship'
    Spaceship::Portal.login('me@joshholtz.com')
    Spaceship::Portal.select_team(team_name: 'Josh Holtz')

    keys = Spaceship::Portal::Key.all
    keys.each do |key|
      key.revoke!
    end

    key = Spaceship::Portal::Key.create(name: "Test Key 2", apns: true)
    puts "we have key: #{key}"

    sleep 10

    key.revoke!
    puts "revoked dude"
  end

  lane :space_users do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'RokkinCat LLC')

    teamname = "hey"

    all_users = Spaceship::Tunes::Members.all
    user = all_users[0] # for example
    account_permissions = {}
    account_permissions[:name] = teamname
    account_permissions[:islive] = !user.not_accepted_invitation
    account_permissions[:permissions] = user.roles
    account_permissions[:apps] = user.has_all_apps ? ["all"] : user.selected_apps.map { |a| a.name if !a.nil? }
    account_permissions[:lastupdated] = Time.now.strftime("%Y-%m-%d")

    puts "account_permissions: #{account_permissions}"
  end

  lane :space_jam do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')

    client = Spaceship::Tunes.client
    puts "client: #{client}"

    team_id = Spaceship::Tunes.client.team_id
    puts "team_id: #{team_id}"
  end

  lane :space_contract do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    #Spaceship::Tunes.select_team
    #Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')
    Spaceship::Tunes.select_team(team_id: 'WPBN76YKX2')

    contract = Spaceship::Tunes.client.contract_messages
    puts "contract: #{contract}"
  end

  lane :pilot_dist do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')

    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')

    fastlane_require 'pilot'
    config = {
      username: "josh+dev@rokkincat.com",
      app_identifier: "com.joshholtz.FastlaneTest",
      team_name: "Rokkincat LLC",
      demo_account_required: true,
      beta_app_review_info: {
        contact_email: "josh+fromfastfile@rokkincat.com",
        contact_first_name: 'Connect',
        contact_last_name: 'API',
        contact_phone: '2622514802',
        demo_account_name: 'josh+connectdemo@rokkincat.com',
        demo_account_password: 'testfastfile'
      }
    }
    Pilot::BuildManager.new.distribute(config, build: build)
  end

  lane :space_connect do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')


    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    app_id = app.apple_id
    puts "app_id: #{app_id}"

    build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')

    resp = Spaceship::ConnectAPI::Base.client.get_builds(filter: { expired: false, processingState: "PROCESSING,VALID", version: build.build_version })
    build_id = resp.first["id"]
    puts "build_id: #{build_id}"

    client = Spaceship::ConnectAPI::Base.client

    #
    # App reivew detail
    #

    attributes = {
      contactEmail: 'josh+connectapi@rokkincat.com',
      contactFirstName: 'Connect',
      contactLastName: 'API',
      contactPhone: '2622514802',
      demoAccountName: 'josh+connectdemo@rokkincat.com',
      demoAccountPassword: 'testapi0101',
      demoAccountRequired: true,
      notes: 'This are api fastlane connect notes'
    }
    app_review_detail_patch = client.patch_beta_app_review_detail(app_id: app_id, attributes: attributes)
    puts "app_review_detail_patch: #{app_review_detail_patch}"

    #
    # App test information
    #

    localizations = client.get_beta_app_localizations(filter: {app: app_id})
    puts "localizations: #{localizations}#"

    localization_id = localizations.first["id"]
    puts "localization_id: #{localization_id}"

    attributes = {
      feedbackEmail: "josh+feedbackemail@rokkincat.com",
      marketingUrl: "https://joshholtz.com/marketingfromapi",
      privacyPolicyUrl: "https://joshholtz.com/policyfromapi",
      #tvOsPrivacyPolicy: nil
      description: "description from new api",
      #locale: nil
    }
    localizations_patch = client.patch_beta_app_localizations(localization_id: localization_id, attributes: attributes)
    puts "localizations_patch: #{localizations_patch}"

    #
    # Build test information
    #

    localizations = client.get_beta_build_localizations(filter: {build: build_id})
    puts "localizations: #{localizations}"

    localization_id = localizations.first["id"]
    puts "localization_id: #{localization_id}"

    attributes = {
      whatsNew: "something new from api"
    }
    localizations_patch = client.patch_beta_build_localizations(localization_id: localization_id, attributes: attributes)
    puts "localizations_patch: #{localizations_patch}"
  end

  lane :airplane do
    pilot(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest2',
      dev_portal_team_id: 'WPBN76YKX2',
    )
  end

  lane :clear do
    clear_derived_data
  end

  lane :pod_spec do
    version = version_get_podspec(
      path: "JSONAPI.podspec"
    )
    puts "Version: #{version}"
  end

  lane :xb do
    xcodebuild(
      build: true,
      buildlog_path: "./fastlane/logs/xcodebuild/",
      build_settings: {
        # fastlane wraps these settings in double-quotes, rather than single-quotes.
        # Thus, bash will attempt to process $(inherited) as a command substitution, which produces:
        # > -bash: inherited: command not found
        # We inject a backslash in front of $ to prevent this.
        # fastlane issue: https://github.com/fastlane/fastlane/issues/12418
        'GCC_PREPROCESSOR_DEFINITIONS'                      => '$(inherited) NDEBUG=1',
      },
      configuration: "Release",
      destination: "platform=iOS Simulator,OS=latest,name=iPhone 6s Plus",
      output_style: :basic,
      scheme: "Test",
      workspace: "Test.xcworkspace",
      xcargs: "-sdk iphonesimulator",
      analyze_build_time: true
    )
  end

  lane :tf do
    # match(
    #   app_identifier: 'com.joshholtz.FastlaneTest',
    #   type: 'adhoc',
    #   username: 'josh+dev@rokkincat.com',
    #   team_id: 'WPBN76YKX2',
    #   git_branch: 'appstore',
    #   force: true
    # )

    gym(
      scheme: 'Test',
      export_method: 'ad-hoc'
    )

    testfairy(
      # upload_url: 'https://josh1.testfairy.com',
      api_key: '713db30a43c570820034cee5d7c3e750f2945172',
      timeout: 3000
    )
  end

  lane :plist do
    set_info_plist_value(
      path: 'Test/Info.plist',
      key: 'NSAppTransportSecurity',
      value: { 'NSExceptionDomains' => {
          'example1.com' => {
            'NSExceptionAllowsInsecureHTTPLoads' => true
          },
          'example2.com' => {
            'NSExceptionAllowsInsecureHTTPLoads' => true
          }
        }
      }
    )
  end

  lane :plist_new do
    # update_plist(
    #   plist_path: 'Test/Info.plist',
    #   block: proc do |plist|
    #     plist["SupDude"] = "hellow dude"
    #   end
    # )

    # update_info_plist(
    #   xcodeproj: 'Test.xcodeproj',
    #   plist_path: 'Test/Info.plist',
    #   # plist_path: 'Test/Info.plist',
    #   display_name: 'LOLOLOLOL',
    # )

    update_info_plist(
      xcodeproj: 'Test.xcodeproj',
      plist_path: 'Test/Info.plist',
      block: proc do |plist|
        plist["SupDude2"] = "hellow dude2"
      end
    )
  end

  lane :ask do
    val = prompt(text: "This is some non-secure text")
    puts("val: #{val}")

    val = prompt(secure_text: "This is some non-secure text")
    puts("val: #{val}")
  end

  lane :get_lane_context do
    puts "Actions.lane_context: #{Actions.lane_context}"
  end

  lane :analyze do
    # match(
    #   app_identifier: 'com.joshholtz.FastlaneTest',
    #   type: 'appstore',
    #   username: 'josh+dev@rokkincat.com',
    #   team_id: 'WPBN76YKX2',
    #   git_branch: 'appstore2',
    #   force: true
    # )

    gym(
      scheme: 'Test',
      export_method: 'app-store',
      analyze_build_time: false,
      export_team_id: 'WPBN76YKX2',
#      export_options: {
#        method: "ad-hoc",
#        provisioningProfiles: {
#          "hey": "dude"
#        }
#      }
#      export_options: 'fastlane/ExampleExportGood.plist',
#      export_options: 'fastlane/ExampleExport.plist',
#      disable_xcpretty: true
    )

    puts "Actions.lane_context: #{Actions.lane_context}"
  end

  lane :adhoc do
    match(
      app_identifier: 'com.joshholtz.FastlaneTest',
      type: 'adhoc',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore',
      # force: true
    )

    # mapping = Actions.lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING]
    # puts "mapping: #{mapping.inspect}"

    fastlane_require 'match'
    env_name = Match::Utils.environment_variable_name_profile_path(app_identifier: 'com.joshholtz.FastlaneTest', type: 'adhoc', platform: 'ios')
    profile_path = ENV[env_name]

    text = File.read(profile_path)
    new_contents = text.gsub(
      "<key>keychain-access-groups</key>", 
      "<key>beta-reports-active</key><false/><key>keychain-access-groups</key>"
    )
    File.open(profile_path, "w") {|file| file.puts text }

    gym(
      scheme: 'Test',
      export_method: 'ad-hoc'
    )
  end

  lane :just_gym do
    match(
      app_identifier: 'com.joshholtz.FastlaneTest',
      type: 'appstore',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore',
      # force: true
    )

    gym(
      scheme: 'Test',
      export_method: 'app-store',
      xcargs: "-UseNewBuildSystem=YES"
    )
  end

  lane :hello do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('admin+enterprise@rokkincat.com')
  end

  desc "Bumps the version and build number on the project"
  desc "The lane to run by developers"
  desc "#### Example:"
  desc "```\nfastlane ios bump version:2.0.1 build_number:23\n```"
  desc "#### Options"
  desc " * **`version`**: The version to set in the Info.plist (`CFBundleShortVersionString`)"
  desc " * **`build_number`**: The build number to set in the Info.plist (`CFBundleVersion`)"
  desc ""
  lane :bump do |options|
    # Update plist with new version and build number
    update_info_plist(
      xcodeproj: 'Test.xcodeproj',
      plist_path: 'Test/Info.plist',
      block: proc do |plist|
        plist["CFBundleShortVersionString"] = get_version_ugh(options)
        plist["CFBundleVersion"] = get_build_number_ugh(options)
      end
    )
  end

  lane :star_wars do
    fastlane_require "rest-client"
    resp = RestClient.get "https://swapi.co/api/people/"
    json = JSON.parse(resp.body)
    people = json["results"]
    random_person = people.sample
    
    update_info_plist(
      xcodeproj: 'Test.xcodeproj',
      plist_path: 'Test/Info.plist',
      block: proc do |plist|
        plist["CFBundleDisplayName"] = random_person['name']
      end
    )

    sigh()
    gym()
  end

  private_lane :get_version_ugh do |options|
    version = nil
    loop do
      version = options[:version] || UI.input("Version?")
      break if version && !version.empty?
    end
    version
  end

  private_lane :get_build_number_ugh do |options|
    build_number = options[:build_number] || UI.input("Build number (defaults to current timestamp)?")
    build_number = Time.now.to_i if build_number.nil? || build_number.empty?
    build_number
  end

  lane :build_adhoc do
    sink
    ENV["MATCH_PASSWORD"] = "trT2jX@ozi7aBo"
    match(
      git_url: 'https://github.com/RokkinCat/apple-certificates.git',
      app_identifier: 'com.joshholtz.FastlaneTest',
      #type: 'appstore',
      type: 'adhoc',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore2',
      # recreate_deleted_profiles: true
      force: true
    )
    gym(
      scheme: 'Test',
      #export_method: 'ad-hoc',
      export_team_id: 'WPBN76YKX2'
    )

    # Copies the DistributionSummary.plist from the -exportPath directory
    # into our fastlane directory
    fastlane_require "gym"
    dist_plist_path = File.join(Gym.cache[:temporary_output_path], "DistributionSummary.plist")
    FileUtils.cp(dist_plist_path, "./")
  end

  lane :build do
    sink
    gym(
      scheme: 'Test',
      export_method: 'app-store',
      export_team_id: 'WPBN76YKX2'
    )

    # Copies the DistributionSummary.plist from the -exportPath directory
    # into our fastlane directory
    fastlane_require "gym"
    dist_plist_path = File.join(Gym.cache[:temporary_output_path], "DistributionSummary.plist")
    FileUtils.cp(dist_plist_path, "./")
  end

  lane :crash_hoc do
#    match(
#      app_identifier: 'com.joshholtz.FastlaneTest',
#      type: 'adhoc',
#      username: 'josh+dev@rokkincat.com',
#      team_id: 'WPBN76YKX2',
#      git_branch: 'appstore2',
#      # recreate_deleted_profiles: true
#      force: true
#    )

#    gym(
#      scheme: 'Test',
#      export_method: 'ad-hoc',
#      export_team_id: 'WPBN76YKX2',
#      export_options: {
#        provisioningProfiles: {
#          "com.joshholtz.FastlaneTest": "match AdHoc com.joshholtz.FastlaneTest"
#        }
#      }
#    )
    
    ENV["CRASHLYTICS_FRAMEWORK_PATH"] = "./Pods/Crashlytics"

    crashlytics(
      #crashlytics_path: "./Pods/Crashlytics/iOS/Crashlytics.framework",
      ipa_path: "./Cat.ipa",
      api_token: '1e77b8b588795b0e62a23c61c9a578feb32a1add',
      build_secret: "4111cc783ddf02ef1fe69c51df8be7f89e4093c05c27fcd068af1e795d7b1949",
      #notes: "hey dude hey"
      #notes_path: "./crash_notes.txt"
    )
  end

  lane :hock do
    ENV['MATCH_PASSWORD'] = 'trT2jX@ozi7aBo'
    match(
      git_url: 'https://github.com/RokkinCat/apple-certificates.git',
      app_identifier: 'com.joshholtz.FastlaneTest',
      type: 'adhoc',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore2',
      # recreate_deleted_profiles: true
      force: true
    )

    gym(
      scheme: 'Test',
      export_method: 'ad-hoc',
      export_team_id: 'WPBN76YKX2'
    )

    hockey(
      api_token: "3593a12832a340019fa48405dd821137" 
    )
  end

  lane :up_meta do
    deliver(
      username: 'josh+dev@rokkincat.com',
      dev_portal_team_id: 'WPBN76YKX2',
      app_identifier: 'com.joshholtz.FastlaneTest',
      # app_identifier: 'com.goodnightcar.GoodNightCar',
      # app_identifier: 'com.getpicter.Sharkagram',
      
      force: true,
 
      ignore_language_directory_validation: true,
      run_precheck_before_submit: false,
 
      #submit_for_review: true,
      #reject_if_possible: true,
      
      individual_metadata_items: ['name','keywords','description'],
 
      skip_metadata: false,
      skip_screenshots: false,
      skip_binary_upload: true
    )
  end

  lane :build_this do
    gym(
      scheme: 'Test',
      #configuration: 'Debug',
      export_method: 'app-store',
      export_team_id: 'WPBN76YKX2'
    )
  end

  lane :release do
    #sink()
    gym(
      scheme: 'Test',
      export_method: 'app-store',
      export_team_id: 'WPBN76YKX2'
    )

    deliver(
      username: 'josh+dev@rokkincat.com',
      dev_portal_team_id: 'WPBN76YKX2',
      app_identifier: 'com.joshholtz.FastlaneTest',
      # app_identifier: 'com.goodnightcar.GoodNightCar',
      # app_identifier: 'com.getpicter.Sharkagram',
      
      force: true,
 
      ignore_language_directory_validation: true,
      run_precheck_before_submit: false,
 
      submit_for_review: true,
      reject_if_possible: true,
 
      skip_metadata: true,
      skip_screenshots: true,
      skip_binary_upload: false
    )
  end

  lane :submit_review do
    deliver(
      username: 'josh+dev@rokkincat.com',
      dev_portal_team_id: 'WPBN76YKX2',

      app_identifier: 'com.joshholtz.FastlaneTest',
      # build_number: '12334', # Use specific version instead of edit ersion
      
      force: true,
 
      submit_for_review: true,
      reject_if_possible: true,
 
      skip_metadata: true,
      skip_screenshots: true,
      skip_binary_upload: true
    )
  end

  lane :tf_submit do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')
    build.submit_for_testflight_review!
  end

  lane :tf_submit_error do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')

    puts "build: #{build}"

    resp = Spaceship::API::Base.client.get_builds(filter: {expired: false, processingState: "PROCESSING,VALID", version: build.build_version, sort: "pizzahead"})
    build = resp.first
  end

  lane :release_pilot do
    #sink()
    gym(
      scheme: 'Test',
      export_method: 'app-store',
      export_team_id: 'WPBN76YKX2'
    )

     pilot(
       username: 'josh+dev@rokkincat.com',
       skip_submission: false,
       changelog: "OMG this thing is so good yeah yeah yeah",
       dev_portal_team_id: 'WPBN76YKX2',
       app_identifier: 'com.joshholtz.FastlaneTest',
       team_name: "Rokkincat LLC",
       demo_account_required: false,
       #wait_for_uploaded_build: true,
       #reject_build_waiting_for_review: true,
       distribute_external: true,
       groups: ["Spacey Group"]
     )
  end

  lane :update_prov do
    sigh(
      app_identifier: 'com.joshholtz.FastlaneTest',
      adhoc: false,
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
    )

    puts "Actions.lane_context: #{Actions.lane_context}"

    update_project_provisioning(
      xcodeproj: "Test.xcodeproj",
      profile: nil,
      #profile: "./#{profilename}", # optional if you use sigh
      target_filter: "Test", # matches name or type of a target
      build_configuration: "Release",
      #code_signing_identity: "iPhone Distribution"
      code_signing_identity: ""
    )

    update_project_provisioning(
      xcodeproj: "Test.xcodeproj",
      #profile: "",
      #profile: "./#{profilename}", # optional if you use sigh
      target_filter: "Test", # matches name or type of a target
      build_configuration: "Debug",
      #code_signing_identity: "iPhone Developer"
      code_signing_identity: ""
    )
  end

  lane :dont_sign do
    automatic_code_signing(
      path: "Test.xcodeproj",
      targets: "Test",
      use_automatic_signing: false,
      team_id: "",
      profile_name: "",
      profile_uuid: "",
      code_sign_identity: ""
    )
  end

  lane :crash_dsyms do
    download_dsyms(
      version: 'latest',
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest'
    )

    upload_symbols_to_crashlytics(
      # api_token: '8d659e13da0c6ae49bf5dd1ccc42024a6495db67'
      gsp_path: 'GoogleService-Info.plist'
    )
  end

  lane :latest_app_store do
    hey = app_store_build_info(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.goodnightcar.GoodNightCar',
      live: true,
      team_id: '1086164'
    )
    puts "good night car info: #{hey}"

    hey = app_store_build_number(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.goodnightcar.GoodNightCar',
      live: true,
      team_id: '1086164'
    )
    puts "good night car version: #{hey}"

    hey = app_store_build_info(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest',
      live: true,
      team_id: '1086164'
    )
    puts "fastlane test info: #{hey}"

    hey = app_store_build_number(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest',
      live: true,
      team_id: '1086164'
    )
    puts "fastlane test version: #{hey}"
  end

  lane :hungry do
    appetize(
      url: "http://127.0.0.1:8000/Debug-iphonesimulator.zip",
      # path: "./Debug-iphonesimulator.zip",
      api_token: "tok_d13vvz92ayd332vbuceck502qm", # get it from https://appetize.io/docs#request-api-token
      public_key: "m5w8fxx18ewh7ruyq820ukmtjr" # get it from https://appetize.io/dashboard
    )
  end

  lane :crash_dsyms_bad do
    upload_symbols_to_crashlytics(
      dsym_path: 'fastlane/appDsyms.zip',
      # api_token: '8d659e13da0c6ae49bf5dd1ccc42024a6495db67'
      gsp_path: 'GoogleService-Info.plist'
    )
  end

  lane :dsyms do
    download_dsyms(
      username: 'josh+dev@rokkincat.com',
      #app_identifier: 'com.joshholtz.FastlaneTest',
      app_identifier: 'com.snapifeye.SnapifeyePro',
      #version: '1.0'
      #version: 'latest'
    )
  end

  lane :dsym_good do
    download_dsyms(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.goodnightcar.GoodNightCar',
      version: '3.0.0',
      build_number: '400'
    )
  end

  lane :dsym_bad do
    download_dsyms(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.rokkincat.cupcakegram',
      version: '1.0.0',
      build_number: '1'
    )
  end

  lane :web_cert do
    pem(
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      website_push: true,
      app_identifier: 'web.comjoshholtz.fastlanewebtest'
    )
  end

  lane :push_cert do
    pem(
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      development: true,
      app_identifier: 'com.joshholtz.FastlaneTest'
    )
  end

  lane :git do
    value = last_git_commit
    puts "value: #{value}"
  end

  lane :the_live do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')

    app = Spaceship::Tunes::Application.find('com.goodnightcar.GoodNightCar')
    live_version = app.live_version
    puts "version: #{live_version.version}"
    puts "build number: #{live_version.build_version}"
  end

  lane :space_reviews do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_name: 'Rokkincat LLC')

    app = Spaceship::Tunes::Application.find('com.goodnightcar.GoodNightCar')
    reviews = app.ratings.reviews
    puts "reviews: #{reviews}"
  end

  lane :space_cloud_create do
    fastlane_require 'spaceship'
    Spaceship::Portal.login('josh+dev@rokkincat.com')
    Spaceship::Portal.select_team(team_name: 'Rokkincat LLC')

    new_cloud_container = Spaceship::Portal.cloud_container.create!(identifier: "iCloud.com.joshholtz.TheFastlaneCloud", name: "TheFastlaneCloud")
    puts "new_cloud_container: #{new_cloud_container}"
  end

  lane :space_cloud do
    fastlane_require 'spaceship'
    Spaceship::Portal.login('josh+dev@rokkincat.com')
    Spaceship::Portal.select_team(team_name: 'Rokkincat LLC')

    cloud_containers = Spaceship::Portal.cloud_container.all
    puts "cloud_containers: #{cloud_containers}"

    app = Spaceship::Portal.app.find('com.joshholtz.FastlaneTest').details
    puts "count: #{app.cloud_containers_count}"
    ass_clouds = app.associated_cloud_containers
    puts "ass_clouds: #{ass_clouds}"

    app = app.associate_cloud_containers(cloud_containers)

    ass_clouds = app.associated_cloud_containers
    puts "ass_clouds 2: #{ass_clouds}"
  end

  lane :auto_release_date do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    app = Spaceship::Tunes::Application.find('com.joshholtz.FastlaneTest')

    v = app.edit_version
    v.auto_release_date = Date.parse("12 May 2018 09:00:00 +0600").strftime('%Q')
    v.save!

    puts "v.auto_release_date: #{v.auto_release_date}"
  end

  lane :update_price do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    app = Spaceship::Tunes::Application.find('com.joshholtz.FastlaneTest')
    app.update_price_tier!(0)
  end

  lane :sup_profiles do
    fastlane_require 'spaceship'
    Spaceship::Portal.login('josh+dev@rokkincat.com')
    Spaceship::Portal.select_team(team_id: '3Q54H69ZVN')

    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    launcher = Spaceship::Launcher.new
    launcher.client.login('josh+dev@rokkincat.com')
    launcher.client.select_team(team_id: '3Q54H69ZVN')

    Spaceship.login('josh+dev@rokkincat.com')
    Spaceship.select_team(team_id: '3Q54H69ZVN')
    
    # puts "in_house? #{Spaceship.client.in_house?}"

    # development = Spaceship.certificate.development.all
    # puts "development: #{development}"

    # in_house = Spaceship.certificate.in_house.all
    # puts "in_house: #{in_house}"

    # production = Spaceship.certificate.production.all
    # puts "production: #{production}"
  end

  lane :preorder do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    app = Spaceship::Tunes::Application.find('com.joshholtz.FastlaneTest')
    # app = Spaceship::Tunes::Application.find('com.getpicter.Sharkagram')
    # app = Spaceship::Tunes::Application.find('com.goodnightcar.GoodNightCar')

    availability = app.availability
    # puts "availability: #{availability.inspect}"
    # puts "cleared_for_preorder: #{availability.cleared_for_preorder}"
    # puts "app_available_date: #{availability.app_available_date}"

    # availability.include_future_territories = true
    # availability = Spaceship::Tunes::Availability.from_territories(["FR", "DK", "GB", "IE", "UA", "SE", "DE", "AT"])
    availability.cleared_for_preorder = true
    availability.app_available_date = "2018-06-05" 
    # availability.cleared_for_preorder = false
    # availability.app_available_date = nil 

    puts "AFTER cleared_for_preorder: #{availability.cleared_for_preorder}"
    puts "AFTER app_available_date: #{availability.app_available_date}"

    # puts "availability: #{availability.inspect}"

    app.update_availability!(availability)
  end

  lane :b2b do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team(team_id: '3Q54H69ZVN')

    app = Spaceship::Tunes::Application.find('com.joshholtz.FastlaneTest')

    availability = app.availability

    puts "availability: #{availability}"
    availability.educational_discount = false
    # availability.enable_b2b_app!

    app.update_availability!(availability)
  end

  lane :latest do
    value = latest_testflight_build_number(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.joshholtz.FastlaneTest',
      live: false
    )

    is_string = value.is_a? String
    puts "is_string: #{is_string}"
    puts "value: #{value}"

    value = latest_testflight_build_number(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.goodnightcar.GoodNightCar',
      live: false
    )

    is_string = value.is_a? String
    puts "is_string: #{is_string}"
    puts "value: #{value}"
  end

  lane :schemes do
    paths = Dir.glob("../**/Test/Info.plist")
    path = File.absolute_path(paths.first)
    puts "path: #{path}"

    update_url_schemes(
      path: path,
      # url_schemes: ["heyyyy", "hoooo", "heeeeee"],
      # url_schemes: "heyyyy",
      update_url_schemes: proc do |schemes|
        puts "existing schemes: #{schemes}"
        schemes + ["hooooo"]
      end
    )
  end

  lane :create_key do
    create_keychain(
      path: "/Users/josh/Projects/fastlane/test-ios/test-fastlane-keychain",
      password: "",
      timeout: false,
      # lock_after_timeout: true
    )
  end

  lane :super_match do
    match(
      app_identifier: [
        'com.joshholtz.FastlaneTest',
        'com.dinogram.Dinogram',
        'com.rokkincat.cupcakegram'
      ],
      type: 'appstore',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore2',
      # recreate_deleted_profiles: true
      # force: true
    )
  end

  lane :sink_josh do
    match(
      git_url: 'https://github.com/joshdholtz/fastlane-match-repo.git',
      app_identifier: 'com.joshholtz.FastlaneApp',
      type: 'development',
      username: 'me@joshholtz.com',
      team_name: "Josh Holtz"
    )
  end

  lane :sink do
    ENV["MATCH_PASSWORD"] = "trT2jX@ozi7aBo"
    match(
      git_url: 'https://github.com/RokkinCat/apple-certificates.git',
      app_identifier: 'com.joshholtz.FastlaneTest',
      #type: 'appstore',
      type: 'development',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore2',
      # recreate_deleted_profiles: true
      force: true
    )
    match(
      git_url: 'https://github.com/RokkinCat/apple-certificates.git',
      app_identifier: 'com.joshholtz.FastlaneTest',
      #type: 'appstore',
      type: 'development',
      username: 'josh+dev@rokkincat.com',
      team_id: 'WPBN76YKX2',
      git_branch: 'appstore2',
      # recreate_deleted_profiles: true
      force: true
    )
  end

  lane :sink_google do
    ENV["MATCH_PASSWORD"] = "trT2jX@ozi7aBo"
    match(
      google_cloud_bucket_name: "joshdholtz-match",
      storage_mode: "google_cloud",
      app_identifier: 'com.joshholtz.FastlaneApp',
      #type: 'appstore',
      type: 'development',
      username: 'me@joshholtz.com',
      # recreate_deleted_profiles: true
      #force: true
    )
    match(
      google_cloud_bucket_name: "joshdholtz-match",
      storage_mode: "google_cloud",
      app_identifier: 'com.joshholtz.FastlaneApp',
      type: 'appstore',
      #type: 'development',
      username: 'me@joshholtz.com',
      # recreate_deleted_profiles: true
      #force: true
    )
  end

  lane :sink_google_cat do
    ENV["MATCH_PASSWORD"] = "trT2jX@ozi7aBo"
    match(
      google_cloud_bucket_name: "joshdholtz-match",
      storage_mode: "google_cloud",
      app_identifier: 'com.joshholtz.FastlaneTest',
      #type: 'appstore',
      type: 'development',
      username: 'josh+dev@rokkincat.com',
      # recreate_deleted_profiles: true
      #force: true
    )
    match(
      google_cloud_bucket_name: "joshdholtz-match",
      storage_mode: "google_cloud",
      app_identifier: 'com.joshholtz.FastlaneTest',
      #type: 'appstore',
      type: 'development',
      username: 'josh+dev@rokkincat.com',
      # recreate_deleted_profiles: true
      force: true
    )
  end

  lane :sigh_ent do
    sigh(
      app_identifier: 'com.joshholtz.Feeded',
      adhoc: 'true',
      username: 'josh+dev@rokkincat.com',
      team_id: '3Q54H69ZVN',
      #recreate_deleted_profiles: true
      #force: true
    )
  end

  lane :sink_enterprise do
    match(
      app_identifier: 'com.joshholtz.Feeded',
      type: 'adhoc',
      username: 'josh+dev@rokkincat.com',
      team_id: '3Q54H69ZVN'
    )
  end

  lane :multi_dysm_download do
    download_dsyms(
      username: 'josh+dev@rokkincat.com',
      app_identifier: 'com.snapifeye.SnapifeyePro',
      version: 'latest'
    )

    sleep 1

    download_dsyms(
      username: 'josh+wantable@rokkincat.com',
      app_identifier: 'com.wantable.Wantable',
      version: 'latest'
    )
  end

  lane :target_version do
    version1 = get_version_number(target:"Test")
    version2 = get_version_number(target:"TestTarget2")
    version3 = get_version_number(target:"TestTarget3")
    # version4 = get_version_number(target:"TestTarget4")
    version5 = get_version_number(target:"TestTarget5")
    version5specified = get_version_number(target:"TestTarget5", configuration: "Release")

    version_question_mark = get_version_number()


    puts "Version 1: #{version1}"
    puts "Version 2: #{version2}"
    puts "Version 3: #{version3}"
    # puts "Version 4: #{version4}"
    puts "Version 5: #{version5}"
    puts "version5specified: #{version5specified}"
    puts "version_question_mark: #{version_question_mark}"
  end

  lane :snaps_10_1 do
    snapshot(
     # devices: ['iPad Pro (12.9-inch) (3rd generation)', 'iPad Pro (11-inch)'],
      reinstall_app: true,
      app_identifier: "com.joshholtz.FastlaneTest"
    )
  end

  lane :snaps_simple do
    snapshot(
      devices: ['iPhone 6 - 10.3', 'iPad Pro (10.5-inch)'],
      reinstall_app: true,
      app_identifier: "com.joshholtz.FastlaneTest"
    )
  end

  lane :snaps_watch do
    snapshot(
      scheme: "TestWatch",
      devices: ['Apple Watch Series 4 - 44mm'],
      reinstall_app: true,
      app_identifier: "com.joshholtz.FastlaneTest.watchkitapp"
    )
  end

    

  lane :frames do
    frameit(
      path: "./fastlane/screenshots",
      silver: true,
      #debug_mode: true,

      force_orientation_block: proc do |filename|
        if filename.end_with?("01LoginScreen")
          :landscape_left
        else
          nil
        end
      end
    )
  end

  lane :snap_all do
    snapshot(
      #html_summary_format: "group_by_screenshot",
      # scheme: 'RunThisRunThis',
      workspace: 'Test.xcworkspace',
      #devices: ['iPhone 6 - 10.3'],
      #xcconfig: "./fastlane/snaps.xcconfig",
      #devices: ['iPhone 8'],
      #devices: [],
#      devices: [
#        "iPhone 5s",
#        "iPhone 5",
#        #"iPhone 4s",
#        "iPad Air 2",
#        "iPad Air",
#        #"iPad 2",
#      ]
      devices: [
        'iPhone 6',
        'iPhone 6 Plus',
        'iPhone 6s',
        'iPhone 6s Plus',
        'iPhone 7',
        'iPhone 7 Plus',
        'iPhone 8',
#        'iPhone 8 Plus',
        'iPhone SE',
        'iPhone X',
        'iPhone XS',
        'iPhone XS Max',
        'iPhone XR',
        'iPad (5th generation)',
        'iPad Air',
        'iPad Air 2',
        'iPad Pro (9.7-inch)',
        'iPad Pro (10.5-inch)',
        'iPad Pro (12.9-inch)',
        'iPad Pro (12.9-inch) (2nd generation)',
      ],
      #result_bundle: true,
      #languages: ["en-US", "en-GB"]
      #languages: ["en-GB"]
      # devices: ['iPad Pro (12.9-inch)']
      # devices: ['The Eight', 'The X']
      # devices: ['The Eight']
    )
  end

  lane :snaps do
    snapshot(
      #html_summary_format: "group_by_screenshot",
      # scheme: 'RunThisRunThis',
      workspace: 'Test.xcworkspace',
      devices: ['iPhone 6 - 10.3'],
      xcconfig: "./fastlane/snaps.xcconfig",
      #devices: ['iPhone 8'],
      #devices: [],
      devices: [
        "iPhone 5s",
        "iPhone 5",
        #"iPhone 4s",
        "iPad Air 2",
        "iPad Air",
        #"iPad 2",
      ]
#      devices: [
#        'iPhone 6',
#        'iPhone 6 Plus',
#        'iPhone 6s',
#        'iPhone 6s Plus',
#        'iPhone 7',
#        'iPhone 7 Plus',
#        'iPhone 8',
#        'iPhone 8 Plus',
#        'iPhone SE',
#        'iPhone X',
#        'iPad (5th generation)',
#        'iPad Air',
#        'iPad Air 2',
#        'iPad Pro (9.7-inch)',
#        'iPad Pro (10.5-inch)',
#        'iPad Pro (12.9-inch)',
#        'iPad Pro (12.9-inch) (2nd generation)',
#      ],
      #result_bundle: true,
      #languages: ["en-US", "en-GB"]
      #languages: ["en-GB"]
      # devices: ['iPad Pro (12.9-inch)']
      # devices: ['The Eight', 'The X']
      # devices: ['The Eight']
    )
  end

  lane :super_snaps do
    snapshot({
      # devices: ['iPhone 8 Plus'],
      output_directory: './ughstuff',
      languages: ["en-US"],
      clear_previous_screenshots: true,
      skip_open_summary: true,
      concurrent_simulators: false,
      erase_simulator: true
    })
  end

  lane :talk do
    say("say string")
    say(["say", "as", "array"])
    say(text: "this is text option")
    say(text: "this is text option but mute key", mute: true)
    # say(text: "this is stuff")
  end

  lane :ver do
    verify_build(
      bundle_identifier: 'com.joshholtz.FastlaneTest',
      team_identifier: 'WPBN76YKX2',
      ipa_path: 'Pizza.ipa'
    )
  end

  lane :ver_app do
    verify_build(
      bundle_identifier: 'com.joshholtz.FastlaneTest',
      team_identifier: 'WPBN76YKX2',
      ipa_path: 'Test.ipa'
    )
  end

  lane :inc do
    build_num = increment_build_number(
      build_number: "40"
    )
    puts "build_num: #{build_num}"
  end

  lane :slacker do
    slack(
      message: "This is :message and it appears in the attachment (like always)",
      # pretext: "This is the new :pretext that appears before the attachment",
      link_names: false,
      slack_url: "https://hooks.slack.com/services/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",
    )
  end

  lane :which_team do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    team_id = Spaceship::Tunes.select_team

    puts "team_id: #{team_id}"
  end

  lane :internal_users do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.goodnightcar.GoodNightCar")

    client = Spaceship::TestFlight::Base.client
    users = client.internal_users(app_id: app.apple_id)
    puts "users: #{users}"
  end

  lane :test_info do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    Spaceship::Tunes.select_team(team_id: '1086164')
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    app_test_info = Spaceship::TestFlight::AppTestInfo.find(app_id: app.apple_id)

    puts "app_test_info: #{app_test_info.test_info}"
  end

  lane :put_test_info do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    Spaceship::Tunes.select_team(team_id: '1086164')
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    app_test_info = Spaceship::TestFlight::AppTestInfo.find(app_id: app.apple_id)
    puts "before app_test_info: #{app_test_info.test_info}"

    app_test_info.test_info.marketing_url = "https://joshholtz.com/marketing2"
    app_test_info.test_info.privacy_policy_url = "https://joshholtz.com/policy2"
    app_test_info.save_for_app!(app_id: app.apple_id)

    app_test_info = Spaceship::TestFlight::AppTestInfo.find(app_id: app.apple_id)
    puts "before app_test_info: #{app_test_info.test_info}"
  end

  lane :dude do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.goodnightcar.GoodNightCar")

    client = Spaceship::TestFlight::Base.client
    bt = client.get_build_trains(app_id: app.apple_id)
    puts "bt: #{bt}"
  end

  lane :bomb_testers do
    fastlane_require 'spaceship'

    email = "josh+test5@rokkincat.com"

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
        unless project.root_object.attributes["TargetAttributes"]
          UI.user_error!("Seems to be a very old project file format - please open your project file in a more recent version of Xcode")
          return false
        end

    testers = Spaceship::TestFlight::Tester.search(app_id: app.apple_id, text: email)
    
    testers.each do |tester|
      tester.remove_from_testflight!(app_id: app.apple_id)
    end

    puts "tester: #{testers}"
  end

  lane :no do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
  end

  lane :stats do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    #app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    app = Spaceship::Tunes::Application.find("com.goodnightcar.GoodNightCar")
    app_analytics = app.analytics
    puts "app_views: #{app_analytics.app_views}"

    start_t, end_t = app_analytics.time_last_7_days
    puts "app_views group: #{app_analytics.app_views_interval(start_t, end_t, "region")}"
    # time = Time.now
    # past = time - (60 * 60 * 24)
    # end_t = time.strftime("%Y-%m-%dT00:00:00Z")
    # start_t = past.strftime("%Y-%m-%dT00:00:00Z")
    # app_crashes = app_analytics.app_crashes_interval(start_t, end_t)
    # puts app_crashes
  end

  lane :add_group_to_tf_build do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')

    group_name = 'Spacey Group'
    group = Spaceship::TestFlight::Group.find(app_id: app.apple_id, group_name: group_name) 
    build.add_group!(group)
  end

  lane :tf_group_builds do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    groups = Spaceship::TestFlight::Group.all(app_id: app.apple_id)

    groups.each do |group|
      puts "group: #{group.name}"
      builds = group.builds || []
      builds.each do |build|
        puts "\tbuild: #{build.id}"
      end
    end
    
  end

  lane :select_latest do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    version = app.edit_version
    latest_build = version
      .candidate_builds
      .sort_by(&:upload_date)
      .last
    version.select_build(latest_build)
    version.save!
  end

  lane :set_release_notes_if_none do
    fastlane_require 'spaceship'

    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    Spaceship::Tunes.select_team(team_name: "Rokkincat LLC")

    app = Spaceship::Tunes::Application.find("com.goodnightcar.GoodNightCar")
    version = app.edit_version
    release_notes = version.release_notes

    release_notes.languages.each do |key|
      value = release_notes[key]
      if value.to_s.size == 0
        new_notes = prompt(text: "New release notes '#{key}':", multi_line_end_keyword: "END")
        release_notes[key] = new_notes
      end
    end

    version.save!

  end

  lane :add_tf_group do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team

    Spaceship::TestFlight::Group.create!(app_id: '1358899889', group_name: 'Fastlane Group')
  end

  lane :remove_tf_group do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team

    Spaceship::TestFlight::Group.delete!(app_id: '1358899889', group_name: 'Fastlane Group')
  end

  lane :trains do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login('josh+dev@rokkincat.com')
    Spaceship::Tunes.select_team
    version1 = Spaceship::Tunes::Application.find('com.snapifeye.SnapifeyePro')
    puts version1.build_trains
    
    Spaceship::Tunes.login('josh+wantable@rokkincat.com')
    Spaceship::Tunes.select_team
    version2 = Spaceship::Tunes::Application.find('com.wantable.Wantable')
    puts version2.build_trains
  end

  lane :get_iap do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")
    purchases = app.in_app_purchases

    puts "purchases: #{purchases.all}"
    puts "families: #{purchases.families.all}"
  end

  lane :create_iap_nonconsume do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")

    app.in_app_purchases.create!(
    type: Spaceship::Tunes::IAPType::NON_CONSUMABLE, 
    versions: {
      "en-US" => {
        name: "Nonconsume1",
        description: "This is the nonconsum 1 description"
      }
    },
    reference_name: "non_consume_1",
    product_id: "com.joshdholtz.FastlaneTest.nonconsume1",
    cleared_for_sale: true,
    review_notes: "A note for a reviewer",
    review_screenshot: "test_nonconsume1.png", 
    pricing_intervals: 
      [
        {
          country: "WW",
          begin_date: nil,
          end_date: nil,
          tier: 1
        }
      ] 
    )
  end

  lane :create_iap_family do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")

    purchases = app.in_app_purchases
    family = purchases.families.create!(
      reference_name: "First Product in Family",
      product_id: "new.product",
      name: "Family Name",
      versions: {
        'de-DE' => {
          subscription_name: "Subname German",
          name: 'App Name German'
        },
        'da' => {
          subscription_name: "Subname DA",
          name: 'App Name DA'
        }
      }
    )

    puts "family: #{family}"
  end

  lane :create_iap_sub_price_target do
    fastlane_require 'spaceship'
    Spaceship::Tunes.login("josh+dev@rokkincat.com")
    app = Spaceship::Tunes::Application.find("com.joshholtz.FastlaneTest")

    num = "6"

    puts "lets create"
    app.in_app_purchases.create!(
      type: Spaceship::Tunes::IAPType::RECURRING, 
      versions: {
        "en-US" => {
          name: "sub#{num}",
          description: "This is the sub#{num} description"
        }
      },
      reference_name: "sub#{num}",
      family_id: "20443114",
      product_id: "com.joshdholtz.FastlaneTest.sub#{num}",
      cleared_for_sale: true,
      review_notes: "A note for a reviewer",
      review_screenshot: "test_nonconsume1.png", 
      subscription_duration: "1m", 
      subscription_price_target: { currency: "EUR", tier: 1 }
    )
  end
end

lane :swift do
  puts "this is swift lane"
end

`./fastlane/Appfile`
app_identifier "com.joshholtz.fastlaneproducetest9"
apple_id "josh+dev@rokkincat.com"

team_name "Rokkincat LLC"

fastlane gems

Gem Version Update-Status
fastlane 2.116.0 ✅ Up-To-Date

Loaded fastlane plugins:

Plugin Version Update-Status
fastlane-plugin-clean_testflight_testers 0.2.0 ✅ Up-To-Date
Loaded gems
Gem Version
did_you_mean 1.0.0
bundler 1.17.3
io-console 0.4.5
psych 2.1.0.1
CFPropertyList 3.0.0
concurrent-ruby 1.1.4
i18n 0.9.5
minitest 5.11.3
thread_safe 0.3.6
tzinfo 1.2.5
activesupport 4.2.11
public_suffix 2.0.5
addressable 2.6.0
atomos 0.1.3
babosa 1.0.2
claide 1.0.2
fuzzy_match 2.0.4
nap 1.1.0
cocoapods-core 1.5.3
cocoapods-deintegrate 1.0.2
cocoapods-downloader 1.2.2
cocoapods-plugins 1.0.0
cocoapods-search 1.0.0
cocoapods-stats 1.0.0
netrc 0.11.0
cocoapods-trunk 1.3.1
cocoapods-try 1.1.0
colored2 3.1.2
escape 0.0.4
fourflusher 2.0.1
gh_inspector 1.1.3
molinillo 0.6.6
ruby-macho 1.3.1
nanaimo 0.2.6
xcodeproj 1.8.0
cocoapods 1.5.3
coderay 1.1.2
colored 1.2
highline 1.7.10
commander-fastlane 4.4.6
declarative 0.0.10
declarative-option 0.1.0
digest-crc 0.4.1
unf_ext 0.0.7.5
unf 0.1.4
domain_name 0.5.20180417
dotenv 2.6.0
emoji_regex 1.0.1
excon 0.62.0
multipart-post 2.0.0
faraday 0.15.4
http-cookie 1.0.3
faraday-cookie_jar 0.0.6
faraday_middleware 0.13.1
fastimage 2.1.5
jwt 2.1.0
memoist 0.16.0
multi_json 1.13.1
os 1.0.0
signet 0.11.0
googleauth 0.6.7
httpclient 2.8.3
mime-types-data 3.2018.0812
mime-types 3.2.2
uber 0.1.0
representable 3.0.4
retriable 3.1.2
google-api-client 0.23.9
google-cloud-env 1.0.5
google-cloud-core 1.3.0
google-cloud-storage 1.16.0
json 2.1.0
mini_magick 4.5.1
multi_xml 0.6.0
plist 3.5.0
rubyzip 1.2.2
security 0.1.3
naturally 2.2.0
simctl 1.6.5
slack-notifier 2.3.2
terminal-notifier 1.8.0
unicode-display_width 1.4.1
terminal-table 1.8.0
tty-screen 0.6.5
tty-cursor 0.6.0
tty-spinner 0.9.0
word_wrap 1.0.0
rouge 2.0.7
xcpretty 0.3.0
xcpretty-travis-formatter 1.0.0
fastlane-plugin-clean_testflight_testers 0.2.0
method_source 0.9.2
pry 0.12.2
rest-client 2.0.2
xcov 1.5.0
xcpretty-teamcity-formatter 0.0.4

generated on: 2019-02-12

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 26 (8 by maintainers)

Most upvoted comments

This is still an issue, but I think it’s more of a user role issue as I am now getting this error:

You are not permitted to create distribution provisioning profiles for team. Please contact one of your team admins, who can create a profile on your behalf.

I was able to create a distribution certificate (via match and manually on the dev portal) but it looks like only the ‘admin’ role can create distribution profiles at the moment. 😞

I upgrade to App-Manager fix this issue, and downgrade to Developer later.

@joshdholtz Thanks for opening this issue. We are also running into similar issues since the apple update. Trying to download certificates returns a similar error.

[!] Couldn't download certificate, got this instead:
...
"You are not allowed to perform this operation.  Please check with one of your Team Admins, or, if you need further assistance, please contact Apple Developer Program Support."

Just got this from Apple Bug Report:

Engineering has provided the following information on this issue: This issue has been resolved. If the issue persists, kindly provide the Time/Date/Zone the error most > recently occurred.

Tested it as an App Manager and it seems to work fine now!

@tsugitta - My fix would only work as a combination of changing the role and checking developer resources. Glad to hear you got it working though. What type role is your user set on? I set mine to app manager and it’s working and I don’t want to touch it and have my CI go boom again. 😃

I have the same problem, what I’m trying to do:

  • Latest Fastlane (2.116)
  • Change team_id and itc_team_id to names
  • My Account has Developer and App Manager permissions and also Access to Certificates, IDs, and Profiles.

Can’t fix it anyway, maybe I’ve missed something?

We made the following changes and it seems to work for now: Upgraded fastlane from 2.115 to 2.116 (probably unrelated), and updated the role for the user to Admin. It seems that for most people in this thread however, setting the user role to App Manager was enough.

As @iblacksun and @rapinto said, activating the “App Manager” role did the trick 😃

@joshdholtz could you tell me, where I’ll find the App Store Connect Team ID?

Hmmm, that loooooks like it should work then 🤔 That “Access to Certificates, IDs and Profiles” is what you are mainly looking for. If it seems like its not working I would make sure you are passing in your App Store Connect team id into anything parameter called team_id now or use team_name instead.

I had a setup in one of my tests that was using the wrong team id 😇

@joshdholtz Thanks for the tip! In the end that didn’t change anything for me, but the fix was to upgrade my account permissions on the App Store Connect dashboard.

Cheers!