Как экспортировать xcresult из удалённого Mac CI? Руководство 2026
Руководство для инженеров, которым нужно сохранять результаты тестов Xcode в удалённом Mac CI и получать их после завершения workflow. Вы настроите уникальный путь для xcresult, обеспечите загрузку при ошибке теста, проверите скачанный пакет и определите правила именования, доступа и хранения.
Содержание
- Для CI-ответственного: подтвердите, что задача действительно создаёт xcresult
- Для инженера сборки: задайте отдельный путь и проверьте его
- Для сопровождающего workflow: загрузите результат даже после ошибки теста
- Для тестировщика: скачайте пакет и проверьте читаемость
- Для владельца платформы: установите правила имени, хранения и доступа
- Для ответственного за выпуск: примите передачу по двум проверочным прогонам
В справке Apple для xcodebuild есть отдельный параметр -resultBundlePath, задающий путь для пакета результатов тестирования. Поэтому указывайте для каждой задачи собственный путь к .xcresult, настройте загрузку пакета даже после ошибки тестов и затем скачайте его, чтобы открыть и проверить содержимое. Зелёный или красный статус CI сам по себе не подтверждает, что диагностический файл сохранён. Справочник Apple по инструментам командной строки описывает параметр -resultBundlePath.
Кому пригодится. Если вы отвечаете за удалённый Mac CI, вам нужно не только запустить тесты, но и забрать результаты после завершения задачи.
Если вы разбираете сбои или отвечаете за выпуск, здесь описаны проверка деталей теста, правила хранения и приёмка доставки результата.
Для CI-ответственного: подтвердите, что задача действительно создаёт xcresult
Xcode Test Result Bundle — это пакет результатов тестирования, а не обычный текстовый журнал сборки и не архив приложения. Прежде чем настраивать загрузку, проверьте, что задача действительно запускает тесты: например, выполняет xcodebuild test, а не только xcodebuild build или архивирование. Apple описывает запуск тестов и интерпретацию результатов отдельно от других действий Xcode. Документация Apple по запуску тестов и анализу результатов.
Это разграничение помогает не искать файл, который workflow не создавал. Команда сборки может успешно завершиться и произвести приложение, но это ещё не доказывает, что были выполнены тесты или сформирован пакет результатов. Аналогично, лог компилятора пригодится для разбора ошибок сборки, но не заменит отчёт о тестовых запусках, ошибках и приложенных к ним материалах.
В качестве исходной проверки просмотрите конфигурацию задачи и убедитесь, что в ней есть действие тестирования, используемая схема и подходящее назначение. Затем сопоставьте фактическую команду с ожидаемым путём результата. Если этап тестирования пропущен, отключён условием или завершился до вызова xcodebuild test, искать .xcresult в артефактах бессмысленно.
| Что вы видите после запуска | Что это подтверждает | Подходит ли для разбора тестов |
|---|---|---|
| Текстовый журнал сборки | Содержит вывод команд и диагностику сборки | Нет, не заменяет пакет результатов |
| Архив приложения | Содержит результат архивирования приложения | Нет, если отдельно не сохранён пакет тестов |
.xcresult |
Пакет результатов, созданный тестовым запуском | Да, если пакет загрузился и открывается |
| Только успешный статус задачи | Все обязательные шаги workflow прошли по его правилам | Нет, наличие диагностического файла нужно проверить отдельно |
Ориентируйтесь на фактический результат конкретной команды, а не на название workflow или зелёную отметку. Особенно это важно, если один и тот же процесс содержит тестирование, сборку и архивирование: у этих этапов разные выходные файлы и разные задачи при диагностике.
Для инженера сборки: задайте отдельный путь и проверьте его
Параметр -resultBundlePath позволяет явно указать, куда сохранить пакет. Не оставляйте путь неявным, если следующий шаг должен подобрать файл для передачи: предсказуемый путь упрощает и загрузку, и поиск нужного результата. Apple перечисляет этот параметр в справочнике командной строки Xcode.
Пример ниже показывает структуру команды, а не готовую конфигурацию для любого проекта. Замените значения в угловых скобках на идентификаторы вашего workflow, задания и назначения:
RESULT_BUNDLE="$RUNNER_TEMP/<RUN_ID>-<JOB_ID>-<DESTINATION_ID>.xcresult"
xcodebuild test \
-scheme "<SCHEME>" \
-destination "<DESTINATION>" \
-resultBundlePath "$RESULT_BUNDLE"
Уникальный путь решает несколько практических проблем. Во-первых, файл оказывается вне каталога с исходным кодом, поэтому его сложнее случайно добавить в коммит или смешать с результатами сборки. Во-вторых, имя помогает связать пакет с конкретным запуском и конфигурацией. В-третьих, разные тестовые задания или параллельные варианты запуска не должны писать в один и тот же путь: иначе результаты можно перезаписать, потерять или сопоставить не с тем заданием.
Перед тем как передавать путь в команду, проверьте, что каталог для результата доступен процессу сборки, а имя не указывает на уже существующий пакет. Не сохраняйте файл в каталог, который очищается до этапа загрузки. Если матрица тестов создаёт несколько заданий, включите в идентификатор пути параметр, отличающий варианты этой матрицы, либо используйте для каждого задания изолированный каталог.
Как выбрать путь сохранения для тестов в xcodebuild? В команде укажите -resultBundlePath и полный путь к будущему .xcresult. Используйте переменную временного каталога, доступную в вашем CI, и добавьте идентификаторы запуска и тестового задания. Так последующий шаг сможет искать результат там же, а параллельные задания не будут претендовать на один выходной файл.
Проверьте и саму команду в журнале workflow: переменная должна раскрыться, а не остаться строкой $RESULT_BUNDLE. Если переменная задаётся только внутри шага запуска тестов, она не обязательно будет доступна другому шагу. Для загрузки передайте тот же путь через контекст workflow, переменную уровня задания или иной механизм, который поддерживает ваша конфигурация.
Для сопровождающего workflow: загрузите результат даже после ошибки теста
Обычная последовательность «тесты — затем загрузка» ненадёжна, если workflow пропускает последующие шаги после ненулевого кода возврата тестовой команды. Результат может быть создан, но загрузка не произойдёт — и в интерфейсе останется только сообщение о провале. Поэтому задайте для шага передачи условие выполнения, которое срабатывает и при неуспешном тестовом шаге, а сам путь к файлу сделайте таким же, как у xcodebuild.
В GitHub Actions артефакты предназначены для сохранения и скачивания файлов, созданных workflow. В официальной документации показано, как задавать пути при загрузке; можно передать отдельный файл, каталог или несколько путей в соответствии с поддерживаемым синтаксисом действия загрузки. Перед внедрением сверьте текущую конфигурацию с документацией GitHub по сохранению данных workflow в артефактах и описанием артефактов workflow.
Пример ниже показывает, где связать тестовый путь с шагом загрузки. Идентификатор действия и значения в угловых скобках необходимо заменить на одобренную вашей командой версию действия и реальные выражения workflow:
- name: Запустить тесты
env:
RESULT_BUNDLE: <ПУТЬ_В_RUNNER_TEMP>/<RUN_ID>-<JOB_ID>-<DESTINATION_ID>.xcresult
run: |
xcodebuild test \
-scheme "<SCHEME>" \
-destination "<DESTINATION>" \
-resultBundlePath "$RESULT_BUNDLE"
- name: Загрузить результаты тестов
if: ${{ always() }}
uses: actions/upload-artifact@<ЗАКРЕПЛЁННАЯ_ВЕРСИЯ>
with:
name: xcresult-<RUN_ID>-<JOB_ID>-<DESTINATION_ID>
path: <ТОТ_ЖЕ_ПУТЬ_К_РЕЗУЛЬТАТУ>
if-no-files-found: error
Условие always() помогает запустить этап загрузки после провала тестового шага, но не создаёт файл, которого нет. Если xcodebuild не сформировал пакет, загрузчик сообщит об отсутствии файла. Такая ошибка полезна: она отличает «результат не создан» от ситуации, когда загрузка не запускалась вовсе. Для проверки синтаксиса условий можно свериться с документацией GitHub по выражениям workflow.
Кэш не следует считать заменой артефакта. Кэш предназначен для повторного использования данных между запусками и настраивается с этой целью; артефакт нужен, чтобы сохранить результат конкретного запуска и предоставить его для последующего скачивания. Смешение этих ролей усложняет диагностику: наличие кэша не подтверждает, что пакет тестов был загружен и привязан к нужному запуску.
| Способ передачи | Что с ним удобно делать | Ограничение при разборе тестов |
|---|---|---|
Загрузка .xcresult как артефакта |
Сохранить результат конкретного workflow и скачать его позже | Нужно правильно указать путь и настроить выполнение шага после ошибки |
| Загрузка каталога с результатом | Передать каталог, если именно он задан как входной путь | Проверьте, что маска и путь захватывают пакет, а не только соседние файлы |
| Кэширование | Повторно использовать подходящие данные в последующих запусках | Не используйте кэш как единственную запись тестового результата |
| Только журнал шага | Читать стандартный вывод и диагностические сообщения | Пакет результатов тестирования может отсутствовать |
Если workflow использует несколько входных путей или шаблонов, не полагайтесь на то, что широкая маска обязательно захватит пакет целиком. Укажите путь к конкретному результату либо проверьте список загруженных файлов в интерфейсе запуска. Настройте поведение на случай отсутствующего файла так, чтобы ошибка не маскировала сбой тестирования.
Почему пакет не появляется среди загруженных результатов? Проверьте, создаётся ли он командой тестирования, совпадает ли путь загрузки с путём xcodebuild, разрешено ли шагу выполняться после неуспешного теста и не исключает ли файл выбранный шаблон. Отдельно убедитесь, что загрузка не завершилась ошибкой из-за отсутствующего пути.
Для тестировщика: скачайте пакет и проверьте читаемость
После завершения workflow откройте запись нужного запуска и скачайте его артефакт через интерфейс или поддерживаемый вами способ доступа. GitHub документирует скачивание артефактов workflow. Сверьте имя артефакта с идентификаторами запуска и задания: если имена не различают тестовые конфигурации, можно исследовать корректный файл, но приписать его не тому результату.
Проверять пакет следует в macOS-среде с доступными инструментами Xcode. Начните с открытия .xcresult в Xcode и убедитесь, что интерфейс показывает ожидаемый тестовый запуск и его итог. Если интерактивный просмотр не подходит для вашей диагностики, используйте xcresulttool для осмотра содержимого пакета. Apple описывает Xcode как средство анализа результата тестирования и указывает доступные инструменты командной строки; интерфейсы и параметры сверяйте с документацией для версии Xcode, на которой работает ваша среда.
После открытия проверьте не только общий статус. Найдите конкретный упавший тест, сообщение об ошибке и доступную диагностику, связанную с его выполнением. Если ваш проект ожидает данные покрытия или вложенные материалы, проверьте, что они есть именно в скачанном пакете. Не делайте вывод об отсутствии покрытия по одному лишь статусу теста: сначала подтвердите, что результат действительно содержит нужные данные и что workflow настроен на их сбор.
Как получить и открыть результат из GitHub Actions? Скачайте артефакт из записи нужного запуска, распакуйте его, если интерфейс отдал архив, и откройте пакет в Xcode или проверьте его с помощью xcresulttool в macOS-среде. Затем сопоставьте тестовый итог, сообщения об ошибках и нужные проекту вложения с ожидаемой конфигурацией запуска.
Если пакет не открывается, зафиксируйте, что именно вы скачали: сам .xcresult, архив, каталог с вложенным пакетом или лишь текстовый файл. Проверьте целостность передачи и путь внутри распакованного результата. Наконец, сверяйте выбранный Xcode с тем, которым создан пакет, особенно если несколько CI-узлов используют разные версии инструментов.
Для владельца платформы: установите правила имени, хранения и доступа
Артефакт должен быть пригоден для поиска и безопасен для хранения. В имени используйте данные, которые помогают восстановить контекст: идентификатор запуска, тестовое задание и, если применимо, идентификатор конфигурации. Это не заменяет ссылку на запись workflow, но снижает риск перепутать результаты при параллельных прогонах или ручном скачивании.
Срок хранения задавайте исходя из требований проекта и реальных настроек платформы. Не копируйте число дней из чужой конфигурации и не считайте, что любое значение по умолчанию подходит вашей политике. Проверьте срок хранения, заданный для конкретного артефакта и репозитория, а также доступы тех, кто может просматривать и скачивать результаты. Руководство GitHub по артефактам описывает параметры управления ими; фактическое значение нужно сверять в вашей конфигурации и настройках проекта.
Пакет результатов может раскрывать имена тестов, структуру проекта, сообщения об ошибках и другие детали реализации. Поэтому не публикуйте его как открытый файл без отдельной проверки содержимого и политики доступа. Если артефакт нужен внешнему подрядчику или участникам релиза, назначайте доступ осознанно, а не через широкую ссылку, переданную в общем канале.
При оценке среды для удалённого CI отдельно учитывайте контроль доступа к самой машине и доступ к результатам workflow. Это разные границы: право подключиться к Mac не должно автоматически означать право читать артефакты проекта, а доступ к скачанному результату не требует постоянной учётной записи на узле. При выборе удалённого узла сравните фактические варианты в каталоге доступных Mac-узлов, но не подменяйте им настройку прав и хранения в CI.
Для ответственного за выпуск: примите передачу по двум проверочным прогонам
Одного успешного теста недостаточно для приёмки: он не показывает, сохранится ли результат при сбое, ради диагностики которого пакет обычно и нужен. Проведите проверку на успешном запуске и на контролируемом тестовом отказе. Для каждого запуска убедитесь, что пакет появился по ожидаемому пути, загрузился в артефакты, скачивается из записи workflow и читается в Xcode или xcresulttool.
Используйте следующий порядок проверки:
- Зафиксируйте ожидаемую схему, назначение и путь к
.xcresult; убедитесь, что путь уникален для проверяемого задания. - Запустите тесты, которые должны завершиться успешно, и проверьте наличие пакета до шага загрузки.
- Откройте запись запуска и убедитесь, что артефакт назван так, чтобы его можно было связать с этим заданием.
- Скачайте артефакт и проверьте в macOS-среде, что пакет открывается и содержит ожидаемую сводку.
- Запустите контролируемый сценарий с неуспешным тестом и подтвердите, что этап загрузки всё равно выполняется.
- Если результат отсутствует или нечитаем, установите причину по этапам: файл не создан, шаг загрузки пропущен, путь или маска не совпадают либо артефакт уже недоступен согласно настройкам хранения.
Такая приёмка помогает отличить четыре разных класса неисправностей. При ошибке пути ищите расхождение между аргументом -resultBundlePath и значением загрузки. Если этап не выполнялся, проверяйте условия workflow после сбоя теста. Если загружен не тот файл, проверьте маски и каталог. Если артефакт больше не доступен, изучите политику хранения и доступов. Не исправляйте эти причины одной общей мерой вроде повторного запуска: она может скрыть, но не устранить проблему.
Итоговая оценка должна опираться на доставленный и открываемый пакет, а не на один статус CI. Для этой проверки можно использовать простую шкалу: не принято — пакет не найден или не открывается; принято с оговорками — результат открывается, но не содержит обязательных для проекта сведений; принято — успешный и неуспешный тестовые прогоны оставили различимые, скачиваемые и читаемые результаты. Это оценка процесса передачи, а не универсальная характеристика производительности или надёжности конкретной платформы.
Если сейчас вы используете общий компьютер разработчика, Linux-узел без macOS-инструментов или собственный Mac, привязанный к рабочему месту, у этих вариантов есть реальные ограничения: доступность общего устройства зависит от его владельца, Linux не запускает нативный тестовый этап Xcode, а личный Mac требует самостоятельного обслуживания и может стать единственной точкой отказа. Для временного проекта или проверки отдельного CI-контура аренда удалённого Mac у VPSMAC позволяет выделить доступную macOS-среду без покупки отдельной машины; варианты размещения можно сопоставить в каталоге узлов VPSMAC. Если же нагрузка постоянная, требования к обслуживанию особые или тестам нужны физические интерфейсы рядом с оборудованием, сначала сравните аренду с собственным Mac и проверьте эти ограничения на практике.