Файл Package.resolved фиксирует версии Swift-зависимостей для CI-сборки — поэтому при сбое удалённой сборки сначала проверьте, какой URL пакета, пользователь macOS и источник учётных данных реально использует задача, а затем убедитесь, что файл фиксации версий включён в репозиторий. Не помещайте токен в URL или исходный код: порядок авторизации зависит от того, выполняется ли сборка в Xcode Cloud или на собственном Mac.

Кому пригодится: вы собираете проект локально, но удалённая задача останавливается при получении приватного Swift-пакета; ниже можно сравнить локальные и CI-учётные данные по проверяемым свидетельствам. Вы обслуживаете xcodebuild или собственный runner и хотите проверить SSH-ключи, проверку узла и пользователя macOS, от имени которого запущена задача. Вы подключили приватную зависимость к Xcode Cloud и хотите применить его авторизацию, а не переносить туда конфигурацию самостоятельного Mac.

Сначала определите этап сбоя и зафиксируйте исходные условия

Сообщение о неудачной сборке само по себе не доказывает, что проблема в пароле или SSH-ключе. Ошибка может возникнуть до компиляции — при обращении к репозиторию или разрешении версий, — либо уже после успешного получения зависимости, когда компилятор обнаруживает ошибку в коде.

Откройте отчёт сборки или полный журнал команды и найдите первую ошибку, относящуюся к пакету. Запишите вход сборки: Xcode Cloud, локально запущенный xcodebuild, агент CI или ручной запуск по SSH. Для собственного Mac зафиксируйте рабочий каталог и macOS-пользователя процесса. Не ориентируйтесь только на итоговый статус: повторные сообщения в конце журнала нередко маскируют первопричину.

Разделите найденное сообщение на тип сбоя:

  • Репозиторий не достигается: ошибка DNS, сетевое соединение не устанавливается или сервер недоступен. Сначала проверяйте сеть и имя узла, а не содержимое сертификатов подписи.
  • Репозиторий отвечает, но доступ запрещён: проверяйте права учётной записи и способ аутентификации, используемый именно удалённым процессом.
  • Репозиторий доступен, но версия не разрешается: проверяйте ссылку на ветку или тег, ограничения в Package.swift и зафиксированное состояние зависимостей.
  • Пакет получен, но сборка не проходит: изучайте ошибки Swift-компиляции и конфигурацию цели. Повторная настройка Git здесь не устранит причину.
