Skip to content

Instantly share code, notes, and snippets.

@milo-the-dev
Forked from jellybeansoup/update-version.sh
Created October 5, 2015 08:14
Show Gist options
  • Save milo-the-dev/5ca307d32c8b0ce59452 to your computer and use it in GitHub Desktop.
Save milo-the-dev/5ca307d32c8b0ce59452 to your computer and use it in GitHub Desktop.

Revisions

  1. @jellybeansoup jellybeansoup created this gist Jul 9, 2015.
    86 changes: 86 additions & 0 deletions update-version.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    #!/bin/bash
    # A command-line script for incrementing build numbers for all known targets in an Xcode project.
    #
    # This script has two main goals: firstly, to ensure that all the targets in a project have the
    # same CFBundleVersion and CFBundleShortVersionString values. This is because mismatched values
    # can cause a warning when submitting to the App Store.
    #
    # Secondly, the script ensures that the build number is incremented when changes are declared
    # based on git's records. Alternatively the number of commits can be used, and is toggled by using
    # the argument "--reflect-commits". If not on "master", the current branch name will be used to
    # ensure no version collisions across branches.
    #
    # If not using git, you are a braver soul than I.

    ##
    # The xcodeproj. This is usually found by the script, but you may need to specify its location
    # if it's not in the same folder as the script is called from (the project root if called as a
    # build phase run script).
    #
    #xcodeproj="Project.xcodeproj"

    ##
    # We have to define an Info.plist as the source of truth. This is typically the one for the main
    # target. If not set, the script will try to guess the correct file from the list it gathers from
    # the xcodeproj file, but this can be overriden by setting the path here.
    #
    #plist="Project/Info.plist"

    # We use PlistBuddy to handle the Info.plist values. Here we define where it lives.
    plistBuddy="/usr/libexec/PlistBuddy"

    # Get the xcodeproj if we don't already have it
    if [[ -z ${xcodeproj} ]]; then
    xcodeproj=$(find . -depth 1 -name "*.xcodeproj" | sed -e 's/^\.\///g')
    echo "Xcode Project: ${xcodeproj}"
    fi

    # Find unique references to Info.plist files in the project
    projectFile="${xcodeproj}/project.pbxproj"
    plists=$(grep "^\s*INFOPLIST_FILE.*$" "${projectFile}" | sed -e 's/^[^"]*"//g' | sed -e 's/"[^"]*$//g' | sort | uniq)

    # Attempt to guess the plist based on the list we have
    if [[ -z ${plist} ]]; then
    read -r plist <<< "${plists}"
    echo "Source Info.plist: ${plist}"
    fi

    # Find the current build number in the main Info.plist
    mainBundleVersion=$("${plistBuddy}" -c "Print CFBundleVersion" "${plist}")
    mainBundleShortVersionString=$("${plistBuddy}" -c "Print CFBundleShortVersionString" "${plist}")
    echo "Current project version is ${mainBundleShortVersionString} (${mainBundleVersion})."

    # Increment the build number if git says things have changed. Note that we also check the main
    # Info.plist file, and if it has already been modified, we don't increment the build number.
    # Alternatively, if the script has been called using "--reflect-commits", we just update to the
    # current number of commits
    git=$(sh /etc/profile; which git)
    if [[ -n $1 ]] && [[ $1 == "--reflect-commits" ]]; then
    mainBundleVersion=$("${git}" rev-list --count HEAD)
    branchName=$("${git}" rev-parse --abbrev-ref HEAD)
    if [[ branchName != "master" ]]; then
    mainBundleVersion="${mainBundleVersion}-${branchName}"
    fi
    else
    status=$("${git}" status --porcelain)
    if [[ ${#status} != 0 ]] && [[ $status != *"M ${plist}"* ]]; then
    mainBundleVersion=$((${mainBundleVersion} + 1))
    fi
    fi

    # Update all of the Info.plist files we discovered
    while read -r thisPlist; do
    # Find out the current version
    thisBundleVersion=$("${plistBuddy}" -c "Print CFBundleVersion" "${thisPlist}")
    thisBundleShortVersionString=$("${plistBuddy}" -c "Print CFBundleShortVersionString" "${thisPlist}")
    # Update the CFBundleVersion if needed
    if [[ ${thisBundleVersion} != ${mainBundleVersion} ]]; then
    echo "Updating \"${thisPlist}\" with build ${mainBundleVersion}"
    "${plistBuddy}" -c "Set :CFBundleVersion ${mainBundleVersion}" "${thisPlist}"
    fi
    # Update the CFBundleShortVersionString if needed
    if [[ ${thisBundleShortVersionString} != ${mainBundleShortVersionString} ]]; then
    echo "Updating \"${thisPlist}\" with marketing version ${mainBundleShortVersionString}"
    "${plistBuddy}" -c "Set :CFBundleShortVersionString ${mainBundleShortVersionString}" "${thisPlist}"
    fi
    done <<< "${plists}"