Сбой fastlane match: сначала определите слой ошибки

В документации fastlane для CI предусмотрен режим readonly: true: в нём match получает существующие подписывающие материалы, не создавая новые. Это сразу задаёт безопасный порядок действий: сначала проверьте доступ к приватному репозиторию, затем пароль шифрования и авторизацию Apple, а после — сертификат, приватный ключ и профиль. Не пересоздавайте сертификаты только потому, что удалённый Mac не смог прочитать хранилище. Документация fastlane по match и режиму readonly.

Эта инструкция для вас, если вы впервые запускаете fastlane match на удалённом Mac и не можете получить материалы для подписи.
Она также пригодится владельцу общей команды, которому нужно разделить права на хранилище, и сопровождающему CI после миграции на новую машину.

Важно различать несколько независимых проверок. Git-аутентификация подтверждает, что среда может обратиться к репозиторию. MATCH_PASSWORD нужен для расшифровки хранящихся там материалов. Apple Developer account проверяется отдельно. Наконец, Xcode нужна пригодная для подписи связка сертификата с соответствующим приватным ключом и подходящий Provisioning Profile. Успех одного этапа не доказывает, что прошли остальные.

Два результата, которые нельзя путать

У match есть два принципиально разных препятствия: не удаётся получить данные из хранилища либо полученные данные не удаётся расшифровать. В первом случае проверяйте адрес, сеть и Git-учётные данные. Во втором — источник и значение пароля шифрования. Сообщение об ошибке полезно, но надёжнее подтвердить диагноз отдельной проверкой Git и не показывать секреты в командной строке или журнале.

Наблюдение Вероятный слой сбоя Что проверить первым
Git сообщает об отказе в доступе или не удаётся установить SSH-соединение Идентификатор Git либо права на хранилище Адрес, фактически выбранный ключ или HTTPS-учётные данные, доступ учётной записи
Репозиторий доступен, но match не читает зашифрованные данные Пароль match MATCH_PASSWORD, механизм передачи секрета и область его доступности
Материалы извлечены, но Xcode не может подписать приложение Сертификат, приватный ключ, Keychain или профиль Связку сертификата с ключом, назначение профиля и параметры цели сборки

Как понять, что сбой именно в клонировании приватного репозитория? Запустите git ls-remote с тем же URL и той же учётной записью, которые доступны процессу сборки. Команда выводит видимые удалённые ссылки; если соединение или аутентификация не проходят, исправление MATCH_PASSWORD проблему не решит. Описание назначения команды есть в справке Git по git ls-remote.

Проверка должна выполняться именно в контексте того пользователя, который запускает lane. Успешный вход в терминал под вашей интерактивной учётной записью ничего не доказывает, если агент сборки работает от другого пользователя и читает другой HOME, SSH-конфигурацию или Keychain. Для диагностики сохраните сам факт результата и тип ошибки, но не полный URL с токеном, приватный ключ или полный журнал с переменными окружения.

Если git ls-remote проходит, а match сообщает о неверном пароле расшифровки, не меняйте SSH-ключи наугад. Если Git-тест не проходит, начинайте с удостоверения личности и разрешений. Это разделение экономит время и снижает риск случайно менять рабочую цепочку подписи.

Разные машины — разные источники учётных данных

Сценарий «на ноутбуке работает, на удалённом Mac — нет» обычно означает, что машины предъявляют разные удостоверения. На ноутбуке мог быть загружен личный SSH-ключ, сохранены HTTPS-учётные данные или уже открыт доступ через менеджер секретов. После миграции на удалённую машину эти данные автоматически не переносятся.

Сначала выясните, кто именно выполняет сборку: интерактивный пользователь, системный агент или пользователь CI. Затем проверьте его домашний каталог, используемую конфигурацию Git и доступный способ аутентификации. Не копируйте личный приватный ключ в общий проект и не отключайте контроль доступа, чтобы «проверить, сработает ли». Выданные права должны относиться к текущему сборочному удостоверению, а не ко всем пользователям хранилища.

