Разработка
Автоматизация увеличения номера сборки Xcode в кастомном формате
Управление номерами сборок в Xcode может быть непростым делом, особенно если вы хотите использовать нестандартный формат.
Введение
Разработчики, работающие c iOS, наверняка сталкивались с необходимостью поиска простого и эффективного способа управления номерами сборки в своем кастомном формате. Если это так, то вы не одиноки. В этой статье мы рассмотрим, как автоматизировать процесс увеличения номеров сборок в Xcode с помощью кастомного формата, основанного на дате и счетчике. Целью является не только установка версии CFBundleVersion, но и обновление настроек проекта, что значительно упрощает жизнь разработчика.
Задача
Некоторое время назад мне понадобился метод управления номерами сборок на основе комбинации даты и счетчика. Конечно, существовали уже готовые решения. Например, команда agvtool bump хорошо работает с номерами сборок, основанными на счетчике, просто добавляя +1 к номеру. Однако она не справляется с задачей настройки формата.
Аналогично, PlistBuddy предлагал способ изменения версии CFBundleVersion, но не позволял изменять настройки проекта. Казалось, я уперся в стену. Но, как оказалось, решение было совсем рядом.
Вдохновение
Прорыв произошел после прочтения статьи Тревора с сайта theswift.dev. Его статья об использовании переменных окружения Xcode для автоматического увеличения номера сборки натолкнула на мысль.
Концепция была проста, но эффективна: хранить версию и номер сборки в файле проекта (точнее, в файле project.pbxproj), затем использовать $(CURRENT_PROJECT_VERSION) для номера сборки и $(MARKETING_VERSION) для версии в настройках сборки каждой цели и в файле Info.plist.
Такой подход открывал возможность задать собственный формат для номера сборки, который затем можно было распространить по всему проекту Xcode. Это был тот самый недостающий кусочек головоломки, который я так долго искал.
Пользовательский формат
С этой новой мыслью я решил реализовать пользовательский формат номера сборки YYYYMMDDC, где C — это счетчик для данного дня (например, 202306216 будет 6-й сборкой в этот день). Вот как это можно сделать.
Шаг 1: Создание конфигурационного файла
Прежде всего, необходимо создать в проекте новый конфигурационный файл *.xcconfig. В этом файле необходимо задать две пары ключ-значение: VERSION и BUILD_NUMBER. Вот как это должно выглядеть:
// // Config.xcconfig // carbonwatchuk // // Created by Mateusz Siatrak on 21/06/2023. // // Configuration settings file format documentation can be found at: // https://help.apple.com/xcode/#/dev745c5c974 VERSION = 1.0.1 BUILD_NUMBER = 202306211
Шаг 2. Настройка Xcode на использование файла конфигурации
Для того чтобы Xcode использовал новый файл конфигурации, необходимо задать его для каждой из конфигураций. Это можно сделать в колонке Project → Configurations → Based on Configuration File.
Далее установите значение Current Project Verision в $(BUILD_NUMBER) и Marketing Version в $(VERSION). Это гарантирует, что Xcode знает, какой номер сборки и версию использовать для проекта.
Шаг 3. Автоматизация обновления номера сборки
Последним шагом является написание скрипта, который обновляет BUILD_NUMBER при каждом запуске сборки или при архивировании для TestFlight. Этого можно добиться, добавив для каждой схемы pre-build действие, вызывающее этот сценарий. У вас есть два варианта: написать скрипт непосредственно в приведенной форме или создать отдельный файл скрипта, прикрепить его к проекту Xcode и вызывать скрипт в действии предварительной сборки.
Я выбрал последний вариант. Это позволяет мне изменять скрипт непосредственно из редактора Xcode, не погружаясь в настройки схемы. Вот мой скрипт version.sh:
#!/bin/bash # This script is designed to increment the build number consistently across all # targets. # Navigating to the 'carbonwatchuk' directory inside the source root. cd "$SRCROOT/$PRODUCT_NAME" # Get the current date in the format "YYYYMMDD". current_date=$(date "+%Y%m%d") # Parse the 'Config.xcconfig' file to retrieve the previous build number. # The 'awk' command is used to find the line containing "BUILD_NUMBER" # and the 'tr' command is used to remove any spaces. previous_build_number=$(awk -F "=" '/BUILD_NUMBER/ {print $2}' Config.xcconfig | tr -d ' ') # Extract the date part and the counter part from the previous build number. previous_date="${previous_build_number:0:8}" counter="${previous_build_number:8}" # If the current date matches the date from the previous build number, # increment the counter. Otherwise, reset the counter to 1. new_counter=$((current_date == previous_date ? counter + 1 : 1)) # Combine the current date and the new counter to create the new build number. new_build_number="${current_date}${new_counter}" # Use 'sed' command to replace the previous build number with the new build # number in the 'Config.xcconfig' file. sed -i -e "/BUILD_NUMBER =/ s/= .*/= $new_build_number/" Config.xcconfig # Remove the backup file created by 'sed' command. rm -f Config.xcconfig-e
И вот как я его вызываю:
cd "$SRCROOT/$PRODUCT_NAME" source version.sh
Управление маркетинговыми версиями
Теперь, если вы хотите увеличить номер маркетинговой версии, достаточно изменить значение VERSION в конфигурационном файле. Таким образом, контроль версий становится простым и понятным: достаточно отредактировать один файл — и больше не нужно лезть в настройки проекта.
Резюме
Управление номерами сборок в Xcode может быть непростым делом, особенно если вы хотите использовать нестандартный формат. Однако при правильном подходе можно автоматизировать этот процесс с высокой степенью кастомизации. Храня номера версий в конфигурационном файле и используя сценарий сборки для их увеличения, можно поддерживать последовательный, индивидуальный номер сборки во всем проекте.
Этот метод не только упрощает управление номерами сборок, но и обеспечивает обновление всех соответствующих настроек в проекте. Попробуйте и убедитесь в том, насколько это изменит управление проектами в Xcode.