fastlane vs iTC

5 minute read

DISCLAMER: this is a living post. It will be updated frequently to add and update the code below as soon as fastlane/deliver will update. The list of changes is here

As all you iOS developers already know, recently Apple rolls out a new version of iTunes Connect.

That means that Apple broke all the fastlane things1 out there! How dare you, Apple!?

Keep calm and fix all the things

Felix, the (main) author of fastlane is working around the clock since days to make deliver working again. He decide (and I cannot disagree with him) to “abandon” the current version of deliver (0.13) and push faster on the new upcoming version that use spaceship, a new tool that greatly improved all iTunes Connect operations by NOT simulating user interaction on the website.

That said, here are the changes I made in our fastlane/deliver script to start publish again our iOS apps. It still not perfect and it not always works, but at least it runs.

EDIT 1: An official migration guide has been prepared on github. Please check it out.

Update Fastfile

fastlane has a deliver action to run deliver. This is broken now, so what you can do is run deliver as a shell script, this way

# Workaround to make deliver working again
#deliver
# --force: skip html report
# --submit_for_review: obvious
sh "deliver --force --submit_for_review"

EDIT 2: With the new release of fastlane (1.30.1) you can rollback to use again the deliver action. We aware that you still need to pass force to the action because of a bug in deliver.

# Workaround 2
deliver(
  force: true
  )

Update Deliverfile

Here changes are more important. Since some releases of deliver, it has introduced a file based configuration for metadata. But we still working with a single Deliverfile and a .env in our iOS app worker.

  1. default_language is not supported anymore. Some property needs to be an hash map with the language (en-US for example) as key.

  2. apple_id has been replaced by app

# apple_id ENV["PRODUCE_APPLE_ID"]
app ENV["PRODUCE_APPLE_ID"]

EDIT 1: This is correct but you don’t need to use apple_id or app. app_identifier is enough.

  1. We need to provide the app bundle id now. Not sure why this is not coming from the ipa directly
app_identifier "com.spreaker.custom.app-xyz"

EDIT 1: In the next version of deliver, app_identifier is optional if you provide the ipa file. However using app_identifier will let you update metadata without the ipa itself.

  1. title has been replaced by name (plus it requires the language)
#title ENV["CUSTOMAPP_NAME"]
name ({ ENV["CUSTOMAPP_CULTURE"] => ENV["CUSTOMAPP_NAME"] })
  1. Subtle change on keywords: now requires a simple string, not an array anymore (plus the language)
#keywords ENV["CUSTOMAPP_KEYWORDS"].split(',')
keywords ({ ENV["CUSTOMAPP_CULTURE"] => ENV["CUSTOMAPP_KEYWORDS"] })
  1. changelog has been replaced by release_notes (and the language)
#changelog ENV["CUSTOMAPP_CHANGELOG"]
release_notes ({ ENV["CUSTOMAPP_CULTURE"] => ENV["CUSTOMAPP_CHANGELOG"] })
  1. privacy_url and support_url requires the language
privacy_url ({ ENV["CUSTOMAPP_CULTURE"] => "https://www.spreaker.com/privacy" })
support_url ({ ENV["CUSTOMAPP_CULTURE"] => "https://www.spreaker.com/help" })
  1. ratings_config_path has been replaced by app_rating_config_path
#ratings_config_path ENV["CUSTOMAPP_RATINGS_FILE"]
app_rating_config_path ENV["CUSTOMAPP_RATINGS_FILE"]

and the content of the file is completly different. From this

[
  {"comment":"Cartoon or Fantasy Violence","level":0},
  {"comment":"Realistic Voilence","level":0},
  {"comment":"Prolonged Graphic or Sadistic Realistic","level":0},
  {"comment":"Profanity or Crude Humor","level":0},
  {"comment":"Mature\/Suggestive Themes","level":0},
  {"comment":"Horror\/Fear Themes","level":0},
  {"comment":"Medical\/Treatment Information","level":0},
  {"comment":"Alcohol, Tobacco, or Drug Use or References","level":0},
  {"comment":"Simulated Gambling","level":0},
  {"comment":"Sexual Content or Nudity","level":0},
  {"comment":"Graphic Sexual Content and Nudity","level":0},
  {"comment":"Unrestricted Web Access","level":0,"type":"boolean"},
  {"comment":"Gambling and Contests","level":0,"type":"boolean"},
  {"comment":"Made for Kids; 1 = Age < 5; 2 = Ages 6-8; 3 = Ages 9 - 11","level":-1}
]

