Синхронизация кода и автоматизация¶
tools/mfsync.py синхронизирует одну рабочую копию с её Git remote. GitHub Actions проверяет отправленные изменения и управляет релизами. Это разные задачи: workflow на GitHub не видит несохранённые или неотправленные файлы другого компьютера и не является резервной копией всех его файлов.
Быстрый старт¶
Нужны Git и Python 3.8+. Сам синхронизатор использует только стандартную библиотеку. Запускайте команды из клона репозитория на том компьютере, где меняете код.
python tools/mfsync.py status
python tools/mfsync.py scan --all
python tools/mfsync.py check --strict
python tools/mfsync.py sync --pr --base main
Первый запуск Git настройте своей учётной записью. Для push Git использует установленный credential helper или SSH. Для создания PR нужен GH_TOKEN, GITHUB_TOKEN или MFSYNC_TOKEN в окружении. Токен не подставляется в URL remote и не сохраняется синхронизатором. Права токена ограничьте нужным репозиторием; для PR нужны Contents и Pull requests с записью, а изменение workflow может требовать отдельного разрешения Workflows.
gh auth login
gh auth setup-git
# Только для текущего процесса/сеанса; не добавляйте вывод в логи.
export GH_TOKEN="$(gh auth token)"
git config mfsync.prOnly true
python tools/mfsync.py sync --pr --base main
На Windows ту же переменную можно установить в PowerShell:
$env:GH_TOKEN = gh auth token
python tools/mfsync.py sync --pr --base main
Не отправляйте токены в сообщения, файлы проекта или аргументы URL. Если токен уже был раскрыт, отзовите его в GitHub и выпустите новый. Секреты для Actions добавляются через Settings → Secrets and variables → Actions.
Что делает sync¶
Порядок: fetch → rebase upstream с сохранением локальных изменений → staging → проверка содержимого index → commit с обычными Git hooks → push или PR. Ошибка fetch, stash или незавершённая операция merge/rebase/cherry-pick останавливает процесс до публикации. Конфликт rebase прерывается; при конфликте восстановления stash нужно вручную разрешить отмеченные файлы, исходный stash не теряется.
sync --no-push оставляет новый коммит локально. Сообщение можно задать через -m, либо инструмент соберёт Conventional Commit из изменённых путей. Сканер проверяет именно данные подготовленного коммита, а не только текущие файлы рабочей копии. Он блокирует распознаваемые токены и опасные имена файлов. Это дополнительная защита, не замена полноценному secret scanning: неизвестные форматы, большие файлы и бинарные данные требуют отдельной проверки.
python tools/mfsync.py sync -m "fix(rw): validate cluster chain" --pr --base main
python tools/mfsync.py sync --no-push
python tools/mfsync.py status --json
При PR-синхронизации ветка стабильна для пары исходная/базовая ветка: повторные запуски обновляют существующий PR, не создавая новый на каждое сохранение. Когда нет коммитов относительно базы, пустой PR не создаётся. Обычный push не переписывает чужую историю; при отказе защиты main используется PR. Если стабильная удалённая ветка разошлась с локальной историей, push останавливается, а не использует force.
Lock размещается в Git directory текущей рабочей копии, поэтому поддерживаются linked worktree. Живая блокировка не снимается только потому, что стала старой. Не запускайте два наблюдателя одной рабочей копии.
Автосинхронизация при сохранении¶
python tools/mfsync.py watch --pr --debounce 5
Наблюдатель ждёт пять секунд без изменений, затем делает sync и обновляет PR. --pr включает отправку; добавлять --push не обязательно. Без --pr и --push наблюдатель создаёт только локальные коммиты. Ctrl+C останавливает наблюдение.
Наблюдатель должен быть запущен на рабочем компьютере. Он не установлен как служба автоматически. Закрытие терминала или выключение компьютера прекращает работу. Для постоянной службы сначала определите ОС, путь клона и безопасный способ авторизации; не используйте временный CI runner или временную сессию для такой службы.
Образы дисков, дампы, виртуальные окружения и build artifacts не входят в обычный снимок watcher. Не храните forensic-материалы в репозитории исходников. Git ignore и резервное копирование данных настраиваются отдельно.
Проверки в GitHub¶
На PR и push работают существующие CI, Quality, Security (including CodeQL), mfsync Verify, Docker и документация. Новый итоговый CI-Gate становится успешным только после тестовой матрицы, integration, бинарных сборок и GUI-проверок. В Quality добавлен actionlint с закреплённой контрольной суммой: неправильный workflow теперь является ошибкой проверки.
mfsync — единый gate для отчёта, сканера секретов, проверки совпадения версий и регрессионных тестов автоматизации. Ежедневный запуск в 03:17 UTC только проверяет репозиторий. Он не создаёт коммит в чистом клоне и не обещает синхронизировать другой компьютер.
В Actions → mfsync → Run workflow доступны verify, commit, pr. Запись разрешена только для явного ручного запроса после успешного Verify. Ввод пользователя передаётся через environment, не вставляется в shell-код. Пишущие maintenance workflow используют общий concurrency group, без отмены операции посреди записи. Коммиты не содержат [skip ci], поэтому проверки PR не подавляются.
Единая релизная версия¶
Согласованы mountfile/__init__.py и [project].version в pyproject.toml. Не редактируйте только один из них.
python scripts/stamp_version.py v1.2.3
python scripts/stamp_version.py v1.2.3 --check
python scripts/release_plan.py --json
python tools/mfsync.py check --strict
stamp_version.py валидирует обе цели до изменений и обновляет только нужные поля. --check ничего не записывает и возвращает ошибку при расхождении с заданным тегом. mfsync check --strict проверяет совпадение исходных файлов; несовпадение с предыдущим релизным тегом может быть нормальным состоянием подготовленного release PR.
Планировщик учитывает стабильные теги-предки текущего HEAD и Conventional Commits: feat → minor, fix/perf → patch, ! или BREAKING CHANGE → major. Другие ветки и prerelease-теги не увеличивают текущую релизную версию. Сам релизный коммит не запускает бесконечный bump.
После успешного CI в main workflow version-bump проверяет, что SHA всё ещё актуален. Если версия требует обновления, создаётся automation/release-<version> PR с обоими файлами. После его merge и успешного CI тегируется именно проверенный, уже версионированный коммит. Затем явно запускаются create-release и release: события от встроенного GITHUB_TOKEN не используются как неявная гарантия запуска следующей стадии. После публикации assets release явно запускает production deployment для этого тега.
Одинаковая версия проставляется перед сборкой Windows, Linux и macOS. У бинарников проверяется наличие файлов SHA-256. Если все попытки загрузки assets неудачны, publish завершается ошибкой, а не ложным успехом. Старые теги и опубликованные релизы не перезаписываются планировщиком.
Автоформатирование и автообъединение¶
autofix запускается вручную, командой /autofix или на push в main, если repository variable ENABLE_AUTOFIX=true. Он использует закреплённые версии isort/black, одинаковую длину строки и совместимый порядок isort → black. Он не применяет UP/F401-преобразования, способные удалить re-export или сломать Python 3.8. Перед публикацией запускаются проверки синтаксиса, секретов и тесты. Результат оформляется как PR, без автоматического approve и без force-push.
Автообъединение требует явной метки auto-merge, доверенного автора и ветки того же репозитория. Оно сверяет head SHA и ждёт CI-Gate, quality-gate, dependency-review и mfsync Verify. Отрицательный результат или отсутствующая проверка оставляет PR открытым. --admin и обход защиты не используются. Major-обновления зависимостей и workflow нужно отдельно просматривать перед добавлением метки.
Dependabot продолжает предлагать обновления зависимостей и Actions согласно .github/dependabot.yml; новый конкурентный бот не добавлен. Проверенные version-sync и formatting PR автоматически получают auto-merge; Dependabot PR с такой меткой тоже может объединиться после обязательных проверок. Все остальные PR требуют явной метки, то есть автообъединение не включено без разбора для пользовательского кода.
После объединения release-version PR workflow сначала ждёт обычный push-CI на новом main и запускает fallback только если GitHub не создал такой run из-за GITHUB_TOKEN; только успешная проверка именно актуального SHA разрешает следующий этап релиза. Это необходимо, потому что события push, созданные GITHUB_TOKEN, не запускают обычные workflow. AI-self-heal остаётся отдельной opt-in возможностью (ENABLE_AI_AUTOMATION=true, OPENAI_API_KEY), ограниченной падениями push в доверенный main.
Разрешения ботов¶
Для основных проверок и релизов достаточно встроенного GITHUB_TOKEN. GitHub может требовать ручного одобрения workflow у PR, созданных этим токеном. Для полностью unattended PR можно настроить отдельный GitHub App или секрет AUTOMATION_TOKEN с минимальными правами. Опубликованный ранее личный токен использовать для этого нельзя.
В Settings → Actions → General должно быть разрешено создание PR workflow. Не ослабляйте ruleset main ради автоматизации. Активный ruleset требует quality-gate и dependency-review; CI-Gate и mfsync Verify остаются обязательными для auto-merge. Изменение файлов workflow может потребовать разрешения Workflows у используемой GitHub App/токена.
Для полностью unattended работы однократно добавьте секрет репозитория AUTOMATION_TOKEN в Settings → Secrets and variables → Actions. Используйте отдельный fine-grained token только для этого репозитория и задайте минимальные Contents: write, Pull requests: write, Actions: write; для правил PR при необходимости также Checks: read. Не используйте PAT, опубликованный в чате. Отзовите его, выпустите новый и добавьте секрет напрямую в Settings — никогда не отправляйте секрет в чат или код. Без AUTOMATION_TOKEN GitHub может задержать проверки PR, созданного GITHUB_TOKEN, до ручного одобрения, а его разрешений может не хватить для автообъединения workflow-файлов; в таком режиме требование полного отсутствия участия человека не гарантируется.
ChatOps¶
В комментарии к PR владелец, участник или collaborator может отправить ровно одну команду:
/release
/autofix
/sync
/release запрашивает patch через общий version-bump и CI gate, а не создаёт непроверенный тег. /autofix запускает форматирование main, /sync запускает read-only проверку. Код самого PR не выполняется привилегированным обработчиком комментария.
Тестирование¶
python -m pytest tests/test_mfsync.py tests/test_release_version.py tests/test_automation_workflows.py -q
python -m pytest tests/ -q
Тесты синхронизации и версионирования используют временные локальные Git-репозитории и mock API: сеть и личные токены не требуются. Actionlint отдельно проверяет реальный синтаксис всех GitHub Actions workflow.