---
title: "Fastlane Fastfile"
slug: fastlane-fastfile
section: tech
date: 2015-07-08T21:53:00.000Z
canonical: https://roland.leth.ro/blog/tech/fastlane-fastfile
---

I [previously](/tech/blog/fastlane) wrote that I can't wait to start using [Fastlane](http://fastlane.tools) full-time, but I never really got to it, since I lost about a day or so and didn't manage to get the provisioning and signing to work.

Since then quite a few updates were issued and things got easier, so I finally managed to make the switch. I will walk through the process in a few posts.

First things first, our release process is more or less release to Hockey with a debug build until a desired state has been reached, release again to Hockey with a release build and make sure everything is working properly, then release to the App Store.

```ruby
desc "Deploy a new major version to the App Store"
lane :release do
  [..]
end
desc "Deploy a new version to Hockey with debug / release settings"
lane :hockey_debug / :hockey_release do
  [..]
end
[...] etc
```

Most of the code inside the lanes are the same, differences being the type of the release, the branch check, the slack output message and other minor things. So instead of duplicating code over and over, all lanes call the same `build_app(type)` method:

```ruby
lane :release do
  build_app 'Release'
end
lane :hockey_debug / :hockey_release do
  build_app 'Debug' / 'Beta'
end
[...] etc
```

And the `build_app(type)` method looks like this:

```ruby
def build_app(type)
  cert(
    development: type == 'Debug',
    username: dev_username,
    team_id: team_id
  )

  pem(
    development: type == 'Debug',
    generate_p12: true,
    app_identifier: app_identifier,
    username: dev_username,
    team_id: team_id,
    p12_password: "xxx",
    pem_name: "aps_#{type}",
    save_private_key: true
  )

  sigh_params = {
    app_identifier: app_identifier,
    username: dev_username,
    team_id: team_id,
    team_name: team_name,
    output_path: "./fastlane/profiles",
    filename: "#{type}.mobileprovision"
  }

  if type == 'Beta'
    sigh_params[:adhoc] = true
  elsif type == 'Debug'
    sigh_params[:development] = true
  end

  sigh sigh_params

  ipa_params = {
    workspace: "xxx.xcworkspace",
    configuration: "#{type}",
    scheme: "#{type}",
    # the auto-increment build number script is at the bottom.
    # Because archiving builds again, that would mean
    # the build number would be increased twice. We don't really need the archive anyway.
    archive: false,
    sdk: "iphoneos",
    clean: true
  }

  # Special case, because setting the signing to Automatic in Xcode
  # uses the Release profile, but we want the AdHoc profile.
  if type == 'Beta'
    ipa_params[:embed] = "./fastlane/profiles/adhoc.mobileprovision"
  end
  ipa ipa_params

  hockey_params = {
    api_token: "xxx",
    notify: (type == "Release") ? "0" : "1", # 0 = Do not notify, 1 = Notify
    status: (type == "Release") ? "1" : "2", # 1 = Download restricted, 2 = Downloadable
    release_type: "0", # Beta, Store creates a new app alltogether
    dsym: Actions.lane_context[Actions::SharedValues::DSYM_OUTPUT_PATH]
  }

  if type != 'Release'
    hockey_params[:tags] = 'alpha'
  end
  hockey hockey_params
end
```

Pretty straighforward and easy to set up: use `cert` to check and refresh the certificates, `pem` to check and refresh the push certificates (it lets you know if you have over 30 days left on them, or not), `sigh` to refresh and download the provisioning profiles, `ipa` to build the `.ipa` file (it uses the `adhoc` profile for the `Beta` builds) and, finally `hockey` to upload the build to `Hockey`, with the required settings.

The script to increment the build number, as promised - go to your `Build Phases` tab, click on `Editor` -> `Add Build Phase` -> `Add Run Script Build Phase` and paste this in there:

```sh
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
```

Next post I will talk about adding major / minor / patch release types and editing the plist to auto-increase the version number.