Лучший способ увеличить номер сборки?

Я использовал сценарий оболочки как часть моего процесса сборки Xcode для увеличения номера сборки в файле plist, однако он часто приводит к сбою Xcode 4.2.1 (с ошибкой о том, что цель не принадлежит проект; я предполагаю, что изменение файла plist каким-то образом сбивает с толку Xcode).

Сценарий оболочки сделал это так, чтобы номер сборки увеличивался на agvtool только тогда, когда файл новее, чем файл plist (поэтому простая сборка не увеличивала значение):

if [ -n \"`find ProjDir -newer ProjDir/Project-Info.plist`\" ]; then agvtool -noscm next-version -all; else echo \"Version not incremented\"; fi

Есть ли способ увеличить номер сборки (в файле plist или где-либо еще), который не нарушает Xcode?

ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: теперь я делаю подобные вещи, используя скрипт Python, который я только что опубликовал на github. Это плохо задокументировано, но разработать его не составит труда. В качестве бонуса это репо также содержит полезный скрипт для автоматического объединения сторонней библиотеки в пакет приложения.


person trojanfoe    schedule 13.02.2012    source источник
comment
Если кому интересно: я немного изменил скрипт, чтобы использовать шестнадцатеричные числа вместо десятичных - gist.github. ru / sascha / 5398750   -  person Sascha    schedule 16.04.2013
comment
Вы можете добавить этот сценарий напрямую в качестве действия перед сборкой, без необходимости вызывать внешний сценарий. Не запускайте этот сценарий на этапе сборки; Xcode будет копировать обновленный список только через каждую вторую сборку.   -  person Ed McManus    schedule 23.04.2013
comment
Я получил ошибку отказа в разрешении, поэтому решил указать на этот вопрос и ответ всем, кто испытывает то же самое: stackoverflow.com/q/9850936/519030   -  person Jason    schedule 23.01.2014
comment
Этот сценарий не работает с кодом выхода 1. Кто-нибудь может мне с этим помочь?   -  person Robert J. Clegg    schedule 14.02.2014
comment
@Tander Похоже, вы не предоставляете файл plist в качестве аргумента скрипту.   -  person trojanfoe    schedule 14.02.2014
comment
Где бы я поместил имя списка в скрипт? - извините, я новичок в скриптах.   -  person Robert J. Clegg    schedule 14.02.2014
comment
@Tander См. Снимок экрана в вопросе (в разделе ИЗМЕНИТЬ 2).   -  person trojanfoe    schedule 14.02.2014
comment
@trojanfoe Когда я меняю его на $ {PROJECT_DIR} /tools/bump_build_number.sh$ {PROJECT_DIR} / $ {INFOPLIST_FILE}, я получаю сообщение об ошибке, что такого файла или папки не существует. Где мне разместить сценарий?   -  person Robert J. Clegg    schedule 17.02.2014
comment
@Tander В каталоге с именем tools, справа рядом с .xcodeproj.   -  person trojanfoe    schedule 17.02.2014
comment
Я сделал это: зашел в свою папку iOS, где находится мое приложение, создал папку, а затем попытался снова в Xcode. Все еще та же ошибка. Мне что-то не хватает :(   -  person Robert J. Clegg    schedule 17.02.2014
comment
Я также рекомендую поместить $ {PROJECT_DIR} в качестве пути к скрипту в кавычки для проблемы с пробелами. Угадайте, как я это узнал. ;)   -  person McCygnus    schedule 07.03.2014
comment
Обратите внимание, что это не удастся, если ваш текущий CFBundleVersion включает десятичную дробь, например 1.0. Сценарии оболочки могут добавлять целые числа только с помощью необработанного оператора +. Измените на обычный 1, и он будет работать нормально.   -  person Stan James    schedule 25.03.2014
comment
Примечание для новичков о создании скриптов с нуля: для использования в Xcode вам необходимо сделать исполняемый файл _1 _ / _ 2_. Это можно сделать, запустив chown +x /path/to/file.sh.   -  person Matt    schedule 24.06.2015


Ответы (22)


Если я правильно понял ваш вопрос, вы хотите изменить файл Project-Info.plist, который является частью стандартного шаблона проекта Xcode?

Причина, по которой я спрашиваю об этом, заключается в том, что Project-Info.plist обычно находится под контролем версий, и его изменение означает, что он будет отмечен как измененный.

Если вас это устраивает, то следующий фрагмент обновит номер сборки и пометит файл как измененный в процессе, где get_build_number - это некоторый сценарий (т.е. заполнитель в этом примере) для получения (возможно увеличенного) номера сборки, который вы хотите использовать:

#!/bin/sh

# get_build_number is a placeholder for your script to get the latest build number
build_number = `get_build_number`

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${build_number}" ProjDir/Project-Info.plist

PlistBuddy позволяет вам установить любой ключ в файле plist, а не только номер версии. Вы можете создать все нужные файлы plist и при необходимости включить их в ресурсы. Затем их можно будет прочитать из пакета.

Что касается необходимости показывать версию на панели сведений и в других местах, вы также можете изучить настройки CFBundleGetInfoString и CFBundleShortVersionString.

person Monolo    schedule 15.02.2012
comment
Мне не нужен коммит (или тег) git в файле plist, поэтому простая система увеличения подойдет (как предусмотрено agvtool), однако действие по изменению plist во время сборки Xcode часто ломается (после удаления скрипта он ни разу не разбился, когда он падал каждые 3 сборки или около того). Можно ли поместить информацию о версии в другой файл plist и включить его в комплект и сделать доступным из приложения? - person trojanfoe; 15.02.2012
comment
Отличный скрипт - я бы предпочел объединить его с предложением Hugues BR использовать его только при архивировании сборок. Сохраняет низкие числа и игнорирует, несмотря на то, что многие сборки разработки выполняются между выпусками. - person Jay; 31.03.2014
comment
Что такое get_build_number? Это просто заполнитель? - person chrisp; 13.04.2014
comment
Да, get_build_number - это просто заполнитель - обновил ответ, чтобы уточнить. - person Monolo; 15.08.2018

Я напортачил с множеством ответов на этот вопрос, и ни один из них меня не удовлетворил. Однако я наконец-то придумал смесь, которая мне очень нравится!

Мы просто устанавливаем номер версии для собранного продукта равным количеству коммитов Git. Это не повлияет на систему управления версиями, поскольку сценарий изменяет только созданный продукт.

Добавьте эту фазу сборки Run Script в конец ваших фаз сборки:

if [ "${CONFIGURATION}" = "Release" ]; then
    buildNumber=$(git rev-list --count head)
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
fi

Установите версию Info.plist в своем проекте так, как хотите, она никогда не будет использована при создании сборки выпуска. Я установил для себя AUTOMATED или DEVELOPMENT, чтобы было ясно, когда я запускаю сборку для разработки.

Вот и все! Созданное приложение будет иметь постоянно увеличивающийся номер сборки. (Если вы всегда строите свои сборки из одной и той же ветки.)

Почему мне нравится этот метод:

  • Легкий
  • Не загрязняет историю версий Git
  • CFBundleVersion полностью автоматический
  • Номер красивой версии можно изменить, когда захочу.

Прочие примечания:

  • Если в вашем проекте есть расширения приложений, просто установите тот же сценарий сборки и для этих целей. Это позволит автоматизировать и синхронизировать все номера версий. Магазин приложений требует, чтобы версии расширений соответствовали вашему основному приложению.
person Wil Gieseler    schedule 15.07.2014
comment
Хранение номеров версий в файле plist с контролем версий - лучший способ сделать это, особенно если у вас есть ветка на выпуск, а иногда требуется слияние или выбор вишни. Спасибо! - person Matthew Phillips; 22.09.2014
comment
Вы можете использовать git rev-list --count HEAD вместо git rev-list HEAD | wc -l | tr -d ' '. - person kennytm; 06.01.2015
comment
Хм. Я обнаружил, что если вы используете fastlane для загрузки автоматических сборок таким образом, вы получите: ERROR ITMS-90058: Этот пакет недействителен. Значение ключа CFBundleVersion [DEVELOPMENT] в файле Info.plist должно быть разделенным точками списком, содержащим не более трех неотрицательных целых чисел. - person fatuhoku; 11.03.2015
comment
Когда вы говорите начало и конец сборки, где именно на этапах сборки должны идти эти сценарии? Все этапы сборки не выполняются для создания архива? Как вы гарантируете, что значение git rev-list попадает в архив, но что изменение в plist отменяется после завершения сборки? - person conorgriffin; 22.07.2015
comment
Я не уверен, где именно он должен быть, я поставил первый скрипт как первую фазу сборки, а последний скрипт как последнюю фазу сборки, и это работает для меня. - person Wil Gieseler; 09.08.2015
comment
Но вы не можете зафиксировать Info.plist, поскольку после этого номер сборки устарел. Этот тип решения, который не является новым, работает только в том случае, если вы создаете файл, который не отслеживается системой контроля версий, а Info.plist всегда отслеживается. - person Droppy; 03.01.2018
comment
Вы определенно можете зафиксировать Info.plist с помощью этого решения - в этом вся суть. Info.plist всегда устанавливается и регистрируется с номером версии, установленным на DEVELOPMENT, он временно изменяется в процессе сборки, а затем снова устанавливается на DEVELOPMENT, чтобы Info.plist был стабильным. - person Wil Gieseler; 04.06.2018
comment
Отличное решение! На последнем этапе я изменил РАЗРАБОТКУ на ••• \ АВТОМАТИЧЕСКАЯ \ В \ СОЗДАТЬ \ ФАЗЫ - так как это намного информативнее. Также на первом этапе я добавил обновление в пакет настроек. - person Johan; 23.06.2018
comment
Я думаю, что предпочитаю сбрасывать номер сборки для каждой выпущенной версии (которую я всегда помечаю после архивирования). Итак, я использовал этот stackoverflow.com/a/48934099/84682 в качестве номера сборки. - person Johan; 23.06.2018
comment
Просто обновил это, чтобы это происходило только в режиме выпуска, что не позволяет ему мешать предварительному просмотру SwiftUI. Фу... - person Wil Gieseler; 18.03.2020
comment
Дальнейшее обновление: требуется только одна фаза сборки, путем изменения встроенного продукта вместо системы управления версиями. Намного проще и надежнее! - person Wil Gieseler; 18.09.2020

Я использовал этот блеск. Работает как положено. https://gist.github.com/sekati/3172554 (все кредиты принадлежат оригиналу автор)

Скрипты, которые я модифицировал со временем.

xcode-versionString-generator.sh,

xcode-build-number-generator.sh

Поскольку эта суть помогает сообществу разработчиков, я сделал из нее проект GitHub. Так что давайте его хорошо разовьём. Вот проект GitHub: https://github.com/alokc83/Xcode-build-and-version-generator

Я обновил код обоих скриптов, немного доработав. вместо использования ниже возьмите последнюю версию с GitHub

Для версии:

# xcode-version-bump.sh
# @desc Auto-increment the version number (only) when a project is archived for export. 
# @usage
# 1. Select: your Target in Xcode
# 2. Select: Build Phases Tab
# 3. Select: Add Build Phase -> Add Run Script
# 4. Paste code below in to new "Run Script" section
# 5. Check the checkbox "Run script only when installing"
# 6. Drag the "Run Script" below "Link Binaries With Libraries"
# 7. Insure your starting version number is in SemVer format (e.g. 1.0.0)

# This splits a two-decimal version string, such as "0.45.123", allowing us to increment the third position.
VERSIONNUM=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}")
NEWSUBVERSION=`echo $VERSIONNUM | awk -F "." '{print $3}'`
NEWSUBVERSION=$(($NEWSUBVERSION + 1))
NEWVERSIONSTRING=`echo $VERSIONNUM | awk -F "." '{print $1 "." $2 ".'$NEWSUBVERSION'" }'`
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $NEWVERSIONSTRING" "${PROJECT_DIR}/${INFOPLIST_FILE}"

