11 сентября 2026 года Apple подтвердила загрузку сборок, созданных с помощью Xcode 27 RC, в App Store Connect — это указано в официальном сообщении о выпуске Xcode 27 RC.

Симптом: вы загружаете сборку для команды, но не уверены, можно ли позже дать её внешним тестировщикам или отправить в App Store.
Самое быстрое решение: только внутренняя проверка — выбирайте TestFlight Internal Only; внешний тест или возможный релиз — обычный канал TestFlight и App Store. Для частых публикаций разделите эти направления на два CI-процесса.

01

Кому пригодится этот разбор

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

Она также пригодится небольшой команде с удалённым Mac или собственным Runner, где внутренние тесты и релизные задачи выполняются автоматически. Если вы впервые планируете пригласить внешних тестировщиков и ещё не понимаете ограничение Internal Only, начните с критериев ниже.

Последнее обновление: 11 сентября 2026 года. Факты сверены с документацией Apple о распространении сборок, внутреннем и внешнем тестировании, загрузке сборок и примечаниями к Xcode 27.

02

Сначала определите право на дальнейшее использование сборки

Название варианта в Xcode — это не косметическая настройка. Оно определяет, какие действия будут доступны после загрузки. Поэтому решение нужно принять до создания финального Archive, а не после появления сборки в App Store Connect.

TestFlight Internal Only

Выбирайте этот вариант, если одновременно выполняются все условия:

  • сборку проверяют только участники вашей команды в App Store Connect;
  • внешние тестировщики не нужны;
  • сборка не будет передана клиентам;
  • этот Archive не должен попасть в цепочку внешнего тестирования или отправки в App Store;
  • вы сознательно принимаете необходимость собрать новую версию для другого назначения.

Apple описывает Internal Only как внутреннюю сборку. Она доступна внутренней группе тестирования и не предназначена для внешних тестеров или отправки клиентам. Подробная граница указана в документации Apple о распространении приложения для бета-тестирования и выпуска.

Обычный TestFlight и App Store

Этот путь нужен, когда сборка должна сохранять более широкую перспективу:

  • вы планируете пригласить внешних тестировщиков;
  • продукт проверяет заказчик, партнёр или пользователь за пределами команды;
  • сборка может стать кандидатом на выпуск;
  • один и тот же код должен пройти внешний Beta App Review, а затем рассматриваться для App Store;
  • релизная ветка уже готовится к публикации.

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

Два канала для частых публикаций

Если проект публикуется регулярно, не используйте Internal Only как временный склад «на всякий случай». Организуйте два канала:

  • внутренний канал — быстрые разработки, эксперименты, отладочные переключатели и проверка командой;
  • кандидатный канал — сборки из релизной ветки, внешнее тестирование и возможная отправка в App Store.

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

03

Кто будет тестировать сборку

Главный критерий — не название ветки и не способ запуска CI, а личность тестировщика и дальнейшая цель Archive.

Участники команды

Внутренние тестировщики должны быть пользователями App Store Connect с подходящим доступом к команде. Apple отдельно описывает добавление внутренних тестировщиков и доступные им сборки в официальной справке о внутренних тестировщиках.

Практическое следствие простое: адрес разработчика, который просто получил ссылку, не превращается автоматически во внутреннего тестировщика. Сначала проверьте его роль и принадлежность к команде, затем назначайте сборку.

Internal Only хорошо подходит для таких задач:

  • проверить миграцию базы данных;
  • включить экспериментальный флаг;
  • убедиться, что новый экран собирается и запускается;
  • проверить интеграцию с тестовым сервером;
  • быстро передать сборку коллегам, имеющим доступ в App Store Connect.

Внешние тестировщики

Внешний тестировщик не обязан быть участником вашей команды. Его добавляют через внешнюю группу TestFlight, приглашение или публичную ссылку, если такой способ используется в конкретном проекте. Apple описывает этот сценарий в справке по приглашению внешних тестировщиков.

Здесь уже важна не только загрузка, но и готовность продукта к внешней проверке. Вам могут понадобиться описание теста, корректная информация о версии и прохождение Beta App Review. Не путайте этот этап с App Review: внешний бета-процесс не является окончательным одобрением приложения для App Store.

Конечные пользователи

Если сборка предназначена клиентам, партнёрам или публичной бета-группе, Internal Only сразу исключается. Даже если сейчас вы хотите показать приложение одному человеку, которого знаете лично, его статус важнее вашего намерения. Если он не входит в команду, выбирайте канал, поддерживающий внешнее тестирование.

Обзор различий между внутренними и внешними сценариями приведён в официальном описании TestFlight.

