В сборке появились новые предупреждения конкурентности, а смена версии компилятора не объясняет, какой режим языка использует каждый target.
Быстрый путь: не объединяйте обновление компилятора и переход на Swift 6 language mode. Сначала включите диагностику конкурентности в текущей конфигурации, затем исправляйте проблемы по target и проверяйте Apple-сборки на подходящем удалённом Mac CI.
Материал предназначен разработчикам Swift, которые мигрируют приложение или библиотеку по модулям, а также инженерам, отвечающим за CI для Apple-платформ.
Он пригодится и командам кроссплатформенных Swift-пакетов, которым нужно отделить задачи существующего CI от проверок, требующих Xcode или Apple SDK.
[ SECTION_01 ] До изменений: зафиксируйте исходное состояние проекта
Swift.org объявил о выпуске Swift 6.4 15 сентября 2026 года. Это дата релиза языка и компилятора, но она сама по себе не подтверждает, что конкретная версия Xcode уже включает этот инструментальный набор. Для сопоставления версии Xcode и входящего в неё toolchain проверяйте официальные заметки о выпусках Xcode, а не ориентируйтесь на номер языка в настройках проекта. Объявление Swift 6.4 отдельно подтверждает выпуск этой версии. Дата проверки этого руководства — 10 октября 2026 года; версии инструментов следует повторно сверить перед изменением CI.
До включения новых проверок сохраните исходный профиль сборки. Иначе команда не сможет отличить уже существующие ошибки от диагностических сообщений, вызванных изменением проверок или языка.
- Запишите фактически используемые инструменты. На каждой CI-машине сохраните вывод
swift --version. Для заданий с Xcode зафиксируйте такжеxcodebuild -versionи выбранный toolchain. Это помогает обнаружить ситуацию, когда локальная оболочка и агент CI вызывают разные компиляторы. - Снимите режим языка по каждому target. Проверьте настройки проекта и фактический вызов компилятора в логе. Не считайте версию компилятора подтверждением языкового режима: это отдельные параметры, а режим можно задавать на уровне отдельных целей. Такая граница описана в руководстве Swift по миграции.
- Сохраните базовые результаты. Запишите, какие команды сборки и тестирования выполняются, какие target они охватывают, какие предупреждения и ошибки уже присутствуют. Для тестов сохраняйте имя задания и конфигурацию, а не только отметку «успешно».
- Зафиксируйте состояние исходников и CI. Сохраните идентификатор коммита, параметры сборки и версию конфигурации runner. Это позволит повторить сравнение после исправлений и понять, не изменились ли заодно зависимости или скрипты.
Удобный результат этого этапа — короткая карточка на каждый target: используемый компилятор, Swift language mode, команда сборки, охват тестов и известные исходные диагностики. Если для target нельзя восстановить один из этих пунктов, сначала устраните пробел в наблюдаемости. Иначе миграционный эксперимент будет трудно воспроизвести.
[ SECTION_02 ] Диагностика: включите проверки до переключения режима
Как начать проверять конкурентность, не переводя весь проект в Swift 6 language mode?
Используйте проверки конкурентности в текущем режиме языка и сначала оцените их результат на исходной ветке. Для проектов Swift 5 language mode миграционные рекомендации описывают диагностический этап отдельно от перехода в Swift 6 language mode. Конкретные флаги и настройки зависят от способа сборки и toolchain, поэтому применяйте параметры из официальной стратегии миграции и сверяйте их с фактическим логом компилятора.
Не включайте одновременно новые диагностики, смену режима языка, обновление Xcode и массовое обновление зависимостей. Если после такого изменения сборка падает, команда теряет возможность быстро определить причину. Изменяйте по одному классу условий, а результаты прикрепляйте к конкретному коммиту.
Для каждого target классифицируйте сообщения по источнику:
- собственный код target;
- код, который приходит через зависимость;
- граница между Swift и Objective-C;
- вызов из изолированного контекста или передача данных между контекстами;
- настройки сборки или расхождение toolchain.
Затем разделите найденное на ошибки и предупреждения, влияющие на дальнейшее переключение, и на сообщения, которые только требуют уточнения. Не превращайте перечень предупреждений в счётчик прогресса: одно сообщение может указывать на неверную границу изоляции, а не на независимую мелкую правку.
Диагностика показывает места, которые нужно исследовать, но сама по себе не доказывает, что код безопасен при конкурентном выполнении. Не закрывайте миграционную задачу подавлением предупреждения без зафиксированного объяснения и проверки поведения.
Если проект собирается через Swift Package Manager, начните с воспроизводимой команды пакета и сохраните её вывод. Если Apple-приложение собирается через Xcode, отдельно исследуйте настройки и лог каждого затрагиваемого target. Наличие успешной сборки пакета не гарантирует, что соответствующая схема Xcode использует те же параметры или тот же набор SDK.
Для разбора сообщений используйте официальный перечень частых проблем миграции. Он помогает связать диагностику с темами, которые требуют содержательной правки: Sendable, изоляцией и передачей данных. Решение должно объяснять границу доступа к состоянию, а не просто заставлять компилятор замолчать.
[ SECTION_03 ] Пилот: выберите один target и обработайте его границы
Не начинайте с наиболее связанного модуля только потому, что он важен. Для пилота лучше подходит target с понятными зависимостями, отдельной командой сборки и тестами, которые можно запускать независимо. Такой выбор упрощает откат: изменение можно сравнить с исходным состоянием, не отменяя миграцию остальных частей проекта.
Для выбранного target проходите диагностику по одному смысловому участку:
- Найдите тип или значение, которое передаётся между контекстами конкурентного выполнения.
- Установите, кто владеет изменяемым состоянием и кто имеет право его читать или менять.
- Проверьте, действительно ли тип может безопасно передаваться между контекстами, прежде чем подтверждать соответствие
Sendable. - Проверьте, где действует изоляция, и должна ли она сохраняться при вызове из другого контекста.
- Повторите сборку и тестирование target после исправления, сопоставляя результат с исходным логом.
Отдельно записывайте причины, по которым миграция пока не завершена. Например, зависимость ещё не готова к выбранному режиму или взаимодействие проходит через Objective-C API. Это не означает, что следует немедленно переписывать всё приложение. Это означает, что команде нужно определить границу совместимости, проверить доступные варианты и оставить решение видимым для следующего этапа.
Руководство по постепенному внедрению Swift 6 поддерживает поэтапный подход: можно разносить работу по частям проекта, а не переключать весь код за один раз. Поэтому состояние «пилот прошёл, остальные target ещё не переведены» может быть корректным промежуточным состоянием. Не обозначайте его как полную миграцию.
[ SECTION_04 ] CI-пилот: добавьте повторяемую задачу для выбранного target
Когда локальная проверка пилотного target понятна, добавьте её в CI как отдельную задачу. Сначала оставьте прежнее задание без изменений. Новая задача должна собирать тот же коммит, использовать явно записанный toolchain и сохранять диагностический вывод. Так команда сможет сравнить старый контур с пилотным, не смешивая результаты.
В задаче укажите:
- какой target проверяется и в каком языковом режиме;
- точную команду сборки и связанный набор тестов;
- выбранный компилятор и, если используется Xcode, версию Xcode;
- место хранения лога, результата тестов и собранного артефакта;
- условия, при которых задача считается успешной или требует ручного разбора.
Не считайте «сборка прошла» достаточным критерием. Минимум сравните сборку, предусмотренные тесты и диагностические сообщения. Если тесты не охватывают изменённую границу конкурентного доступа, отметьте это как ограничение, а не как пройденную проверку.
Кроссплатформенный Swift-пакет может продолжать выполнять подходящие для его целевых платформ задания в существующем CI. Но переносимость сборки пакета не превращает этот CI в замену Xcode, Apple SDK или тестированию на Apple-платформе. Это разные проверки с разными требованиями.
Для согласования общей схемы полезно заранее зафиксировать, какие задачи остаются на имеющихся агентах, а какие назначаются Mac-этапу. В разделе NOVAKVM с вариантами удалённого Mac можно отдельно изучить, как устроен доступ к удалённой среде; конкретную пригодность окружения для проекта всё равно нужно подтверждать проверкой требуемого toolchain.
[ SECTION_05 ] Apple-платформы: выполните приёмку на Mac
Какие миграционные проверки требуют Mac, а какие можно оставить в текущем CI?
Mac необходим не для каждого Swift-теста. Он требуется там, где проверяемая задача использует Xcode, Apple SDK, цель Apple-платформы или Simulator. Если проект проверяет только кроссплатформенную логику пакета на поддерживаемой системе, соответствующая работа может оставаться в уже используемом CI. Для Apple-сборок проверяйте фактическую цель и инструменты, а не делайте вывод только по языку проекта.
Порядок приёмки на Mac:
- Сверьте доступный toolchain с требованиями проекта. Получите версии через
swift --versionиxcodebuild -version. Затем проверьте в заметках Apple к выпуску Xcode, какой инструментальный набор указан для конкретного релиза. Не выводите наличие Swift 6.4 из предположения о номере Xcode. - Запустите исходную команду для выбранной схемы или target. Не подменяйте её облегчённой командой, которая не проходит через нужные Apple-инструменты.
- Проверьте сборку для фактической Apple-цели. Если проект использует Simulator, убедитесь, что выбранная задача действительно выполняет нужный этап с Simulator, а не только собирает пакет.
- Выполните относящиеся к миграции тесты. Сохраните результаты и проверьте, что тесты используют ожидаемую схему, SDK и конфигурацию.
- Проверьте артефакт и его назначение. Убедитесь, что собран результат нужного типа и для нужной цели. Проход тестов Swift-пакета не подтверждает готовность Apple-приложения к выпуску.
- Сопоставьте результат с пилотом и исходной конфигурацией. Сохраните логи, параметры и коммит так, чтобы повторный запуск мог подтвердить тот же вывод.
Приёмка должна отвечать на три отдельных вопроса: компилируется ли изменённый код, проходят ли относящиеся к нему тесты и пригоден ли полученный артефакт для требуемой Apple-цели. Если один ответ отсутствует, задача пока не закрыта.
Точные версии компилятора и Xcode, подходящие проекту, нельзя назначить универсально. На них влияют минимальная версия платформы, используемый SDK, внешние зависимости и требования к выпуску. Официальная справка о совместимости версий Swift помогает проверить языковую совместимость, но не заменяет испытание конкретного проекта в его CI.
[ SECTION_06 ] Решение о расширении: сравните результаты и цену отката
После пилота не переводите следующий target автоматически. Сначала сравните его с исходной карточкой: какая диагностика устранена, какие тесты пройдены, использовались ли ожидаемые инструменты и можно ли воспроизвести сборку на другом запуске CI. Если результаты неполные, оставьте target в текущем режиме и уточните проверку.
Условия выбора следующего шага
Используйте список ниже как решение по каждому target. Отметьте подходящую ветку и выполняйте указанное действие; не отмечайте миграцию завершённой, пока не выполнены условия приёмки.
- [ ] Пилот собирается в заданном режиме, тесты охватывают изменённые границы, а Apple-проверки и артефакт прошли на требуемом Mac toolchain. Переводите следующий независимый target и сохраняйте исходный CI-контур для сравнения.
- [ ] Собственный код исправлен, но переход блокирует сторонняя зависимость. Оставьте target в текущем режиме, проверьте совместимое обновление или согласуйте границу совместимости; не объявляйте весь проект переведённым.
- [ ] Агенты CI используют разные версии Swift или Xcode. Сначала выровняйте и зафиксируйте окружение. Пока toolchain не унифицирован, результаты запусков несопоставимы.
- [ ] Не проверены Apple-цель, Simulator или выпускаемый артефакт. Добавьте Mac-этап или отложите приёмку. До появления результата отмечайте миграцию как частично проверенную.
- [ ] Откат требует отменить несвязанные правки. Разделите коммиты и настройки CI до расширения миграции.
Для выбора места выполнения CI-задачи применяйте отдельные условия:
- Если задача проверяет кроссплатформенную логику пакета и не требует Xcode, Apple SDK, Apple-цели или Simulator, оставьте её в существующем CI.
- Если команда использует Apple-инструменты или проверяет сборку и тесты для Apple-платформы, назначьте задачу Mac-этапу.
- Если большая часть пакета кроссплатформенная, но выпуск или интеграционные проверки зависят от Apple SDK, разделите workflow на общий и Mac-этапы.
- Если независимые задачи уже корректно выполняются в существующем CI, не переносите весь процесс на Mac без технической необходимости.
Эти условия помогают выбирать место запуска по требованиям каждой задачи, а не предполагать, что весь проект должен собираться на одной платформе. Схема с общим и Mac-этапом может потребовать согласовать входные данные и передачу артефактов, но позволяет оставить независимые кроссплатформенные проверки в текущем CI.
Команда может вести состояния «диагностика включена», «пилотный target проверен», «миграция распространена на выбранные target» и «Apple-платформенный процесс принят». Эти формулировки точнее, чем один общий флаг «готово»: они показывают, какую часть работы уже подтвердили тестами и сборкой.
Для длительной миграции полезно хранить решения вместе с конфигурацией CI: почему оставлен тот или иной языковой режим, какое ограничение найдено на границе зависимости и какой тест подтверждает исправление. Это снижает риск, что очередное обновление компилятора будет ошибочно принято за завершённый переход на Swift 6 language mode.
Если текущая схема опирается только на Linux или другой уже имеющийся CI, её достоинства — повторное использование инфраструктуры и удобство кроссплатформенных задач. Но она не выполнит Xcode-сборку, проверку с Apple SDK или Simulator; отдельная Mac-машина, в свою очередь, добавит ещё один этап и потребует согласовать toolchain и передачу артефактов. Когда миграция упирается именно в Apple-платформенную приёмку, аренда Mac у NOVAKVM позволяет выделить удалённый Mac для пилотного CI без покупки устройства. Подходящие варианты можно проверить на странице оформления удалённого Mac NOVAKVM; перед запуском всё равно следует подтвердить совместимость доступного окружения с требованиями проекта.