Для сборки:

# xcode-build-bump.sh
# @desc Auto-increment the build number every time the project is run. 
# @usage
# 1. Select: your Target in Xcode
# 2. Select: Build Phases Tab
# 3. Select: Add Build Phase -> Add Run Script
# 4. Paste code below into new "Run Script" section
# 5. Drag the "Run Script" below "Link Binaries With Libraries"
# 6. Ensure that your starting build number is set to a whole integer and not a float (e.g. 1, not 1.0)

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
person Alix    schedule 18.03.2013
comment
Это будет всегда увеличивать номер сборки, тогда как я хотел, чтобы он увеличивался только при изменении исходного файла. Это просто сценарий, который я использую сейчас, с меньшим количеством проверок безопасности и менее разборчивым в том, что изменилось. - person trojanfoe; 14.01.2014
comment
XCode 5: Редактор (строка меню) → Добавить этап сборки → Добавить скопировать файлы Этап сборки: - person Jonny; 06.02.2014
comment
@trojanfoe: вы можете запустить этот скрипт как обработчик пост-фиксации. В этом сценарии номер сборки будет увеличиваться только тогда, когда вы передадите свой код в репозиторий. Ответ ниже от LostInTheTrees - это нечто большее, чем вы, возможно, захотите. - person Alix; 15.04.2014
comment
Скрипты оболочки, на которые ссылается @Alix, теперь сильно отличаются от размещенных здесь. Чтобы увеличить номер сборки только при сборке архива, вы можете использовать созданный мной смысл, во многом основанный на приведенных выше сценариях Аликс, здесь: gist.github.com/mattpotts/abcffea6d08ad45739ef - person Matthew; 28.03.2015

