narner
narner

Reputation: 3221

Increment Bundle Version Error - Fastfile

I have the following Fastfile that I'm using to upload a TestFlight build of a MacOS app:

# Fastfile
default_platform(:mac)

DEVELOPER_APP_ID = ENV["DEVELOPER_APP_ID"]
APP_IDENTIFIER = ENV["APP_IDENTIFIER"]
PROVISIONING_PROFILE_SPECIFIER = ""
TEMP_KEYCHAIN_USER = ENV["TEMP_KEYCHAIN_USER"]
TEMP_KEYCHAIN_PASSWORD = ENV["TEMP_KEYCHAIN_PASSWORD"]
APPLE_ISSUER_ID = ENV["APPLE_ISSUER_ID"]
APPLE_KEY_ID = ENV["APPLE_KEY_ID"]
APPLE_KEY_CONTENT = ENV["APPLE_KEY_CONTENT"]
GIT_AUTHORIZATION = ENV["GIT_AUTHORIZATION"]
TEAM_ID = '752MACT599'
ORG_NAME = 'Meter'
PROJECT_NAME = 'Meter'
SIGH_PROVISIONING_PROFILE_NAME = "com.meter.vpn-client1 AppStore"

def delete_temp_keychain(name)
  delete_keychain(
    name: name
  ) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db")
end

def create_temp_keychain(name, password)
  create_keychain(
    name: name,
    password: password,
    unlock: false,
    timeout: 0
  )
end

def ensure_temp_keychain(name, password)
  delete_temp_keychain(name)
  create_temp_keychain(name, password)
end

update_fastlane

desc 'Build, Archive, and Upload to App Store Connect'
lane :release do |options|
  is_nightly = 0

  app_identifier = ENV['APP_IDENTIFIER']
  scheme = 'Meter'
  configuration = 'Release'

  UI.message("Debug: Creating App Store Connect API key...")

  keychain_name = TEMP_KEYCHAIN_USER
  keychain_password = TEMP_KEYCHAIN_PASSWORD
  ensure_temp_keychain(keychain_name, keychain_password)

  api_key = app_store_connect_api_key(
    key_id: APPLE_KEY_ID,
    issuer_id: APPLE_ISSUER_ID,
    key_content: APPLE_KEY_CONTENT,
    duration: 1200,
    in_house: false
  )

  increment_build_number(
    xcodeproj: "Meter.xcodeproj"
  )
  
  match(
    # app_identifier: app_identifier,
    git_basic_authorization: Base64.strict_encode64(GIT_AUTHORIZATION),
    additional_cert_types: 'mac_installer_distribution',
    readonly: false,
    keychain_name: keychain_name,
    keychain_password: keychain_password,
    api_key: api_key,
    platform: "macos"
  )
  cert(
    keychain_path: "~/Library/Keychains/#{keychain_name}-db",
    keychain_password: keychain_password,
    api_key: api_key,
    platform: "macos"
  )
  sigh(
    app_identifier: app_identifier,
    readonly: false,
    cert_id: lane_context[SharedValues::CERT_CERTIFICATE_ID],
    provisioning_name: ENV['SIGH_PROVISIONING_PROFILE_NAME'],
    ignore_profiles_with_different_name: true,
    api_key: api_key,
    platform: "macos"
  )

  update_project_team(
    path: "Meter.xcodeproj",
    teamid: TEAM_ID
  )

  gym(
    project: 'Meter.xcodeproj',
    scheme: scheme,
    export_method: 'app-store',
    configuration: configuration,
    clean: false,
    derived_data_path: './build',
    xcargs: "WARNING_CFLAGS='$(inherited)'",
    skip_profile_detection: true,
  )

  upload_to_testflight(
    app_identifier: app_identifier,
    skip_submission: true,
    skip_waiting_for_build_processing: true,
    pkg: './Meter.pkg'
  )
end

I keep getting the following error; even though I am incrementing the bundle id:

[19:42:32]: Successfully exported and signed the pkg file:
[19:42:32]: /Users/runner/work/client-app-swift/client-app-swift/Meter.pkg
[19:42:32]: ----------------------------------
[19:42:32]: --- Step: upload_to_testflight ---
[19:42:32]: ----------------------------------
[19:42:32]: Creating authorization token for App Store Connect API
[19:42:33]: Ready to upload new build to TestFlight (App: 6449044498)...
[19:42:33]: Going to upload updated app to App Store Connect
[19:42:33]: This might take a few minutes. Please don't interrupt the script.
[19:42:39]: [altool] 2023-09-27 19:42:39.760 *** Error: The provided entity includes an attribute with a value that has already been used The bundle version must be higher than the previously uploaded version: '27'. (ID: a4eed95a-923c-40d7-a697-0c47012fe8be) (-19232)

