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


133

Я использовал сценарий оболочки как часть моего процесса сборки 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 . Это не очень хорошо задокументировано, но не должно быть трудным для разработки. В качестве бонуса этот репозиторий также содержит полезный скрипт для автоматического объединения сторонней библиотеки в комплект приложений.


1
Если кому-то интересно: я немного изменил скрипт, чтобы использовать шестнадцатеричные числа вместо десятичных - gist.github.com/sascha/5398750
Саша

1
Вы можете добавить этот сценарий непосредственно перед сборкой, не вызывая внешний сценарий. Не запускайте этот скрипт на этапе сборки; Xcode будет копировать только обновленный список при каждой сборке.
Эд Макманус

3
Из коробки я получил сообщение об ошибке «отказано в разрешении», поэтому подумал, что я укажу на этот вопрос и ответы всем, кто испытывает то же самое: stackoverflow.com/q/9850936/519030
Джейсон

Этот скрипт завершается ошибкой с кодом выхода 1. Кто-нибудь может мне помочь с этим?
Роберт Дж. Клегг

@ Тандер Похоже, вы не предоставляете файл plist в качестве аргумента скрипту.
Trojanfoe

Ответы:


29

Если я правильно понимаю ваш вопрос, вы хотите изменить 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 и при необходимости включить их в ресурсы. Затем их можно прочитать из комплекта.

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


Мне не нужен коммит (или тег) git в файле plist, так что простая инкрементная система хороша (как предусмотрено agvtool), однако процесс модификации plist во время сборки часто ломает XCode (так как удаление сценария, которого он не имел ') t разбился один раз, когда он падал каждые 3 сборки или около того). Можно ли поместить информацию о версии в другой plist- файл и включить ее в комплект и получить доступ из приложения?
trojanfoe

Отличный сценарий - я бы предпочел объединить это с предложением Hugues BR использовать его только при архивировании сборок. Поддерживает низкие значения и игнорирует, сколько сборок dev выполняется между выпусками.
Джей

5
Что такое get_build_number? Это просто какой-то заполнитель?
Четверг

Да, get_build_numberэто просто заполнитель - уточнил ответ, уточни.
Моноло

72

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

Есть два шага, один в начале и один в конце фаз сборки.

В начале:

# Set the build number to the count of Git commits
if [ "${CONFIGURATION}" = "Release" ]; then
    buildNumber=$(git rev-list HEAD | wc -l | tr -d ' ')
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
fi

В конце:

# Set the build number to "DEVELOPMENT"
if [ "${CONFIGURATION}" = "Release" ]; then
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion DEVELOPMENT" "${PROJECT_DIR}/${INFOPLIST_FILE}"
fi

Взглянув на Info.plist в XCode, вы увидите, что номер версии - «РАЗРАБОТКА», но встроенное приложение будет иметь постоянно увеличивающийся номер сборки. (Пока вы всегда делаете свои сборки из одной и той же ветки.)

Установка номера версии обратно в константную строку в конце предотвращает изменение файла Info.plist при сборке приложения.

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

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

Хранение номеров версий из контролируемого версиями файла plist - лучший способ сделать это, особенно если у вас есть брейк на выпуск, а иногда вам нужно объединить или выбрать вишню. Спасибо!
Мэтью Филлипс

14
Вы могли бы использовать git rev-list --count HEADвместо git rev-list HEAD | wc -l | tr -d ' '.
Кеннитм

Хм. Я обнаружил, что если вы используете fastlaneдля загрузки автоматических сборок таким способом, вы получите: ERROR ITMS-90058: «Этот пакет недействителен. Значение для ключа CFBundleVersion [DEVELOPMENT] в файле Info.plist должно быть разделенным периодом списком в большинство трех неотрицательных целых. "
фатухоку

1
Я не уверен, куда именно это должно пойти, я поставил первый скрипт как первый этап сборки, а последний скрипт как последний этап сборки, и он работает для меня.
Уил Гизелер

1
Вы определенно можете зафиксировать Info.plist с помощью этого решения - вот и весь смысл. Info.plist всегда устанавливается и регистрируется с номером версии, установленным на «DEVELOPMENT», он временно изменяется во время процесса сборки, а затем снова устанавливается на «DEVELOPMENT», чтобы Info.plist был стабильным.
Уил Гизелер

38

Я использовал этот список. Работает как положено. 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}"

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

XCode 5: Редактор (строка меню) → Добавить фазу сборки → Добавить копии файлов Фаза сборки:
Джонни

@trojanfoe: Вы можете запустить этот скрипт как хук после фиксации. В этом сценарии будет увеличен только номер сборки, когда вы передадите свой код для репо. Ответ от LostInTheTrees ниже - это нечто большее, что вы можете сделать.
Аликс

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

14

Вся эта запись была чрезвычайно полезной. Я использовал этот трюк, но настроил свой скрипт как ловушку пост-фиксации в 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

У меня такое же требование, поэтому номер сборки увеличивается только в случае изменения исходного файла. Я обнаружил, что это работает очень хорошо, и мне не приходилось вносить изменения в bump_build_number.shсценарий с момента создания.
trojanfoe

14

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

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

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

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

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

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

  1. Включить agvtool

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

  • Установите текущую версию проекта на значение по вашему выбору.

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

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

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

Установите систему управления версиями на Apple Generic

  1. Настройте свою версию и номера сборки

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

Настройте свою версию и номера сборки

Выйдите из Xcode, затем перейдите в каталог, содержащий ваш файл проекта .xcodeproj в приложении Terminal, прежде чем выполнять любую из следующих команд. Файл проекта .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

