2026 Удалённый Mac: DS_Store, AppleDouble и rsync/SFTP для CI
Версионируйте исключения, delete только в staging, разделяйте учётки, гейты до переключения видимости; далее ссылки на APFS xattr, files-from и атомарный релиз.
Содержание
Три нумерованных риска
- Вилки видны как
._*на Linux и портят подпись. .DS_Storeискажает дельты каталогов и алерты.--deleteбез staging удаляет артефакты при отсутствии парных файлов.
Команды часто объявляют удалённый Mac источником истины для сборок, а затем винят сеть, когда Linux-runner заполняется ._* или .DS_Store. Реже виноват канал: чаще не разведены поверхности записи, нет шаблонов исключений в репозитории с ревью и в заявке не зафиксирован радиус --delete, ограниченный именованным поддеревом staging.
Вилки AppleDouble на «чужих» ФС проявляются как ._* и доходят до подписи или статического анализа при неполном инвентаре. .DS_Store портит дельты каталогов даже при жёстких десктоп-политиках, а rsync --delete без инварианта staging смешивает уборку с удалением реальных артефактов. Не смешивайте сохранение xattr APFS с шумом Finder: в одном runbook это гоняет диагностику между ACL, -aE и простыми exclude без измеримого выигрыша.
Общие учётные данные для интерактивного SFTP и CI делают аудит непрозрачным после drag-and-drop метаданных. Хэшировать только крупные бандлы без сверки дерева оставляет вилки, которые ломают цепочку позже. В структурированных логах держите рядом версию шаблона исключений, ID сборки, путь staging и ревизию манифеста — дежурный должен восстановить картину за минуты.
В разборе инцидентов 2026 снова три профиля: мобильные команды с огромными деревьями DerivedData, контент со смешанными ассетами и артефактами на одном томе, платформы с разными сборками rsync на macOS и Linux. Планирование ёмкости должно учитывать churn inode и число записей каталога, а не только мегабайты в минуту: «зелёный» по объёму прогон может скрыть лавину мелких файлов.
Сдержать дрейф помогают негативные тесты с .DS_Store у publish-якоря, три dry-run со сводными удалениями и передачами против манифеста, раздельные шаблоны push/pull и серверные слои «люди / билдер / read-only якорь для CI». Зафиксируйте в тикете версию шаблона, счётчики шума, область delete и дайджест манифеста до закупки нового оркестратора. NFS, кэши IDE и договорные глубины хэширования разбираются в следующем разделе.
Углубление и пограничные сценарии
Ночные пайплайны и дневные ручные загрузки на одном дереве дают скрытые гонки. Зафиксируйте окна, когда пишет только CI, и отдельно — когда допускаются люди; иначе счётчики шума растут без единого «плохого» коммита.
Экспортированные .xcarchive и .ipa часто содержат xattr, которые не видны в списке файлов. Добавьте выборочный обход с xattr -l на эталонных бинарниках до отправки, не смешивая это с простым исключением ._*.
Старые SMB/NAS могут оставлять скрытые lock-файлы на стороне сервера. Протокол и права squash должны быть в том же тикете, что и exclude-лист, иначе сравнение инвентарей между сторонами бессмысленно.
Кэши CocoaPods, Gradle или npm, скопированные с Mac, раздувают inode. Держите их на отдельном томе или жёстко исключайте; иначе лимиты исчерпываются до шага подписи.
Для медиа-ассетов задайте лимит размера пакета и обязательный LFS/Git-обходчик. Массовый drag-and-drop обходит хуки и возвращает шум Finder.
Логи приложений должны нести ID политики исключений, а не только версию rsync. Тогда скачок счётчиков связывается с конкретным merge в репозитории шаблонов.
Плейбуки ИБ разделите: «взрыв метаданных» и «реальное удаление». Два коротких скрипта — один считает ._*, второй сверяет манифест построчно — экономят часы расследований.
В договоре фиксируйте, кто и на какой глубине считает дерево. Разные глубины дадут расхождение при зелёных пайплайнах обеих сторон.
Быстрый чек-лист: в тикете есть три агрегата (добавлено/изменено/удалено) и они совпали с последним dry-run? Если нет, приложите структурированный лог раньше, чем покупать новый оркестратор.
How-to: шесть шагов
rsync -az \
--exclude='.DS_Store' \
--exclude='.AppleDouble' \
--exclude='._*' \
--delete \
./staging/out/ user@runner:/data/in/
- Зафиксируйте константы путей для якоря, staging и runner в одном источнике.
- Включайте delete только в поддереве staging.
- Базовые исключения для
.DS_Store,.AppleDouble,._*и кэшей IDE. - Три dry-run: удаления и передачи против манифеста.
- Разделите интерактивный SFTP и CI с read-only якорем.
- Гейт по SHA256 или манифесту до переключения видимости.
Matrix
| Сцена | Решение |
|---|---|
| Малый репозиторий, мало GUI | Исключения + простой хэш |
| Монорепо с сотнями артефактов | files-from/манифест до delete |
| Частые дизайн-отгрузки | Staging + базовый шум |
| Кросс-ОС CI с подписью | Матрица xattr до видимости |
Итог
Версионируемые исключения, delete только в staging, раздельные учётки и гейты до переключения видимости — базовая линия 2026. Аренда Mac не отменяет манифесты, но снижает коллизии человек/автоматизация.