[19:42:39]: [altool]  {

[19:42:39]: [altool]     NSLocalizedDescription = "The provided entity includes an attribute with a value that has already been used";

[19:42:39]: [altool]     NSLocalizedFailureReason = "The bundle version must be higher than the previously uploaded version: \U201827\U2019. (ID: a4eed95a-923c-40d7-a697-0c47012fe8be)";

[19:42:39]: [altool]     NSUnderlyingError = "Error Domain=IrisAPI Code=-19241 \"The provided entity includes an attribute with a value that has already been used\" UserInfo={status=409, detail=The bundle version must be higher than the previously uploaded version., source={\n    pointer = \"/data/attributes/cfBundleVersion\";\n}, id=a4eed95a-923c-40d7-a697-0c47012fe8be, code=ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE, title=The provided entity includes an attribute with a value that has already been used, meta={\n    previousBundleVersion = 27;\n}, NSLocalizedDescription=The provided entity includes an attribute with a value that has already been used, NSLocalizedFailureReason=The bundle version must be higher than the previously uploaded version.}";

[19:42:39]: [altool]     "iris-code" = "ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE";

[19:42:39]: [altool]     previousBundleVersion = 27;

[19:42:39]: [altool] }

[19:42:39]: Application Loader output above ^
[19:42:39]: Error uploading '/var/folders/r_/vbvvglrx3lvds6dp_mbyq3_c0000gn/T/881530bf-4d94-4419-84f8-32cb1b667364.pkg'.

[19:42:39]: The provided entity includes an attribute with a value that has already been used The bundle version must be higher than the previously uploaded version: '27'. (ID: a4eed95a-923c-40d7-a697-0c47012fe8be) (-19232)