to this

{
"CARTOON_FANTASY_VIOLENCE" : 0,
"REALISTIC_VIOLENCE" : 0,
"PROLONGED_GRAPHIC_SADISTIC_REALISTIC_VIOLENCE" : 0,
"PROFANITY_CRUDE_HUMOR" : 0,
"MATURE_SUGGESTIVE" : 0,
"HORROR" : 0,
"MEDICAL_TREATMENT_INFO" : 0,
"ALCOHOL_TOBACCO_DRUGS" : 0,
"GAMBLING" : 0,
"SEXUAL_CONTENT_NUDITY" : 0,
"GRAPHIC_SEXUAL_CONTENT_NUDITY" : 0,
"UNRESTRICTED_WEB_ACCESS" : 0,
"GAMBLING_CONTESTS" : 0
}
  1. submit_further_information has been replaced by submission_information but the content is structured differently.

Before is was like this

submit_further_information({
  export_compliance: {
    encryption_updated: false,
    cryptography_enabled: false,
    is_exempt: false
    },
  third_party_content: {
    contains_third_party_content: false,
    has_rights: false
    },
  advertising_identifier: {
    use_idfa: false,
    serve_advertisement: false,
    attribute_advertisement: false,
    attribute_actions: false,
    limit_ad_tracking: false
    }
})	

Now is like ... I don't know. It's not clear right now how we should pass these information to deliver. For sure, it will be an hash map like this

submission_information({
  export_compliance_available_on_french_store: false,
  export_compliance_ccat_file: false,
  export_compliance_contains_proprietary_cryptography: false,
  export_compliance_contains_third_party_cryptography: false,
  export_compliance_is_exempt: false,
  export_compliance_uses_encryption: false,
  export_compliance_app_type: false,
  export_compliance_encryption_updated: false,
  export_compliance_compliance_required: false,
  export_compliance_platform: false,
  content_rights_contains_third_party_content: false,
  content_rights_has_rights: false,
  add_id_info_limits_tracking: false,
  add_id_info_serves_ads: false,
  add_id_info_tracks_action: false,
  add_id_info_tracks_install: false,
  add_id_info_uses_idfa: false
})

That said, this example is basically useless because it rappresents the default values. You can basically skip the declaration of submission_information if you don’t have any value to set true.

Screenshots

Because deliver does not accept a “default language” anymore for all metadata, screenshots needs to be inside a folder with the name of the language.

That means, if the folder that contains your screenshots is called screens and your language is en-US, you have to create a en-US folder inside screens and move all pngs inside of it. For example, if an image was in screens/iphone4_4_821308711567.png but it should be in screens/en-US/iphone4_4_821308711567.png.

I wrote this small workaround to move screenshots automagically and do not edit my worker code. Of course, it all depends on your setup

if !File.directory?("#{ENV["CUSTOMAPP_SCREENSHOTS_FOLDER"]}/#{ENV["CUSTOMAPP_CULTURE"]}")
  # Hack: move screenshots inside a localized folder
  sh "mkdir #{ENV["CUSTOMAPP_SCREENSHOTS_FOLDER"]}/#{ENV["CUSTOMAPP_CULTURE"]}"
  sh "mv #{ENV["CUSTOMAPP_SCREENSHOTS_FOLDER"]}/*.png #{ENV["CUSTOMAPP_SCREENSHOTS_FOLDER"]}/#{ENV["CUSTOMAPP_CULTURE"]}"
end

To sum up

Changes are quite important now, so take now the decision to migrate to a metadata files based configuration to be more future proof (probably). We will, at Spreaker, migrate our Deliverfile-.evn setup soon but for now, these changes helps us to start publishing app again.

All of this is possible just because fastlane exist, and makes our developer life much more easy! So keep coding Felix, and thanks for all the fishes!

Alessandro

Post Changelog

Edit 1, Sept 29th, 2015:

After the release of the official Migration guide, some of the suggested changes are not usefull anymore.

Edit 2, Sept 30th, 2015:

fastlane 1.30.1 fixed deliver action so the workaround can be removed.

  1. As Felix pointed out, not all the things are broken, just deliver, pilot and spaceship. However deliver is the most important tool of all (at least to me).