7
Проблема с этим в том, что agvtool прервет сборку xcode, поэтому она не может быть интегрирована как сценарий на этапах сборки.
Даниэль Шлауг

1
Не могли бы вы просто вставить bump через agvtool в предварительные действия сборки схемы?
lottadot

11

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;

Как вы можете увеличить CFBundleVersion? В Xcode 5.1 это строка, отформатированная как "1.0"?
Четкий

1
Наконец-то кто-то делает все правильно :) Зачем мне заботиться о каждой сборке, которую я запускаю на своем устройстве dev? Релизы (и релизы для тестировщиков) учитываются, а не сборки "хм, сдвинь эти 2 пикселя влево".
Uvesten

7

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

Мой Info.plist находится в подкаталоге с именем, содержащим пробелы, поэтому мне пришлось изменить Run Script с кавычками вокруг пути 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

Да, это имеет смысл. Рад, что вы нашли это полезным; С тех пор я пользуюсь без проблем под Xcode 4. {2,3,4,5}.
Trojanfoe

Я бы сэкономил себе несколько часов, если бы увидел этот ответ! Кроме того, обратите внимание, что номер сборки hte не должен иметь десятичную дробь, иначе BASH изменится.
Бренден

6

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

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

# 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 .


5

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

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

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


1
Autorevisionне появляется, чтобы поднять номер сборки, как требуется?
Trojanfoe

Предполагая, что он строится только на новом коммите, тогда это VCS_NUMдолжно быть то, что вы ищете ( см. autorevision.hПример ).
dak180

Vienna-Info.plist и Vienna-All.xcconfig - хороший пример того, как это можно сделать в любом проекте xcode.
dak180

4

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

Этот сценарий Perl увеличивает все Info.plists в проекте, а не только один для текущей цели, поэтому номера сборок остаются в непрерывном режиме. Он также использует одну цифру патча и две младшие цифры, поэтому сборка 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');
}

В сообщении, которое вы цитируете, говорится : «По сути, LS ожидает следующий формат: nnnnn [.nn [.nn]] [X], где n - это цифра от 0 до 9, квадратные скобки указывают необязательные компоненты, а X - любая строка, не начиная с цифры. Х игнорируется, когда присутствует. '- так что это 99999 сборок. Должно быть достаточно для большинства проектов ..?
Джей

@ Джей, я, очевидно, неправильно понял это как четыре цифры. К сожалению. (Тем не менее, если ваш стиль разработки включает в себя множество настроек и перестройки, немыслимо, что вы сможете достичь 100 000 сборок после нескольких лет разработки проекта.)
Брент Роял-Гордон

@ BrentRoyal-Gordon Правда - я настроил свой скрипт сборки, чтобы увеличивать сборки только для конфигураций релизов ... хотя я, вероятно, никогда не достигал сборок около 10 000, даже с моим более чем 10-летним устаревшим продуктом, это действительно приятно иметь множество головных уборов с новыми проектами Какао ;-)
Jay

4

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


3
Проблема с этим решением заключается в том, что вызов agvtool из скрипта в проекте отменит вашу сборку. Это не хорошее решение, если вы не можете найти обходной путь для этого.
Дэн Левенхерц

3

Основываясь на решении Уилла Гизелера , у меня было только одно изменение, которое я хотел сделать. Его решение помещает количество коммитов 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 в чистоте.


Так как же это работает, учитывая, что вы будете записывать информацию о git Info.plist, которая сама отслеживается git?
Trojanfoe

@trojanfoe Как я уже упоминал в верхней части ответа, этот ответ является адаптацией решения Вила Гизелера. Таким образом, он требует того же скрипта пост-сборки, который использовался там. Я добавил это к ответу явно.
Раврон

2

Я попытался изменить процедуру, и она не сработала, потому что:

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

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

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

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

2

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

В схему (Product / Edit Scheme / Archive / Pre-Actions) вы можете добавить скрипт, который будет выполняться только при архивировании.

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

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

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

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

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


1
Да, он быстро растет (сейчас 5500+), но для меня это не проблема; это просто число. Интересно, сколько раз Cmd-B / Cmd-R получают удар, прежде чем что-либо хотя бы работает, хотя ...
trojanfoe

2

Я использую последнюю версию 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}'`

2

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

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

VersionX:

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

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

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

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

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

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

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

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


1

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

Проект Xcodebump находится здесь:

https://github.com/markeissler/Xcodebump


1

Я обновляю 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+")

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

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

major_number=${BUILD_NUMBER}

1

Вот обновленная версия. Это работает с 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 и установите для «Bundle version» значение 1, а для «Bundle version string, short» значение 1, вы должны быть установлены.

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

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

0

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

Создайте файл с именем, 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когда захотите.


0

Я считаю наиболее удобным использовать Automating Version и номера сборки с помощью agvtool .

Попробуй это:

  1. Настройте его, как описано в документации Apple, ссылка на которую приведена выше.
  2. Добавить сценарий в качестве предварительного действия для проекта -> Изменить схему ... -> Архив (или другой, если вы предпочитаете)
  3. Set: предоставить настройки сборки из <your_app_target>

Скрипт (первая строка необязательна):

exec > ${PROJECT_DIR}/prebuild.log 2>&1
cd ${PROJECT_DIR}
xcrun agvtool next-version -all
cd -

0

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

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

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

  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» в меню «Файл проекта» и убедитесь, что ключ «Версия пакета» в разделе «Ключ» наиболее содержит пятый шаг проверки числового значения

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.