04

Почему удобство загрузки не важнее права на выпуск

Internal Only может казаться безопасным выбором для любого промежуточного Archive: сборка предназначена для проверки, значит, её якобы можно будет расширить позже. Именно это предположение создаёт проблему.

Что даёт Internal Only

Преимущества:

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

Недостатки:

  • сборка не подходит для внешней группы;
  • она не предназначена для отправки в App Store;
  • ошибочный выбор приводит к необходимости подготовить новый Archive;
  • версия, номер сборки, подпись и журналы нужно будет сопоставлять заново.

Что даёт обычный канал

Преимущества:

  • сборка может использоваться во внешнем TestFlight после выполнения требований Apple;
  • её можно рассматривать как кандидата на выпуск;
  • проще сохранить один релизный поток от CI до App Store;
  • внешний фидбэк можно получать до формальной отправки.

Недостатки:

  • требуется более строгий контроль доступа;
  • релизные секреты нельзя выдавать каждому тестовому Job;
  • ошибка в ветке или Scheme может отправить незрелый код дальше;
  • внешний тестовый сценарий может потребовать дополнительной проверки и подготовки материалов.

Apple связывает доступ тестировщиков с назначенными сборками и группами. Это описано в правилах добавления тестировщиков к сборкам. При этом обычная сборка не становится релизом автоматически, а Internal Only не превращается в обычную сборку одним переключателем.

Важно: не планируйте релиз, исходя из того, что обработка, Beta App Review или очередь загрузки завершатся за фиксированное время. Apple не даёт универсального обещания по такому сроку, а состояние сборки нужно проверять в App Store Connect.

05

Как разделить задачи на удалённом Mac и в CI

Удалённый Mac полезен не потому, что меняет правила App Store Connect, а потому, что позволяет постоянно выполнять разные задачи в изолированных средах. Для проекта, где нужен удалённый Mac для iOS-сборок, разделяйте не только команды запуска, но и полномочия.

Внутренний Job

Настройте отдельное задание для разработки:

  • источник — рабочая или экспериментальная ветка;
  • Scheme — явно указанная тестовая схема;
  • экспорт — вариант, предназначенный для внутренней проверки;
  • результат — TestFlight Internal Only;
  • разрешения — только те, что нужны для сборки и внутренней загрузки;
  • публикация — без автоматического шага отправки в App Store.

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

Кандидатный Job

Отдельный процесс должен работать с релизной веткой:

  • запуск — после слияния проверенного кода;
  • Scheme — релизная;
  • экспорт — обычный канал TestFlight и App Store;
  • доступ — через ручное подтверждение или защищённое правило ветки;
  • ключи — только у этого задания;
  • результат — кандидат для внешней проверки или дальнейшей отправки.

Укажите в CI явное условие остановки. Например, если ветка не является релизной, Job не должен получать релизные учётные данные App Store Connect. Если Scheme не совпадает с ожидаемой, процесс должен завершаться до подписи и загрузки.

Изоляция секретов

Разделите:

  • сертификаты и приватные ключи;
  • профиль подписи;
  • учётные данные App Store Connect;
  • переменные Runner;
  • журналы загрузки;
  • права на ручное подтверждение.

Не помещайте реальные адреса, идентификаторы команды, Bundle ID или API-ключи в YAML, скриншоты и статьи команды. Для документации используйте обезличенные значения вроде TEAM_ID, APP_BUNDLE_ID и REDACTED_KEY.

Apple отдельно описывает загрузку сборок в официальной справке App Store Connect. Сама возможность загрузить Archive не доказывает, что выбран правильный канал. После загрузки проверяйте категорию и доступные действия в интерфейсе.

06

Пошаговая проверка перед загрузкой

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

Определите аудиторию

Запишите одну фразу: «Эту сборку будут устанавливать только участники команды» или «Эту сборку должны получить внешние тестировщики». Если формулировка содержит «возможно позже», не выбирайте Internal Only для кандидата.

Зафиксируйте назначение ветки

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

Проверьте Scheme и конфигурацию

Убедитесь, что CI использует ожидаемую Scheme, конфигурацию сборки и способ экспорта. Ошибка здесь может привести к тому, что внутренний процесс загрузит не тот Archive, а релизный — сборку с отладочными параметрами.

Создайте Archive с правильным намерением

До нажатия команды Archive определите, куда пойдёт результат. Archive — это артефакт сборки, а не гарантия конкретного TestFlight-сценария. Сохраните его с обезличенным, но понятным именем: ветка, назначение и номер сборки.

Проверьте способ распределения

