Как вносить изменения¶
Основной репозиторий — на GitLab. Merge-request’ы отправляются туда, не в апстрим SatNOGS и не на GitHub.
Полный текст руководства по вкладу, унаследованный от Libre Space Foundation (включая
Developer’s Certificate of Origin и требование подписывать коммиты), — в CONTRIBUTING.md
в корне репозитория.
Рабочий цикл¶
Ветка от актуальной основной ветки.
Изменения атомарными коммитами: одно логическое изменение — один коммит.
Локально прогнать проверки:
tox -e ruff tox -e deps,pytest tox -e docs npm run lint npm test
Merge request с описанием мотивации, а не только содержания диффа.
Отработать замечания ревью.
Хуки до коммита¶
Необязательно, но экономит круг по CI: те же проверки, но только по файлам в индексе.
pip install pre-commit
pre-commit install
Набор описан в .pre-commit-config.yaml: ruff check --fix, ruff format, eslint
и stylelint. Версия ruff в хуке совпадает с версией в tox.ini — разъехавшиеся
версии форматтера и дают «у меня проходило»: хук переформатирует файл по-своему, CI
просит обратно. CI от хуков не зависит и гоняет тот же набор целиком.
Стиль кода¶
Правила фиксируются ruff.toml и проверяются tox -e ruff:
Правило |
Значение |
|---|---|
Длина строки |
88 |
Отступ |
4 пробела |
Кавычки |
двойные |
Импорты |
сортировка |
Docstring’и |
стиль Google |
Форматирование применяется командой tox -e ruff-format.
Обязательные соглашения¶
Миграции. Существующие файлы в network/*/migrations/ не редактируются. Изменения
схемы — только новыми миграциями через makemigrations.
Бэкфиллы. RunPython, который проходит по Observation, пишется батчами: таблица
на проде — миллионы строк, а web не отвечает, пока идут миграции.
def fill(apps, schema_editor):
Observation = apps.get_model("base", "Observation")
batch = []
for observation in Observation.objects.filter(field__isnull=True).iterator(
chunk_size=5000
):
observation.field = compute(observation)
batch.append(observation)
if len(batch) >= 5000:
Observation.objects.bulk_update(batch, ["field"])
batch.clear()
if batch:
Observation.objects.bulk_update(batch, ["field"])
Образец того, как не надо, — 0048_observation_snapshot: два безусловных UPDATE по
всей таблице. Она уже выпущена, редактировать её нельзя (см. выше), и в CHANGELOG к
1.10.0 из-за неё стоит отдельное предупреждение «заложить время на миграции».
Squash миграций base не делаем: стенды и станции обновляются вразнобой, а squash
ломает любую базу, которая остановилась на миграции внутри схлопнутого отрезка.
Секреты. Ничего не хардкодится. Только config("VAR_NAME", default="") через
python-decouple, значение попадает в .env, а новая переменная — в env-dist
и в Конфигурация.
Решённые вопросы. Прежде чем предлагать очевидное улучшение, загляните в Принятые решения: там записано, что уже пробовали и почему отказались.
Размещение кода. HTML-представления — в network/base/views/<домен>.py,
эндпоинты API — в network/api/views.py классами DRF. См. Архитектура.
Локализация. Весь текст, видимый пользователю, — через gettext_lazy.
Комментарии и docstring’и — на английском.
Сгенерированные файлы. Руками не правятся:
requirements.txt,requirements-dev.txt,constraints.txt— генерируются./contrib/refresh-requirements.shизsetup.cfg;soniks-network-api-client/— генерируется openapi-generator в CI;network/_version.py— versioneer.
Декодеры телеметрии¶
Декодеры (.ksy Kaitai Struct) живут в отдельном репозитории
soniks-decoders,
подключённом как submodule soniks-decoders/; пакет satnogs-decoders с PyPI
больше не используется. Сгенерированный Python в репозитории не хранится:
в образе .ksy компилируются стадией decoders Dockerfile, для разработки
без Docker — cd soniks-decoders && ./contrib/docker-ksc.sh.
Новый декодер: MR в soniks-decoders (ветка soniks), затем в этом репозитории
передвинуть пин и закоммитить:
git submodule update --remote soniks-decoders
git add soniks-decoders
Документация¶
Документация живёт в docs/, пишется на русском в MyST-Markdown, собирается с -W
(любое предупреждение Sphinx — ошибка сборки).
tox -e docs
# или
pip install -r docs/requirements.txt && make -C docs html
Новая страница обязана попасть в какой-нибудь toctree в docs/index.md — иначе
сборка упадёт. Ссылки между страницами — относительные, синтаксисом MyST:
[](../tle.md) подставит заголовок целевой страницы.
Зависимости сборки — только в docs/requirements.txt, в setup.cfg они не входят.
Изменение поведения без изменения документации — незаконченное изменение. Особенно это касается новых настроек, задач Celery, management-команд и эндпоинтов API: для них есть готовые места в Конфигурация, Задачи Celery, Management-команды и Обзор эндпоинтов.