Вся эта запись была чрезвычайно полезной. Я использовал этот трюк, но настроил свой скрипт как перехватчик после фиксации в GIT, поэтому CFBundleVersion увеличивается после каждой успешной фиксации. Скрипт перехвата находится в .git / hooks. Журнал остается в каталоге проекта.

Это соответствует моему самому основному критерию. Я хочу получить версию из GIT и перестроить ту же сборку, что и раньше. Любое приращение, сделанное в процессе сборки, этого не делает.

Вот мой сценарий:

#!/bin/sh
#
# post-commit
#
# This script increments the CFBundleVersion for each successful commit
#

plist="./XYZZY/XYZZY-Info.plist"
buildnum=$(/usr/libexec/Plistbuddy -c "Print CFBundleVersion" "$plist")
if [ -z "$buildnum" ]; then
    exit 1
fi
buildnumplus=$(expr $buildnum + 1)
/usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnumplus" "$plist"

echo $(date) "- Incremented CFBundleVersion to" $buildnumplus >> hookLog.txt
person LostInTheTrees    schedule 07.02.2013
comment
У меня такое же требование, поэтому номер сборки увеличивается только, если исходный файл был изменен. Я обнаружил, что это работает очень хорошо, и мне не приходилось вносить изменения в сценарий bump_build_number.sh с момента его создания. - person trojanfoe; 08.02.2013

