iosxcodefastlanefastlane-gym

Build number is not set by fastlane, but is set by Xcode


I have setup my project to use a run script that automatically sets the build number based on the amount of commits I have in my main branch:

enter image description here

The entire script, should that help any:

#!/bin/bash

#  update_build_number.sh
#  Usage: `update_build_number.sh [branch]`
#  Run this script after the 'Copy Bundle Resources' build phase
#  Ref: http://tgoode.com/2014/06/05/sensible-way-increment-bundle-version-cfbundleversion-xcode/

branch=${1:-'master'}
buildNumber=$(expr $(git rev-list $branch --count) - $(git rev-list HEAD..$branch --count))
echo "Updating build number to $buildNumber using branch '$branch'."
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
if [ -f "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}.dSYM/Contents/Info.plist" ]; then
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}.dSYM/Contents/Info.plist"
fi

As mentioned in the title, I can build this to a device, and the build number is properly set. Or, I can archive and upload to the AppStore via Xcode and the version is again set correctly. Based on these observations, I am assuming this is configured properly.

However, when I use fastlane to manage my deployment, it is not updating the build number, so I get this error:

ERROR ITMS-90189: "Redundant Binary Upload. You've already uploaded a build with build number '#' for version number '#'. Make sure you increment the build string before you upload your app to App Store Connect. Learn more in Xcode Help (http://help.apple.com/xcode/mac/current/#/devba7f53ad4)."

tl;dr

"You already gave us that version, send us a new one"

For fastlane, this is a condensed version of what I am using to deploy a beta release:

default_platform(:ios)

platform :ios do
  lane :beta do
    build_app(workspace: "MyApp.xcworkspace", 
              scheme: "MyApp")
    upload_to_testflight
  end
end

Finally, if I hardcode an updated build number in Xcode, then fastlane will properly deliver the file, so I am assuming my setup is valid, sans the version issue.

I also experimented with increment_build_number, but I could not find a setting that made it work (plus, Xcode should be managing this for me now, so fastlane should not be concerned).


Solution

  • Figured this one, and it turned out to be quite simple.

    When Xcode builds the application, the build output goes to:

    /Users/theuser/Library/Developer/Xcode/DerivedData/MyAppName/Build/Products/Debug-iphoneos
    

    When fastlane builds it, the file is saved in the local directory per this.

    output_directory    
    The directory in which the ipa file should be stored in     
    Default value: .
    

    By changing the output_directory for my build_app function, I can point fastlane to the same folder Xcode uses, allowing the script to work.

    build_app(workspace: "MyApp.xcworkspace", 
              scheme: "MyApp",
              output_directory: "/Users/theuser/Library/Developer/Xcode/DerivedData/MyApp/Build/Products/Debug-iphoneos")
    

    However, there is a catch that is not obvious here. The folder in DerivedData can be changed, which would make this a problem for future builds. However, using this answer here, you can instead specify an output folder in Xcode, and then sync it with fastlane.