Способ доступа Что проверять на удалённой машине Типичная граница применения
SSH deploy key Какой публичный ключ загружен, доступен ли соответствующий приватный ключ процессу, к нужному ли репозиторию он привязан Отдельный доступ сборочной машины к репозиторию
HTTPS с токеном Источник токена, срок и права, отсутствие токена в URL, истории команд и логах Работа через HTTPS, если разрешённый способ секретов это поддерживает
Другой настроенный backend Фактическую конфигурацию match и права на выбранное хранилище Сценарий, где материалы хранятся не в Git

Для SSH используйте проверку соединения из того же пользователя и среды, где запускается сборка. Инструкция по тестированию SSH-аутентификации помогает установить, какой тип удостоверения отвечает на запрос. Она не заменяет проверку разрешений именно на нужный приватный репозиторий. О назначении и границах deploy keys рассказывает справка по ключам развёртывания.

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

Почему пароль match может быть неверным, хотя репозиторий читается? Это разные секреты. Git-клиент сначала получает зашифрованное содержимое через настроенную аутентификацию. Затем match использует пароль шифрования, обычно передаваемый через MATCH_PASSWORD, чтобы обработать это содержимое. Успех первого действия не подтверждает корректность второго.

Сравните имя переменной в lane и в среде запуска. Проверьте, передаёт ли секрет именно CI-процессу его система управления секретами, а не только интерактивной оболочке пользователя. Убедитесь, что новый Mac подключён к нужному источнику секрета и что в задаче нет переопределения пустым значением. Не распечатывайте значение для сравнения. Если неясно, доступен ли секрет в конкретном событии или контексте CI, сверяйтесь с правилами области видимости секретов в GitHub Actions.

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

Общая команда и CI: ограничьте запись

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

Для CI fastlane рекомендует использовать readonly, чтобы job получал существующие материалы, а не пытался создавать или обновлять их автоматически. Это уменьшает вероятность, что параллельный запуск или неверно настроенная среда изменит общее состояние. Само значение параметра — конкретная часть конфигурации: для lane передавайте readonly: true согласно описанию режима в документации match.

Роль Необходимое действие Чего не следует давать по умолчанию
Разработчик Получать материалы, нужные для своей сборки Запись в хранилище без рабочей причины
Администратор подписывающих материалов Проверять и выполнять согласованные изменения Передавать личные секреты всем разработчикам
CI-агент Читать заранее подготовленные материалы и собирать проект Неограниченное право изменять сертификаты и профили

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

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

После извлечения: сертификат, приватный ключ и профиль

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

Затем проверьте Provisioning Profile. Он должен соответствовать нужному приложению и условиям подписи, включая используемые возможности и разрешённое удостоверение. Сверьте bundle identifier целевого приложения, тип сборки и настройки Xcode с содержимым профиля. В описании Apple о содержимом provisioning profiles объяснено, какие условия связывают профиль с подписью. Если профиль устарел или требует обновления, используйте официальный процесс редактирования, загрузки и удаления профилей, а не удаляйте всё содержимое Keychain.

Ошибку авторизации Apple Developer account отделяйте от отсутствующего ключа на машине. Если проверка учётной записи не проходит, выясняйте права, состояние сессии и используемый способ авторизации. Если же match получил материалы, но сертификат в Keychain не образует пару с приватным ключом, повторная авторизация Apple сама по себе не добавит отсутствующий ключ. Не пересоздавайте сертификат, пока не установили, что именно отсутствует и кто ещё зависит от текущего сертификата.

Условия выбора способа исправления

  • Если Git не может обратиться к приватному хранилищу, исправьте URL, сеть или доступ именно сборочного пользователя; пароль MATCH_PASSWORD пока не меняйте.
  • Если Git получает данные, но они не расшифровываются, проверяйте передачу и значение пароля match; не меняйте SSH-ключ.
  • Если хранилище читается и материалы обрабатываются, но нет подходящей идентичности подписи, проверяйте Keychain, приватный ключ и профиль.
  • Если CI только собирает проект, оставьте readonly: true; если нужно изменить подписывающие материалы, вернитесь к согласованной операции с отдельными правами и ответственным владельцем.
  • Если данных недостаточно, не отзывайте и не выпускайте сертификаты. Сначала повторите проверки в том же контексте пользователя и сохраните безопасные диагностические сведения.

