MBL
Go / Проекты / Open-Source-PR / helm/helm #32485 — воспроизводимые чарты
Go сложный

helm/helm #32485 — воспроизводимые чарты

projectsopensourcehelm

Диаграмма: от бага до PR (archify) →

Смердженный PR: helm/helm #32485 — "fix(chart): normalize StampModTimes timestamp to UTC/truncate + Chart.lock reproducibility test". Мержен 20 августа 2026, +86/-10, четыре файла (тесты, тестовые фикстуры и pkg/chart/v2/chart.go). Closes #32396.

Проблема

Chart.StampModTimes (добавлен ранее, в #32162) проставляет одно и то же epoch-значение как временную метку модификации во все файлы чарта — идея в том, чтобы сборка была воспроизводимой: одинаковый вход даёт байт-в-байт одинаковый архив чарта. Но само epoch-значение приходило как обычный time.Time, без нормализации.

Почему воспроизводимость ломалась именно так

time.Time в Go хранит не только момент времени, но и часовой пояс (Location). Одно и то же мгновение, представленное как time.Time с локальной таймзоной (например, +03:00), при сериализации в поле generated: даёт РАЗНУЮ строку на разных машинах — хотя оба раза передавалось одно и то же epoch-значение. Это классическая ловушка воспроизводимых сборок: не значение отличается, а его текстовое представление.

Фикс — два отдельных вызова, каждый решает свою задачу

t = t.UTC().Truncate(time.Second)
  • .UTC() — собственно фикс воспроизводимости: убирает зависимость представления от локали машины, на которой идёт сборка.
  • .Truncate(time.Second) — отдельная, независимая причина: спецификация SOURCE_DATE_EPOCH определяет момент сборки в целых секундах — если time.Time внутри хранит ещё и наносекунды из системных часов, два прогона в одну и ту же секунду всё равно дадут разные метки без явного усечения.

PR также добавляет тест на воспроизводимость Chart.lock — не просто проверяет, что фикс "работает на глаз", а фиксирует инвариант тестом, который упадёт при регрессии.

Почему это ценно на собесе

Здесь ценность не в объёме кода (диф крошечный), а в точности диагностики: два похожих на первый взгляд источника недетерминированности (таймзона и точность до наносекунд) требуют двух РАЗНЫХ независимых исправлений, и PR явно проговаривает разницу, а не сваливает оба факта в одну общую фразу "нормализовали время". Это ровно тот навык — различать похожие, но разные причины одного и того же наблюдаемого симптома — который и проверяет код-ревью на собесе.

Самопроверка 0 / 2
Понимаю, зачем в фиксе нужны ОБА вызова — и .UTC(), и .Truncate(time.Second) — а не один из них
Знаю, что такое SOURCE_DATE_EPOCH и почему воспроизводимая сборка требует детерминированных временных меток
Как усвоено?