Перед загрузкой ещё раз проверьте, выбран ли Internal Only или обычная раздача TestFlight и App Store. Не считайте этот выбор обратимым после появления сборки в App Store Connect.

Загрузите и дождитесь обработки

Apple показывает состояния обработки и доступности сборки в App Store Connect. Для расшифровки статусов используйте официальный справочник состояний сборок. Не делайте вывод о пригодности сборки только по факту завершения команды загрузки.

Проверьте доступную группу

Для внутреннего варианта убедитесь, что сборка видна внутренней группе. Для обычного варианта проверьте, что интерфейс позволяет назначить её нужной внешней группе после выполнения условий Apple. Отсутствие такой возможности — повод сначала проверить категорию загрузки, а не менять сертификаты.

Выполните контрольный сценарий

Загрузите обезличенную внутреннюю сборку и отдельно — кандидатную сборку. Проверьте:

  • отметку Internal для внутреннего варианта;
  • доступность внутренней группы;
  • отсутствие внешнего назначения у Internal Only;
  • доступность дальнейшего кандидатного процесса для обычной сборки;
  • соответствие ветки, Scheme и номера сборки;
  • отсутствие релизных секретов во внутреннем Job.

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

07

Чек-лист выбора канала

Перед загрузкой отметьте каждый пункт:

  • [ ] Сборка предназначена только пользователям, уже добавленным в команду App Store Connect.
  • [ ] Внешние тестировщики не нужны для этого Archive.
  • [ ] Сборка точно не станет кандидатом на отправку в App Store.
  • [ ] Для внутреннего процесса выбрана TestFlight Internal Only.
  • [ ] Для релизной ветки выбран обычный канал TestFlight и App Store.
  • [ ] Внутренний и кандидатный Job используют разные правила запуска.
  • [ ] Релизные ключи недоступны внутреннему Job.
  • [ ] Scheme и конфигурация явно заданы в CI.
  • [ ] После обработки проверена фактическая категория сборки.
  • [ ] Для внешней группы используется новая обычная сборка, если предыдущая была Internal Only.
  • [ ] Архивы, журналы и идентификаторы обезличены в командной документации.
  • [ ] Есть ручная остановка перед кандидатной публикацией.
08

Итоговый выбор для трёх типичных сценариев

Один разработчик

Если вы проверяете код только на собственных устройствах и не планируете приглашать внешних людей, Internal Only подходит. Но для версии, которую вы хотите показать клиенту или выпустить, создайте новый Archive в обычном канале.

Публичная бета

Если в тестировании участвуют люди за пределами команды, сразу выбирайте обычную раздачу TestFlight и App Store. Internal Only здесь экономит только один шаг в момент загрузки, но создаёт повторную сборку позже.

Непрерывный выпуск

Для постоянного CI используйте два Job. Внутренний — для быстрых экспериментальных сборок. Кандидатный — для релизной ветки, внешнего теста и возможной отправки. Internal Only не должен быть промежуточным контейнером для будущего релиза.

09

Частые ошибки после загрузки

Если внешняя группа не видит сборку, сначала проверьте, не была ли она загружена как Internal Only. Эта категория не становится внешней из-за изменения группы или приглашения другого адреса.

Если внутренняя сборка не отображается нужному человеку, проверьте его учётную запись и роль в App Store Connect. Apple связывает внутреннее тестирование с пользователями команды, а не просто с наличием ссылки.

Если кандидатная сборка не готова к отправке, не откатывайте сразу сертификаты и не удаляйте все Archive. Сначала сравните ветку, Scheme, способ экспорта, категорию распределения и статус обработки. Ошибка в выборе канала не исправляется очисткой локального архива.

Для команд, которые уже используют удалённую машину, полезно отдельно проверить настройку Mac для постоянной iOS-сборки и правила доступа к релизным заданиям. Это особенно важно, если один Runner обслуживает и эксперименты, и публикацию.

Если ваш текущий Mac не может постоянно выполнять внутренние проверки и кандидатные сборки, аренда удалённого Mac у KVMNODE может оказаться практичнее отдельного компьютера: локальная машина не должна быть всё время включена, а CI получает постоянную среду для Xcode и подписи. Однако для длительной тяжёлой нагрузки, физического доступа к устройствам или особых требований к периферии собственный Mac может быть разумнее. Перед выбором проверьте, нужен ли вам именно временный или постоянно доступный контур.

Категория Internal Only — это защита назначения сборки, а не универсальный режим TestFlight. Если код останется внутри команды, выбирайте её. Если возможны внешняя бета или App Store, создавайте обычный Archive и ограничивайте риск через разделение веток, секретов и ручных подтверждений.