Сопоставьте текст первой ошибки с [описанием типовых проблем конфигурации и сборки Xcode](https://developer.apple.com/documentation/xcode/resolving-common-configuration-and-build-issues?changes=_7). Это помогает отделить диагностику Swift Package Manager от последующей ошибки компиляции, но не заменяет проверку журнала конкретной задачи.

Сверьте URL, сеть и состояние репозитория

Для каждого приватного пакета сравните источник зависимости в Package.swift, настройках проекта Xcode и зафиксированных сведениях в Package.resolved. Сверяйте не только название репозитория: важно, куда фактически обращается удалённая задача — по SSH или HTTPS, к ожидаемому адресу и именно к нужному проекту.

Если конфигурация проекта не позволяет однозначно определить источник, посмотрите журнал разрешения пакетов и настройки SCM, используемые сборкой. Документация Apple описывает формат объявления зависимости Swift-пакета. В вашем проекте проверьте, совпадает ли фактически используемый адрес с источником, который вы намеревались подключить.

Проверки выполняйте последовательно:

  • Убедитесь, что имя узла разрешается из среды, где работает сборка.
  • Проверьте сетевое соединение до сервера репозиториев. Если соединение не устанавливается, сначала выясните, доступна ли сеть из CI и не ограничен ли исходящий трафик.
  • Проверьте путь к репозиторию и то, что он существует в нужной SCM-системе.
  • Убедитесь, что указанная ветка или метка версии существует и доступна задаче.
  • Только после этого проверяйте, разрешён ли доступ конкретному пользователю или CI-процессу.
Смена SSH-адреса на HTTPS или наоборот — не универсальное исправление ошибки авторизации. Она меняет способ подключения и требования к учётным данным, но сама по себе не выдаёт доступ к приватному репозиторию. Перед изменением источника зафиксируйте исходный адрес и убедитесь, что соответствующий URL есть в поддерживаемой конфигурации проекта.

Установите реального пользователя и источник учётных данных

Почему локальная сборка проходит, а удалённый Mac не получает приватную зависимость? Чаще всего эти процессы нельзя считать эквивалентными без проверки: у них могут различаться macOS-пользователь, рабочий каталог, настройки Git, загруженные SSH-ключи и доступ к агенту ключей. Сравнивайте фактические условия выполнения, а не только содержимое локального проекта.

На собственном Mac добавьте диагностический вывод в контекст той же задачи, которая завершается ошибкой. Зафиксируйте имя пользователя, каталог запуска и доступную конфигурацию Git. Не выводите секреты и полное содержимое файлов с ключами. Проверка из интерактивного терминала под вашей учётной записью не доказывает, что сервис или runner имеет такой же доступ: задача может запускаться от другого пользователя и не наследовать вашу пользовательскую среду.

Для SSH проверьте, что ключ доступен нужному пользователю и что ssh-agent действительно предоставляет его в контексте задания. Отдельно проверьте known_hosts: проверка сервера должна выполняться предсказуемо и без обхода защиты. Конфигурация, созданная в домашнем каталоге разработчика, не становится автоматически конфигурацией пользователя CI. Учитывайте также права на файлы: слишком широкие права могут привести к тому, что клиент SSH откажется использовать ключ.

Если используется HTTPS, выясните, откуда именно процесс получает учётные данные. Проверьте, не рассчитывает ли задача на интерактивный ввод пароля, которого нет в безголовой сборке. Убедитесь, что секрет передаётся через предназначенное для этого защищённое хранилище или механизм CI, а не из локального профиля пользователя.

Apple отдельно описывает настройку доступа SCM и подключение репозитория к Xcode Cloud: изучите порядок настройки управления исходным кодом и подключения Xcode Cloud к репозиторию. Для Xcode Cloud следуйте его процедуре авторизации приватных зависимостей из раздела ниже. Не переносите туда команды настройки SSH, рассчитанные на самостоятельный Mac.

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

Разберите авторизацию отдельно для Xcode Cloud и собственного Mac

Для самостоятельного macOS runner причина обычно находится в контексте процесса: пользователь, SSH-конфигурация или источник HTTPS-учётных данных. Проверьте доступ от имени того же пользователя, под которым запускается xcodebuild, и тем же способом, который использует задание. Не выдавайте runner более широкие права на все репозитории, если сборке требуется только один приватный пакет.

В Xcode Cloud используйте предусмотренный платформой процесс предоставления доступа к приватной зависимости. Apple публикует отдельные инструкции для доступности зависимостей в Xcode Cloud. Проверьте авторизацию именно для SCM-источника приватного пакета и убедитесь, что она связана с нужным проектом и сборкой. Локальный SSH-ключ, установленный на вашем компьютере, не является доказательством того, что Xcode Cloud сможет скачать пакет.

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

Проверьте Package.resolved и повторяемость разрешения

Package.resolved нужен не только для локального удобства. Apple указывает его использование для закрепления разрешённых версий при непрерывной интеграции. Если ожидаемая фиксация отсутствует или удалённая сборка получает другой набор зависимостей, ошибка может быть связана не с доступом к репозиторию, а с разрешением версии.

Проверьте, что файл находится в ожидаемом месте для структуры проекта и включён в контроль версий там, где это требуется вашему CI-процессу. Сравните состояние файла в рабочей копии разработчика и в ревизии, которую собирает удалённая задача. Уточните, совпадают ли идентификаторы версий и ссылки на выбранные ревизии пакетов. Требования могут зависеть от структуры проекта, поэтому не переносите файл в другой каталог по предположению.

Для изолированной проверки запустите разрешение пакетов и сборку в чистой рабочей копии с тем же коммитом, тем же пользователем и тем же способом авторизации, что и в производственной задаче. В документации Apple о Swift-пакетах в CI описаны фиксация зависимостей и использование файла при непрерывной интеграции.

Не включайте принудительное повторное разрешение как способ «починить» любую ошибку. Оно может изменить выбранные версии и затруднить сравнение с успешной сборкой, но не создаёт доступ к приватному репозиторию. Если вы полагаетесь на поведение Git, отличающееся от настроек Xcode по умолчанию, сначала подтвердите применимость нужной конфигурации по документации Apple для вашего способа запуска. Не меняйте общий Git-конфиг runner без проверки, какие другие проекты и задачи от него зависят.

Выполните исправление и проверьте его по контрольным свидетельствам

Считайте проблему решённой не после исчезновения первого сообщения об ошибке, а когда повторяемая проверка подтверждает и доступ, и правильный набор зависимостей, и успешную сборку. Выполняйте её через тот же вход — Xcode Cloud или команду CI на собственном Mac, — который будет использоваться в работе.

  • [ ] Зафиксируйте коммит, рабочий каталог, способ запуска и macOS-пользователя неудачной задачи.
  • [ ] Найдите первую ошибку, связанную с получением пакета, и определите: сеть, доступ, разрешение версии или компиляция.
  • [ ] Сверьте фактический URL приватного репозитория, его доступность, путь и требуемую ветку или метку.
  • [ ] Проверьте SSH-ключ или HTTPS-учётные данные в контексте реального пользователя задачи; не выводите секреты в журнал.
  • [ ] Для Xcode Cloud используйте его авторизацию SCM; для самостоятельного Mac проверяйте пользовательскую SSH- или Git-конфигурацию.
  • [ ] Сравните Package.resolved в ожидаемой ревизии с файлом, использованным сборкой.
  • [ ] Повторите разрешение пакетов и сборку в чистой рабочей копии через производственный вход.
  • [ ] Сохраните безопасные свидетельства: доступ к репозиторию подтверждён, версии совпадают, конечная сборка проходит.
  • [ ] Если секрет раскрывался, отзовите его, настройте замену и проверьте журналы и конфигурации, где он мог сохраниться.
Для запуска через командную строку используйте тот же проект и тот же контекст учётной записи. Команда xcodebuild и её параметры описаны в [справке Apple по инструменту командной строки Xcode](https://developer.apple.com/documentation/xcode/xcode-command-line-tool-reference?changes=_1&language=objc). Перед повторным запуском проверьте синтаксис и доступность нужных параметров для установленной версии инструментов; не вставляйте реальные токены, приватные адреса и имена пользователей в публикуемые логи или примеры.

Сравните причины по силе подтверждения

Таблица ниже помогает не принимать предположение за диагноз. «Высокая» оценка означает, что указанное свидетельство прямо подтверждает соответствующий участок; низкая — что требуется дополнительная проверка.

<
Наблюдение в задачеВероятный участокСила подтвержденияСледующее действие
Узел не разрешается или соединение не устанавливаетсяDNS или сетьВысокая для проблемы достижимости, низкая для причины недоступностиПроверить сеть из среды runner и доступность адреса
Соединение устанавливается, но сервер отклоняет доступУчётные данные или права SCMВысокая для отказа доступаПроверить пользователя задачи, ключ или токен и предоставленные права
Репозиторий читается, но выбранная версия отсутствуетВетка, метка или ограничение версииВысокая для проблемы разрешения версииСверить Package.swift, Package.resolved и доступные ревизии
Пакет разрешён, ошибка появляется при компиляцииКод или настройки целиВысокая для этапа компиляцииРазбирать первую ошибку компилятора, не менять авторизацию
Если причина подтверждена как особенности собственной сборочной среды, а не как неверные права SCM или расхождение зависимостей, вам может подойти отдельный удалённый Mac. Для оценки такого сценария сначала посмотрите [руководство по удалённому Mac](https://macgpu.com/ru/m4-rukovodstvo.html): сопоставьте способ подключения, управление пользователями и реальный процесс CI со своей задачей. Если постоянная сборочная машина нужна только для временной работы или проверки процесса, сравните эту потребность с [условиями аренды Mac](https://macgpu.com/ru/m4-tseny-arendy.html).

Самостоятельный Mac остаётся разумным выбором, если вам нужны физические интерфейсы, постоянный контроль над оборудованием или длительная стабильная нагрузка. Удалённая среда не исправит отсутствующие права на приватный пакет, неверный Package.resolved или ошибку компиляции. Но если локальная конфигурация перегружена секретами и пользовательскими настройками, а вам нужно воспроизводимое macOS-окружение для временной разработки и CI-проверки, аренда Mac у MACGPU позволяет отделить такую работу от основной машины без покупки отдельного устройства.