Я не знаю, какой способ лучше, но я отправлю ответ Apple на всякий случай, если кто-то его ищет ...

Согласно этому сообщению Apple о вопросах и ответах:

Автоматизация номеров версий и сборок с помощью agvtool

Ключи номера версии и сборки соответственно определяют маркетинговую и внутреннюю версии вашего приложения. agvtool - это инструмент командной строки, который позволяет автоматически увеличивать эти числа до следующего наибольшего числа или до определенного числа.

Номер сборки указывает на невыпущенную или выпущенную версию вашего приложения. Он хранится в Info.plist вашего приложения как CFBundleVersion (версия Bundle).

Вы должны выполнить следующие шаги в своем проекте Xcode:

  1. Включить agvtool

Перейдите к панели параметров сборки вашей цели, затем обновите ее для всех конфигураций сборки следующим образом:

  • Установите для Current Project Version любое значение по вашему выбору.

Ваш файл данных проекта Xcode, project.pbxproj, включает параметр сборки CURRENT_PROJECT_VERSION (Текущая версия проекта), который указывает текущую версию вашего проекта. agvtool ищет в project.pbxproj CURRENT_PROJECT_VERSION. Он продолжает работать, если CURRENT_PROJECT_VERSION существует, и прекращает работу в противном случае. Его значение используется для обновления номера сборки.

  • Установите для системы управления версиями значение Apple Generic.

По умолчанию Xcode не использует систему управления версиями. Установка системы управления версиями на Apple Generic гарантирует, что Xcode будет включать в ваш проект всю информацию о версиях, созданную с помощью agvtool.

«Установить

  1. Укажите версию и номера сборки

agvtool ищет в Info.plist вашего приложения номера версии и сборки. Он обновляет их, если они существуют, и ничего не делает в противном случае. Убедитесь, что ключи CFBundleVersion (версия пакета) и CFBundleShortVersionString (строка версий пакета, короткая) существуют в вашем Info.plist, как показано на изображении ниже:

«Задайте

Закройте Xcode, затем перейдите в каталог, содержащий файл вашего проекта .xcodeproj, в приложении «Терминал» перед выполнением любой из следующих команд. Файл проекта .xcodeproj содержит project.pbxproj, который используется agvtool. (Это часть, которую вы можете запустить в сценарии, а не в командной строке.)

Обновление номера версии

Чтобы обновить номер версии до определенной версии, запустите

xcrun agvtool new-marketing-version <your_specific_version>

Пример: обновите номер версии до 2.0.

xcrun agvtool new-marketing-version 2.0

Обновление номера сборки

Чтобы автоматически увеличивать номер сборки, запустите

xcrun agvtool next-version -all

Чтобы установить номер сборки вашего приложения для конкретной версии, запустите

xcrun agvtool new-version -all <your_specific_version>

Пример: установите номер сборки 2.6.9.

xcrun agvtool new-version -all 2.6.9

Бонус:

Чтобы просмотреть номер текущей версии, запустите

xcrun agvtool what-marketing-version

Чтобы просмотреть текущий номер сборки, запустите

xcrun agvtool what-version
person FormigaNinja    schedule 25.02.2016
comment
Проблема с этим в том, что agvtool прервет сборку xcode, поэтому его нельзя интегрировать в качестве сценария на этапах сборки. - person Daniel Schlaug; 06.06.2016
comment
Не могли бы вы просто поставить bump через agvtool в предварительные действия сборки схемы? - person lottadot; 18.06.2018
comment
Я добавил его как сценарий пост-действия для построения схемы. Таким образом, он увеличивается после успешной сборки и не отменяет сборку. - person Chad; 15.10.2020

FWIW - это то, что я сейчас использую для увеличения номера сборки только для сборок выпуска (включая архивирование). Прекрасно работает под Xcode 5.1.

Просто скопируйте / вставьте фрагмент в фазу сборки Выполнить скрипт прямо в Xcode:

buildnum=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$PRODUCT_SETTINGS_PATH")