Пошаговая проверка восстановления

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

  1. Определите контекст процесса. Зафиксируйте, кто запускает lane, какой рабочий каталог и HOME он использует и откуда получает переменные. Уберите из диагностических материалов имена пользователей, адреса хранилищ и пути, если их публикация нежелательна.
  2. Проверьте соединение с хранилищем. Запустите git ls-remote под тем же пользователем и с тем же URL, но без токена в командной строке. Запишите только результат: видны ли ссылки или получен отказ.
  3. Сопоставьте удостоверение с доступом. Для SSH проверьте выбранный ключ и соединение; для HTTPS — источник учётных данных и разрешения. Подтвердите, что авторизация относится к нужному репозиторию, а не просто к аккаунту в целом.
  4. Проверьте передачу пароля match. Установите, что процесс видит переменную MATCH_PASSWORD, не выводя её значение. Проверьте имя, источник и область доступности секрета. Если Git успешен, а расшифровка нет, оставайтесь на этом слое.
  5. Получите существующие материалы в режиме чтения. Для CI задайте readonly: true. Успешное чтение подтвердите завершением соответствующего шага и отсутствием ошибки доступа или расшифровки; не считайте этого доказательством готовой подписи.
  6. Проверьте локальную идентичность. Убедитесь, что сертификат и связанный с ним приватный ключ доступны сборочному пользователю в нужном Keychain. Затем проверьте, что профиль относится к целевой конфигурации приложения.
  7. Соберите и архивируйте проект. Запустите реальную сборку с теми же схемой, настройками подписи и пользователем, которые применяются в выпускном контуре. Проверьте завершение build и Archive. Если приложение должно загружаться дальше по процессу выпуска, отдельно проверьте соответствующий этап.
  8. Зафиксируйте доказательства и план возврата. Храните обезличенный результат проверок Git, match, идентичности, профиля и сборки. Перед отзывом, заменой или удалением сертификата выясните зависимые проекты и подготовьте согласованный способ восстановления.

Сценарий из практики диагностики здесь типовой, а не привязанный к конкретному сервису: локальный Mac успешно получает материалы, а новый удалённый Mac после входа в систему видит отказ Git. Разница часто оказывается не в самом репозитории, а в том, что локальный терминал использует загруженный SSH-ключ, а агент на новом Mac — нет. Проверка git ls-remote под пользователем агента обнаруживает это до запуска Xcode. После восстановления доступа отдельно проверяются пароль match и связка сертификата с ключом — это три разных результата, а не одна общая проверка «подпись работает».

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

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

Когда проблема уже в среде сборки

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

Если текущая среда — Windows или Linux без доступного Mac, она не заменит macOS для Xcode-подписи и архивирования. В таком случае сначала определите частоту сборок и требование к постоянно доступному агенту. Для временной проверки релиза достаточно подготовленной удалённой среды; для регулярно работающего CI нужен устойчивый процесс выдачи секретов, доступа и обслуживания.

Главные причины неудачи fastlane match — разные Git-удостоверения на разных машинах, недоступный или неверный пароль шифрования и отсутствие пригодной идентичности подписи после загрузки материалов. Исправляйте только подтверждённый слой и завершайте диагностику реальным Archive, а не одним успешным клонированием.

Если корень проблемы в том, что у вас нет подходящей macOS-среды для сборки и подписи, изучите вариант оформления удалённого Mac и сопоставьте его с частотой выпусков. Для редких задач сначала оцените возможность локальной машины; если нужен отдельный постоянно доступный сборочный контур, аренда Mac у MACCOME может быть практичнее покупки оборудования.