Совместимость
Какие версии PostgreSQL и Go и что здесь означает стабильность.
PostgreSQL#
14, 15, 16, 17 и 18.
Не «должно работать». Набор тестов совместимости отказывается запускаться, если доступны не все пять сразу:
the compatibility matrix requires every supported major and
[ORM_TEST_DSN_PG14 ... PG18] are unset. Skipping here would report a five-major
claim proven by however many servers happened to be runningЗаявленной, но ни разу не проверенной версии верить нельзя.
14 покинет список, когда разработчики PostgreSQL прекратят её поддержку 12 ноября 2026 года.
Что доказано на всех пяти#
- Весь пользовательский сценарий: миграция, генерация, проверка, запись, чтение, джойн, обновление матпредставления.
- Побайтово одинаковые артефакты. Сгенерированный Go,
orm.lockи артефакты миграций одинаковы на 14 и на 18. Команда с разными серверами не получает диф при чекауте. - Ничего серверно-локального ни в одном артефакте: ни OID, ни имени базы, ни версии сервера, ни разобранного определения, ни абсолютных путей.
Go#
Минимальная версия — та, что в go.mod, сейчас 1.24, и её повышение — решение, а не побочный эффект появления нового тулчейна. Отдельная задача в CI фиксирует GOTOOLCHAIN=local и собирает только те модули, которые на этой планке, — то есть утверждение доказывается, а не предполагается.
Некоторые периферийные модули заявляют версию выше, потому что этого требуют их собственные зависимости: помощник для Testcontainers и часть примеров хотят 1.25. Планку библиотеки это не двигает, и задачи разделены так, чтобы не могло.
PostGIS#
Доказано на тех сочетаниях, которые проект действительно заявляет: PostgreSQL 17 с PostGIS 3.5, 16 с 3.4 и 14 с 3.4. Пространственный набор пропускается, когда расширения нет, — правильно на машине разработчика, неправильно в CI, — поэтому CI ставит ORM_REQUIRE_POSTGIS=1, что превращает пропуск в падение.
Стабильность#
Публичный API заморожен на v1 и отслеживается сгенерированным манифестом. Удалённый символ, изменённая сигнатура, ужесточённое ограничение и метод, добавленный в интерфейс, который реализуют потребители, — всё это роняет сборку. Сам инструмент манифеста протестирован на то, что замечает каждое из этого.
Расширения#
citext, hstore, pg_trgm, uuid-ossp и PostGIS распознаются, когда установлены. Ни одно не обязательно, и библиотека никогда не создаёт расширение — это привилегированная операция того, кто владеет базой.
Разобранные примеры#
Матрица CI, которая не может тихо сократиться#
strategy:
fail-fast: false
matrix:
postgres: ['14', '15', '16', '17', '18']И тест, который отказывается запускаться на меньшем числе, вместо того чтобы объявить поддержку пяти версий, доказанную тем, сколько серверов оказалось поднято:
func requireEveryMajor(t *testing.T) map[string]string {
var missing []string
for _, v := range []string{"14", "15", "16", "17", "18"} {
if os.Getenv("PG_DSN_"+v) == "" {
missing = append(missing, v)
}
}
if len(missing) > 0 {
t.Fatalf("missing servers for %v; skipping here would report a claim "+
"nobody proved", missing)
}
return nil
}Зафиксировать минимальную версию Go и доказать её#
- name: the library builds on its declared floor
env:
GOTOOLCHAIN: local # не тянуть молча более новый Go
run: go build ./...Без GOTOOLCHAIN=local более новый тулчейн скачивается по требованию, и планка
не проверяется никогда.
Сделать необязательное расширение обязательным в CI#
- env:
ORM_REQUIRE_POSTGIS: '1'
run: go test ./postgis/...Пространственный набор пропускается, когда PostGIS нет: на ноутбуке это верно, в CI — нет. Переменная превращает пропуск в падение.