Changing version and build number for a specific target Fastlane

2.8k views Asked by At

I am trying to implement Fastlane into a Xcode project containing over 30 apps.

At this moment I am stuck with the lane that builds the app for the "AppStore" as it has to change the version and the build number for a specific target. The code for my lane is:

desc "Archives and creates the app for the AppStore"
lane :build_appstore do |options|
    scheme = options[:scheme]
    output_directory = options[:output_directory]
    configuration = options[:configuration]
    export_method = options[:export_method]

    bundle_id = options[:bundle_id]
    version = options[:version]
    build = options[:build]

    # Used for increment_version_number. Does it work?
    ENV["APP_IDENTIFIER"] = options[:bundle_id]
      
    increment_version_number(
        version_number: version
    )
    increment_build_number(
        build_number: build
    )
      
    gym(
        scheme: scheme,
        output_directory: output_directory,
        configuration: configuration,
        export_method: export_method
    )
end

The lanes works but when I have a look at the project, I see that all targets have the version and build number changed which is a little but of inconvenient.

Any ideas??

2

There are 2 answers

1
Reimond Hill On BEST ANSWER

I ended up create using xcodeproj ruby and I create the following lane:

# Sets the "VERSION" and "BUILD" number for a target
#
# @param args [Hash] Key value arguments. All the values are Strings. List: 
#   - target_name: The name of the target (REQUIRED)
#   - version: The version number to be used (REQUIRED)
#   - build: The build number to be used (REQUIRED)
#
desc "Sets the \"VERSION\" and \"BUILD\" number for a target"
lane :set_version_build_number do |args|
    puts("\"set_version_build_number\" lane with ARGUMENTS: #{args}")

    target_name = args[:target_name]
    version = args[:version]
    build = args[:build]

    raise(StandardError, "Invalid ARGUMENTS for: \"set_version_build_number\" LANE") unless (
        target_name != nil &&
        version != nil &&
        build != nil
    )

    puts("Variables:")
    puts("\ttarget_name: #{target_name}")
    puts("\tversion: #{version}")
    puts("\tbuild: #{build}")
    
    project_url = find_xcode_project()
    raise(StandardError, "Invalid Xcode project for: \"set_version_build_number\" LANE") unless project_url != nil
    project = Xcodeproj::Project.open(project_url)

    xc_target = project.targets.find { |target| target.name == target_name }
    raise(StandardError, "Invalid target for: \"set_version_build_number\" LANE") unless xc_target != nil

    xc_target.build_configurations.each { |build_configuration| 
        build_configuration.build_settings["MARKETING_VERSION"] = version
        build_configuration.build_settings["CURRENT_PROJECT_VERSION"] = build
    }

    project.save()
end
0
Mudith Chathuranga Silva On

Try to update CURRENT_PROJECT_VERSION like this

lane :try_update_build_number do
    project_path = "test.xcodeproj" # Add your xcodeproj name
    target_name = "target name".    # Add target name
    configuration_name = "Release"  # Add configuration
    new_build_number = "51".        # Pass build number

    UI.message("Updating build number to #{new_build_number}")

    project = Xcodeproj::Project.open("../#{project_path}")
    target = project.targets.detect { |t| t.name == target_name }

    if target
        target.build_configurations.each do |config|
        if config.name == configuration_name
            config.build_settings["CURRENT_PROJECT_VERSION"] = new_build_number
        end
        end

        project.save
        UI.success("Build number updated successfully!")
    else
        UI.error("Target '#{target_name}' not found in project '#{project_path}'")
    end
end

Or you could pass variables for the below function

 def update_target_build_number(build, build_configuration, target_name)
    project_path = "test.xcodeproj" # Add your xcodeproj name

    UI.message("Updating build number to #{build}")

    project = Xcodeproj::Project.open("../#{project_path}")
    target = project.targets.detect { |t| t.name == target_name }

    if target
        target.build_configurations.each do |config|
        if config.name == build_configuration
            config.build_settings["CURRENT_PROJECT_VERSION"] = "#{build}"
        end
    end

        project.save
        UI.success("Build number updated successfully!")
    else
        UI.error("Target '#{target_name}' not found in project '#{project_path}'")
    end
 end