[19:42:39]: The call to the altool completed with a non-zero exit status: 1. This indicates a failure.
[19:42:39]: Could not download/upload from App Store Connect!
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                              Lane Context                                                                                               |
+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| DEFAULT_PLATFORM                   | mac                                                                                                                                                                |
| PLATFORM_NAME                      |                                                                                                                                                                    |
| LANE_NAME                          | release                                                                                                                                                            |
| KEYCHAIN_PATH                      | ~/Library/Keychains/***                                                                                                                                        |
| BUILD_NUMBER                       | 2                                                                                                                                                                  |
| SIGH_PROFILE_TYPE                  | app-store                                                                                                                                                          |
| MATCH_PROVISIONING_PROFILE_MAPPING | {"***"=>"match AppStore *** macos", "***.extension"=>"match AppStore ***.extension macos"} |
| CERT_FILE_PATH                     | /Users/runner/work/client-app-swift/client-app-swift/7532RULTT7.cer                                                                                                |
| CERT_CERTIFICATE_ID                | 7532RULTT7                                                                                                                                                         |
| SIGH_PROFILE_PATH                  | /Users/runner/work/client-app-swift/client-app-swift/AppStore_***.provisionprofile                                                               |
| SIGH_PROFILE_PATHS                 | ["/Users/runner/work/client-app-swift/client-app-swift/AppStore_***.provisionprofile"]                                                           |
| SIGH_UDID                          | 61cc4105-d494-4957-a18a-1a757e194d34                                                                                                                               |
| SIGH_UUID                          | 61cc4105-d494-4957-a18a-1a757e194d34                                                                                                                               |
| SIGH_NAME                          | match AppStore *** macos                                                                                                                         |
| PKG_OUTPUT_PATH                    | /Users/runner/work/client-app-swift/client-app-swift/Meter.pkg                                                                                                     |
| XCODEBUILD_ARCHIVE                 | /Users/runner/Library/Developer/Xcode/Archives/2023-09-27/Meter 2023-09-27 19.39.33.xcarchive                                                                      |
+------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
[19:42:39]: Error uploading pkg file: 
 [Application Loader Error Output]: Error uploading '/var/folders/r_/vbvvglrx3lvds6dp_mbyq3_c0000gn/T/881530bf-4d94-4419-84f8-32cb1b667364.pkg'.
[Application Loader Error Output]: The provided entity includes an attribute with a value that has already been used The bundle version must be higher than the previously uploaded version: '27'. (ID: a4eed95a-923c-40d7-a697-0c47012fe8be) (-19232)
[Application Loader Error Output]: The call to the altool completed with a non-zero exit status: 1. This indicates a failure.

+------------------------------------------------+
|                fastlane summary                |

[!] Error uploading pkg file: 
 [Application Loader Error Output]: Error uploading '/var/folders/r_/vbvvglrx3lvds6dp_mbyq3_c0000gn/T/881530bf-4d94-4419-84f8-32cb1b667364.pkg'.
[Application Loader Error Output]: The provided entity includes an attribute with a value that has already been used The bundle version must be higher than the previously uploaded version: '27'. (ID: a4eed95a-923c-40d7-a697-0c47012fe8be) (-19232)
[Application Loader Error Output]: The call to the altool completed with a non-zero exit status: 1. This indicates a failure.
+------+---------------------------+-------------+
| Step | Action                    | Time (in s) |
+------+---------------------------+-------------+
| 1    | default_platform          | 0           |
| 2    | update_fastlane           | 5           |
| 3    | create_keychain           | 0           |
| 4    | app_store_connect_api_key | 0           |
| 5    | increment_build_number    | 6           |
| 6    | match                     | 4           |
| 7    | cert                      | 0           |
| 8    | sigh                      | 0           |
| 9    | update_project_team       | 0           |
| 10   | gym                       | 299         |
| 💥   | upload_to_testflight      | 6           |
+------+---------------------------+-------------+

[19:42:39]: fastlane finished with errors

Upvotes: 5

Views: 1413

Answers (1)

Keoni
Keoni

Reputation: 51

I've encountered a similar problem. increment_build_number didn't actually work for me, and I think it's because I'm using nativescript. See below for more details. My solution required me to use regex to manually update the Info.plist file.

Solution

  1. I created a custom lane to get and set a new build number. I needed to do this so I could pass the new build number to a shell script,

    desc 'Auto increments and sets the build number.'
    lane :setBuildNumber do |options|
        app_identifier = options[:app_identifier]
        live = options[:live] || false
        api_key = app_store_connect_api_key(
            key_id: ENV['APP_STORE_CONNECT_API_KEY_KEY_ID'],
            issuer_id: ENV['APP_STORE_CONNECT_API_KEY_ISSUER_ID'],
            key_content: ENV['APP_STORE_CONNECT_API_KEY_KEY']
        )
        build_number = app_store_build_number(
            api_key: api_key, 
            live: live,
            app_identifier: app_identifier
        )
        build_number = build_number + 1
        sh("cd ../ && EXPLICIT_BUILD_NUMBER=#{build_number} make set-versions-explicit")
        UI.message "Set Build Number to #{build_number} for #{app_identifier}."
    end
    
  2. The shell script simply calls a regex on the file that needs changing,

    perl -0777 -i -pe 's/CFBundleVersion.*\n.*<\/string>/CFBundleVersion<\/key>\n    <string>$(EXPLICIT_BUILD_NUMBER)<\/string>/g' App_Resources/iOS/Info.plist
    
  3. I call the setBuildNumber lane before I run ns prepare ios to ensure that the generated $(SRCROOT)/nativesriptapp/nativesriptapp-Info.plist file has the correct build number,

    setBuildNumber(app_identifier: package_name)
    sh("ns", "prepare", "ios", "--release", "--clean", "--env.production", "--env.env=prod")
    

Discussion

Getting fastlane to build ios in ci/cd wasn't as trivial as android. Before I encountered this problem, I fist had to get the archive to build.

When I first encountered the error, The provided entity includes an attribute with a value that has already been used, I tried setting the build_number in multiple places including before I ran build_app, upload_to_testflight, and the lane context variable LATEST_BUILD_NUMBER. None of those actually changed the build number in the built ipa file. Ultimately what solved the problem for me was manually updating the correct Info.plist file.

This didn't work for me,

api_key = app_store_connect_api_key(...etc...)
build_num = app_store_build_number(...etc...)
increment_build_number(
    build_number: build_num,
    xcodeproj: "./platforms/ios/APP.xcodeproj" # canonical nativescript path
)

as it failed with error,

[11:20:26]: â–¸ Setting version of project nativesriptapp to:
[11:20:26]: â–¸ 19.
[11:20:26]: â–¸ Also setting CFBundleVersion key (assuming it exists)
[11:20:26]: â–¸ Updating CFBundleVersion in Info.plist(s)...
[11:20:26]: â–¸ $(SRCROOT)/nativesriptapp/nativesriptapp-Info.plist
[11:20:26]: â–¸ Cannot find "$(SRCROOT)/nativesriptapp/nativesriptapp-Info.plist"
[11:20:26]: â–¸ /Users/../code/
[11:20:26]: Cannot set build number with plist path containing $(SRCROOT)
[11:20:26]: Please remove $(SRCROOT) in your Xcode target build settings

It turns out agvtool was failing and people have asked questions about it and the recommended answer is to remove $(SRCROOT) from the path. This wasn't an option for me as these files are generated by nativescript. Instead, we had to use a perl command in a makefile to update the CFBundleVersion in our Info.plist,

perl -0777 -i -pe 's/CFBundleVersion.*\n.*<\/string>/CFBundleVersion<\/key>\n    <string>$(BUILD_NUMBER)<\/string>/g' App_Resources/iOS/Info.plist

so in fastlane we call this command,

sh("cd ../ && BUILD_NUMBER=#{build_number} make set-versions")

You could call a similar regex in any other way using sh. That side stepped having to use the increment_build_number. Note that for us, we had to update the correct Info.plist file before we ran our nativescript prepare commands, that way the Info.plist in the xcode project directory used the new build number. You'll see in the output above our source Info.plist and the generated one after running ns prepare ios,

App_Resources/iOS/Info.plist # We customize this file
$(SRCROOT)/nativesriptapp/nativesriptapp-Info.plist # ns prepare ios creates this file with the one above.

The other gotchas was nativescript can also use the .env file to set the build numberin the generated Info.plist, so we needed to change one more file,

perl -0777 -i -pe 's/BUILD_NUMBER=.*/BUILD_NUMBER=$(EXPLICIT_BUILD_NUMBER)/g' env/.env.base

Passing the --verbose flag and running some of these lanes locally ultimately helped me solve this. It's a slow process because I can't run gitactions locally on MacOS even with using act.

Upvotes: 2

Related Questions