if [ "$CONFIGURATION" = "Release" ]; then
buildnum=$((buildnum + 1))
echo "Build number updated to $buildnum"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildnum" "$PRODUCT_SETTINGS_PATH"
fi;
person Jay    schedule 31.03.2014
comment
Как можно увеличить CFBundleVersion? В Xcode 5.1 это строка в формате 1.0? - person chrisp; 13.04.2014
comment
Наконец-то кто-то все делает правильно :) Зачем мне заботиться о каждой сборке, которую я запускаю на своем устройстве разработчика? Количество выпусков (и выпусков для тестировщиков), а не хм, переместите эти 2 пикселя влево сборки. - person uvesten; 22.04.2015

Спасибо за сценарий. Работает отлично.

Мой Info.plist находится в подкаталоге с именем, содержащим пробелы, поэтому мне пришлось изменить сценарий запуска, заключив в кавычки путь к списку:

${PROJECT_DIR}/tools/bump_build_number.sh "${PROJECT_DIR}/${INFOPLIST_FILE}"

и сценарий оболочки таким же образом с кавычками вокруг всех путей:

#!/bin/sh

if [ $# -ne 1 ]; then
    echo usage: $0 plist-file
    exit 1
fi

plist=$1
dir=$(dirname "$plist")

# Only increment the build number if source files have changed
if [ -n "$(find "$dir" \! -path "*xcuserdata*" \! -path "*.git" -newer "$plist")" ]; then
    buildnum=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$plist")
    if [ -z "$buildnum" ]; then
        echo "No build number in $plist"
        exit 2
    fi
    buildnum=$(expr $buildnum + 1)
    /usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnum" "$plist"
    echo "Incremented build number to $buildnum"
else
    echo "Not incrementing build number as source files have not changed"
fi
person massimobio    schedule 02.07.2012
comment
Да, в этом есть смысл. Рад, что ты нашел это полезным; С тех пор я без проблем использую Xcode 4. {2,3,4,5}. - person trojanfoe; 03.07.2012
comment
Я бы сэкономил несколько часов, если бы увидел этот ответ! Также обратите внимание, что в номере сборки не должно быть десятичной дроби, иначе BASH сработает. - person Brenden; 08.11.2012

Сценарий, который я сейчас использую, во многом основан на Аликсе, приведенном выше. Моя адаптация, приведенная ниже, добавляет проверку только для автоматического увеличения сборки выпуска / архива.

Без этого изменения будут возникать конфликты управления версиями, поскольку каждый разработчик будет увеличивать номер сборки со своей скоростью. И тот факт, что история git будет излишне загрязнена из-за постоянного изменения номера сборки.

# xcode-build-bump.sh
# @desc Auto-increment Xcode target build number every time the project is archived
# @src stackoverflow.com/a/15483906
# @usage
# 1. Select: your Target in Xcode
# 2. Select: Build Phases Tab
# 3. Select: Add Build Phase -> Add Run Script
# 4. Paste code below in to new "Run Script" section
# 5. Drag the "Run Script" below "Link Binaries With Libraries"
# 6. Insure that your starting build number is set to a whole integer and not a float (e.g. 1, not 1.0)

if [ "Release" != "${CONFIGURATION}" ]
then
    exit 0
fi

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"

Он также доступен (в более легком для копирования и вставки формате) в виде GitHub gist.

person Matthew    schedule 28.03.2015

Я бы рекомендовал использовать авторевизию.

Xcode позволяет использовать файл заголовка (который может быть автоматически сгенерирован во время сборки, а не в собственном vcs) для предоставления значений, которые будут расширены в info.plist во время сборки. Вы можете найти пошаговое руководство по настройке на веб-сайте авторевизии.

Autorevision имеет тип вывода, ориентированный на файлы заголовков этих типов, чтобы помочь именно в этих ситуациях.

person dak180    schedule 29.08.2013
comment
Autorevision, похоже, не увеличивает номер сборки, как требуется? - person trojanfoe; 29.08.2013
comment
Предполагая, что один из них строится только на новом коммите, VCS_NUM должен быть тем, что вы ищете ( см. autorevision.h пример). - person dak180; 04.09.2013
comment
Vienna-Info.plist и Vienna-All.xcconfig являются хороший пример того, как это можно настроить в любом проекте xcode. - person dak180; 04.09.2013

Одна проблема с некоторыми из этих решений заключается в том, что Launch Services распознает только четыре пяти основных цифры в версии пакета. У меня есть проект с номером сборки, который исчисляется тысячами, поэтому я хотел использовать некоторые из менее значимых цифр.

Этот сценарий Perl увеличивает все Info.plist в проекте, а не только один для текущей цели, поэтому все номера сборки остаются неизменными. Он также использует одну цифру патча и две второстепенные цифры, поэтому для сборки 1234 задана версия 1.23.4. Я использую его в качестве поведения перед сборкой, поэтому он применяется ко всем проектам, которые я создаю.

Скрипт довольно грубый, но у меня он работает.

#!/usr/bin/perl

use strict;
use warnings;
use v5.12.0;

use Dir::Iterate;

for my $plist_file(grepdir { /-Info.plist$/ } '.') {
    my $build = `/usr/libexec/PlistBuddy -c "Print CFBundleVersion" '$plist_file'`;
    chomp $build;

    next unless $build;

    # Strip dots
    $build =~ s/\.//g;
    $build =~ s/^0//g;

    # Increment
    $build++;

    # Re-insert dots
    $build =~ s/^(\d{0,4}?) (\d{0,2}?) (\d{0,1}?)$/$1.$2.$3/x;

    # Insert zeroes
    $build =~ s{(^|\.)\.}{${1}0.}g;

    system qq(/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $build" '$plist_file');
}
person Becca Royal-Gordon    schedule 16.05.2013
comment
В сообщении, которое вы цитируете, говорится, что 'По сути, LS ожидает следующего формата: nnnnn [.nn [.nn]] [X], где n - это цифра 0–9, квадратные скобки указывают на необязательные компоненты, а X - любая строка, не начинающаяся с цифры. X игнорируется, если он присутствует. '- так что это 99999 сборок. Должно быть достаточно для большинства проектов ..? - person Jay; 31.03.2014
comment
@Jay Я, по-видимому, неправильно понял это как четыре цифры. Ой. (Тем не менее, если ваш стиль разработки включает в себя множество настроек и перестроек, вполне возможно, что вы сможете достичь 100 000 сборок после многих лет разработки проекта.) - person Becca Royal-Gordon; 03.04.2014
comment
@ BrentRoyal-Gordon Верно - я настроил свой скрипт сборки, чтобы увеличивать количество сборок только для конфигураций выпуска ... хотя я, вероятно, никогда не достигал и близко к 10k сборок, даже с моим устаревшим продуктом более 10 лет, он вроде как приятно иметь множество головных уборов с новыми проектами Какао ;-) - person Jay; 03.04.2014

Вы можете использовать общее управление версиями Apple . По сути, все, что вам нужно сделать, это вызвать agvtool next-version -all из каталога, в котором находится ваш файл .xcproj. Для получения дополнительной информации проверьте URL-адрес выше.

person Valentin Radu    schedule 31.08.2015
comment
Проблема с этим решением заключается в том, что вызов agvtool из сценария в проекте отменяет вашу сборку. Это не лучшее решение, если вы не можете найти обходной путь. - person dwlz; 19.07.2016

Основываясь на решении Вила Гизелера, я хотел внести только одно изменение. Его решение помещает количество коммитов git в номер сборки. Полезно, но все же довольно сложно найти фактический коммит, создавший эту сборку. Меня не слишком заботило, будет ли номер сборки монотонно увеличиваться, поэтому я отказался от этого требования, чтобы мне было легче получить доступ к фиксации, которая сгенерировала данный двоичный файл.

С этой целью я изменил его первый сценарий следующим образом:

# Set the build number to the decimal conversion of the short version of the current git SHA

# Get the short version of the current git SHA in hexadecimal
SHA=$(git rev-parse --short @)
# Uppercase any alphabetic chars in SHA (bc doesn't like lowercase hex numbers)
UPPERCASE_SHA=$(tr '[:lower:]' '[:upper:]' <<< "$SHA")
# Use bc to convert the uppercase SHA from hex to decimal
BUILD_NUM=$(bc <<< "ibase=16;obase=A;$UPPERCASE_SHA")
# Set our build number to that
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUM" "${PROJECT_DIR}/${INFOPLIST_FILE}"

# To convert a build number back to a usable git SHA, run the following, substituting the build number for <build number>
# bc <<< "ibase=10;obase=16;<build number>"

Это преобразует короткую версию текущего Git SHA в десятичную. Шестнадцатеричные символы плохо сочетаются с требованиями Apple к номерам сборки, поэтому мне пришлось это сделать. Чтобы преобразовать его обратно, вы просто запустите что-то вроде этого:

SHA=$(bc <<< "ibase=10;obase=16;<build number>")

в bash, где <build number> - номер сборки, полученный из двоичного файла. Затем просто запустите git checkout $SHA, и готово.

Поскольку это адаптация решения Уила Гизелера, как упоминалось выше, вам также понадобится следующий сценарий после сборки:

# Set the build number to "DEVELOPMENT"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion DEVELOPMENT" "${PROJECT_DIR}/${INFOPLIST_FILE}"

что сохраняет вашу историю git в чистоте.

person ravron    schedule 23.03.2015
comment
Итак, как это работает, если вы будете записывать информацию о git в Info.plist, которая сама отслеживается git? - person trojanfoe; 24.03.2015
comment
@trojanfoe Как я уже упоминал в начале ответа, этот ответ является адаптацией решения Уила Гизелера. Таким образом, он требует того же сценария после сборки, который использовался там. Я явно добавил это к ответу. - person ravron; 24.03.2015

Я попробовал модифицированную процедуру, но она не сработала, потому что: -

  1. Xcode 4.2.1 изменяет подкаталог xcuserdata в .xcodeproj

  2. git отмечает предыдущее изменение в Project-Info.plist

Следующая модификация заставляет их игнорировать и отмечает только подлинные изменения: -

if [ -n "$(find $dir \! -path "*xcuserdata*" \! -path "*.git" -newer $plist)" ]; then
person Milliways    schedule 09.04.2012

Вы можете сделать это, только когда вы архивируете (и загружаете, например, в TF). В противном случае номер вашей версии может очень быстро подняться.

В схеме (Продукт / Редактировать схему / Архив / Предварительные действия) вы можете добавить скрипт, который будет выполняться только при архивировании.

Кроме того, вы можете захотеть сбрасывать номер сборки каждый раз, когда увеличиваете версию приложения.

И последнее, если вы вместо этого используете архив, вы можете безопасно отключить:

# if [ -n "$(find "$dir" \! -path "*xcuserdata*" \! -path "*.git" -newer "$plist")" ]; then
...
# else
    # echo "Not incrementing build number as source files have not changed"
# fi

Поскольку номер сборки будет увеличиваться только при архивировании ...

РЕДАКТИРОВАТЬ: исправьте то, что я сказал, предварительные действия в архиве выполняются после сборки (но до архивирования), поэтому номер сборки будет увеличиваться для следующего архива ... Но вы можете создать новую схему и добавить это действие в сборку (предварительно actions) этой новой схемы. и используйте эту схему, когда хотите создать новую сборку

person Hugues BR    schedule 18.12.2012
comment
Да, он быстро растет (5500+ на данный момент), но для меня это не проблема; это просто число. Интересно, сколько раз попадает Cmd-B / Cmd-R, прежде чем что-нибудь вообще сработает ... - person trojanfoe; 18.12.2012

В качестве номера сборки я использую последнюю ревизию SVN. Если вы измените Info.plist в каталоге сборки, вы не повлияете на исходный Info.plist:

# use the last SVN revision as the build number:
Info_plist="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Info.plist"
defaults write "${Info_plist}" CFBundleVersion `svn stat -u | awk '/'"Status against revision:"'/ {print $4}'`
person jack    schedule 29.09.2014

Я чувствую, что нашел свое племя. Племя, надеюсь, вас позабавила VersionX.

Десять лет назад, работая над рабочей областью, в которой было более 25 проектов Xcode, я воспользовался возможностью автоматизировать версию и построить обновления строк до степени, которая может показаться абсурдной, если вы поддерживаете только один или два проекта с периодическими обновлениями.

Версия X:

  • знает тип сборки (Release / Debug)
  • собирает информацию во время сборки из репозитория (поддержка git включена, но ее можно настроить для hg, svn или того, что вы используете)
  • предусмотрены легко настраиваемые причудливые строки маркетинговой версии (которые имели гораздо больше вариаций до того, как App Store ввел соглашение), поэтому вы можете автоматически увеличивать строки, которые включают символы для «бета», например, с использованием соглашения о тегах git.
  • включает класс, заполненный переменными экземпляра, содержащими информацию о версии и фиксации. Это полезно для заполнения вашей панели сведений и построения строк журнала, отчетов о сбоях или отчетов об ошибках по электронной почте пользователей с предварительно заполненной информацией.

Было весело делать это. Я узнал много о системе сборки Xcode.

Вот пример необычных строк версии и сборки, которые VersionX может генерировать автоматически.

Версия X 1.0.1 β7 (c5959a3 «Чистый»)

Маркетинговая версия: VersionX 1.0.1 β7 "1.0.1 является производным от тега для фиксации, в то время как" Beta 7 "автоматически генерируется счетчиком фиксации или счетчиком сборки (например) .

Версия сборки: (c5959a3 «Clean») Отображает короткий хеш фиксации и сообщает, что в каталоге сборки нет незафиксированных изменений.

VersionX (исходный код на GitHub) - барочная система для автоматического увеличения версии и построения строк в Xcode проекты.

Документация VersionX.

person Gary W. Longsine    schedule 19.09.2018

Возможно, вы захотите опробовать новый инструмент, который я разрабатываю, под названием Xcodebump. Он может обрабатывать обновление как CFBundleShortVersionString, так и CFBundleVersion. В качестве последнего шага он также выполнит проверку в git и пометит фиксацию, чтобы она соответствовала этим значениям CFBundle.

Здесь находится проект Xcodebump:

https://github.com/markeissler/Xcodebump

person markeissler    schedule 24.05.2014

Обновляю build number следующим способом.

$INFO_FILE - это путь к файлу plist. И $build_number - это новый номер сборки для этого здания.

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $build_number" "${INFO_FILE}"

Обычно мой $build_number состоит из частей major и minor. minor взято из информации о проекте. Итак, я описываю, как создать часть major.

## Composed by `major` and `minor`. 
## `minor` is parsed from project information. It's another story.
## Examples: `21.1`, or `21.1.3`
build_number="${major_number}.${minor_number}"

У меня есть 2 стратегии, чтобы решить $build_number.

Первая стратегия

Эта стратегия использует счетчик git tag для определения major build number. Если у проекта есть 53 тегов, он вернет 53 с помощью следующего сценария оболочки.

В общем, увеличивается. И это заставит разработчика поставить тег git перед публикацией.

major_number=$(git tag -l | wc -l | grep -oE "\d+")

Вторая стратегия

Пусть система CI Jenkins решит major часть. У него есть переменная окружения BUILD_NUMBER. Он увеличивается автоматически при построении системы CI. Эта информация полезна для отслеживания истории проекта в системе CI.

major_number=${BUILD_NUMBER}
person AechoLiu    schedule 02.08.2016

Вот обновленная версия. Это работает с Xcode 9.3.1, iOS 11.

Щелкните «Фазы сборки» в целевом приложении, щелкните значок «+», чтобы добавить новый сценарий выполнения, и вставьте этот код в поле.

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"

Зайдите в файл Info.plist и установите для параметра «Версия пакета» значение 1, а для параметра «Строка версий пакета, краткое» - значение 1, которое вы должны установить.

Создайте проект с Info.plist в поле зрения, и вы должны увидеть изменение версии Bundle (номер сборки).

  • Обратите внимание, что начиная с Xcode 9.3.1 вы не сможете увидеть эти изменения на вкладке «Общие», но увидите изменения при архивировании сборки и в Info.plist.
person L. Davis    schedule 19.05.2018

Вот мое решение. Если вы похожи на меня: дружелюбны к терминалам, как ruby, как семантическое управление версиями, попробуйте это.

Создайте файл с именем Rakefile, который содержит следующее:

require "xcodeproj"
require "versionomy"

XCODEPROJECT = "MyProject.xcodeproj"
INFOPLISTFILE = "MyProject/MyProject-Info.plist"

$UPDATES = [:major,:minor,:tiny]
$UPDATES.each { |part|
  desc "increment #{part} part of version"
  task "increment:#{part}" do |task|
    version=`/usr/libexec/Plistbuddy -c "Print CFBundleVersion" #{INFOPLISTFILE}`.chomp
    version=Versionomy.parse(version)
    version=version.bump(part)

    # I use the same string for CFBundleVersion and CFBundleShortVersionString for now
    `/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{version}" #{INFOPLISTFILE}`
    `/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString #{version}" #{INFOPLISTFILE}`
    print "version upgraded to #{version}\n"
  end
}

Подготовить: gem install xcodeproj versionomy

Беги: rake increment:major, rake increment:minor или rake increment:tiny, когда хочешь.

person mash    schedule 28.07.2014


Давайте сделаем это по-своему. Номер сборки будет увеличиваться после каждой успешной сборки.

Я проведу вас через 5 изображений, просто просмотрите их.

  1. Выберите «Изменить схему ...» из раскрывающегося списка, когда вы выбираете имя своего проекта, расположенное справа от Stop_build_button. Проверить первый шаг

  2. В левом меню разверните опцию «Сборка» и выберите «Пост-действия» Проверить второй шаг

  3. Здесь вы можете добавить желаемые коды (скрипты), которые вы хотите выполнить после успешной сборки вашей программы. Это место, где мы должны добавить немного кода, чтобы наша автоматизация работала идеально. >> 1. нажмите кнопку «добавить (+)» в левом углу, чтобы добавить новый файл сценария. >> 2. Теперь в раскрывающемся списке выберите «Создать действие сценария запуска» Проверить третий шаг

  4. Он имеет 3 поля >> 1. оболочка уже назначена для вас >> 2. теперь для «Предоставить вам настройки сборки из» выберите имя вашего проекта. >> 3. Есть большое поле для добавления вашего скрипта, просто скопируйте и вставьте туда этот код: Проверить Четвертый шаг

    PLIST = "$ {PROJECT_DIR} / $ {INFOPLIST_FILE}" PLB = / usr / libexec / PlistBuddy LAST_NUMBER = $ ($ PLB -c "Распечатать CFBundleVersion" "$ PLIST") NEW_VERSION = $ (($ LAST_NUMBER + 1)) $ PLB -c "Установить: CFBundleVersion $ NEW_VERSION" "$ PLIST"

  5. После завершения 4-го шага просто выберите «Закрыть», чтобы закрыть окно, и мы должны сделать последний шаг, перейдите к вашему файлу «plist.info» в меню «Файл проекта» и убедитесь, что ключ «Версия пакета» в разделе «Ключ» больше всего содержит числовое значение Отметьте пятый шаг

person Debashish Das    schedule 03.04.2020