Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 1081|Ответ: 1

Краткое введение в воспроизводимую сборку

[Скопировать ссылку]
Опубликовано 2025-4-30 10:09:27 | | | |
Что такое повторяемая сборка?

Детерминированный билд или воспроизводимый билд немного различаются, но из этой статьи их можно понять как одно и то же.

Воспроизводимые сборки относятся кМногократные запуски процесса сборки с одинаковыми входами и средой сборки могут дать абсолютно одинаковый результат。 Эта технология важна для разработки, распространения и проверки безопасности.

Сборка воспроизводима, если она даёт одинаковый результат вне зависимости от времени и места. Неважно, на каком компьютере вы работаете, в какое время суток и к какому внешнему сервису пользуетесь по сети, воспроизводимые сборки дают одинаковый результат по байту. Это отлично подходит как для разработки (потому что воспроизводимые сборки легко делиться между разными устройствами разработчиков), так и для продакшена (потому что легко убедиться, что результаты воспроизводимых сборок не были изменены — просто запустите сборку на своей машине и убедитесь, что результаты согласованы!). очень полезны.



Три столпа повторяемых билдов

Столп 1: Повторяемые билды

Повторяемость билда относится к тому, что происходит с самой машиной сборки. Если наши входные данные для сборки доступны и мир вокруг нас ничего не меняется, даёт ли наш билд одинаковый результат при повторении?

Детерминированный план установки

Первое, самое простое и очевидное требование в повторяемой сборке — это детерминированный план установки зависимостей.

В большинстве языков всё просто: проверить заблокированный файл. Современные инструменты сборки часто позволяют проектам выражать прямые требования к зависимости в виде ограничений, а затем разрешать эти ограничения для генерации плана установки (списка имён зависимостей и пар версий для установки). Многие из этих инструментов также генерируют файлы блокировки для сериализированных планов установки. Разработчики могут передавать эти файлы блокировки в систему контроля версий, чтобы будущие сборки использовали те же имена и версии зависимостей.

Обратите внимание, что нам также нужна детерминированность в самой сборке зависимости (не только при выборе версии), а детерминированный план установки не позволяет нам этого добиться!

Детерминированное построение

Как только мы знаем, что строить, наша сборка (включая наш собственный код и билд кода зависимостей) должна быть действительно детерминированной.

Для проектов без этапа компиляции это может не быть проблемой! Например, проект Node со всеми зависимостями — это чистый JavaScript, и для достижения эффективной детерминированности не требуется дополнительная работа.

Для проектов, которые включают этапы компиляции или перевода (компиляция от источника к источнику), обеспечение детерминизма — самая сложная часть построения воспроизводимой сборки. Процесс компиляции может неявно вводить недетерминизм различными способами, включая:

  • Скрипты сборки программ с полным уровнем Тьюринга могут изменять скомпилированный результат по своему желанию.
  • Скрипты после установки, основанные на исполняемых файловых системах или сетевых вызовах.
  • C-привязка к установленному системой пакету, где связки на разных системах с разными заголовками могут давать разные выходы.
  • Шаги для создания файла, который читается вне контроля версий.
  • Постройте шаги для генерации временных меток с использованием системного времени.
  • Шаги по созданию зависимостей, которые не выражены в плане установки сетевой загрузки (например, скачать зависимость NPM с GitHub для кэшированной бинарной сборки, связанной с C).
  • Изменяйте поведение в зависимости от текущей переменной среды, но не отправляйте сборку с конфигурацией переменной среды.


Не все эти модели поведения обязательно создают неопределённость при правильной установке, но правильная настройка процесса сборки может быть сложной и сложной. Например, вы можете прочитать этот блог о неопределённости в сборках Chromium. Многие из этих проблем можно смягчить, контролируя местную строительную среду, о которой мы расскажем в следующем разделе.

Столп 2: Неизменная среда

Даже с повторяемыми билдами нужно убедиться, что входные данные не меняются. Часто это означает, что мы хотим строить на неизменном снимке окружающей среды.

Неизменная локальная среда

Как мы обсуждали выше, распространённым источником неопределённости билда является опора на «зависимости», которые не учитываются инструментом сборки. Наиболее распространёнными примерами являются системные библиотеки с ограничением C, но другие локальные факторы окружающей среды, такие как настройки переменных среды и файлы, не входящие в сферу контроля версий, также могут влиять на сборку.

Простой способ решить эту проблему — запустить сборку в известном, неизменяемом контейнере. Например, контейнерное время выполнения, такое как Docker, помогает обеспечить использование одних и тех же системных зависимостей, одинаковых переменных среды и работы на одной и той же файловой системе. Кроме того, легко проверить, совпадает ли содержимое контейнера с известным хорошим контейнером сборки, и при необходимости контейнер можно легко полностью удалить из известного хорошего изображения и воссоздать заново.

Обратите внимание, что мы очень чётко понимаем известные контейнеры или известные изображения контейнеров. Недостаточно просто отправить файл в Docker! Почему? Потому что сам Dockerfile не описывает полностью воспроизводимый процесс сборки для образов Docker, потому что они не работают в неизменяемой глобальной среде.

Неизменная глобальная среда

Системы сборки часто взаимодействуют с внешними сервисами для выполнения задач, таких как разрешение версий и загрузка зависимостей. Но внешние сервисы меняются часто.

Запуск apt install nodejs сегодня даст вам другие результаты, чем в прошлом году, и, вероятно, в следующем году тоже будут другие. Вот почему сами Dockerfiles не могут описать воспроизводимые сборки — если запускать один и тот же Dockerfile в разное время, это даст разные выходы сборок!

Простое решение здесь — настраивать сборку по возможности с указанием точной версии (желательно точный хэш контента), чтобы будущие сборки использовали ту же версию, что и текущая. Но внешние сервисы также могут неожиданно изменить своё поведение — по-настоящему пессимистично воспроизводимая сборка запускает внутренний образ с максимально большим количеством сетевых ресурсов.

Столп 3: Доступность ресурсов

Допустим, наша сборка повторяется, и мир под ногами не меняется. Теперь нам нужен только доступ к входу сборки. Это кажется простым, правда? Колодец......

Реестр иногда выходит из строя

Большинство разработчиков Node сталкивались хотя бы с одним сбоем NPM, во время которого нарушается конвейер сборки без кэширования или зеркалирования NPM-пакетов. Многие разработчики Node также столкнулись с удалением левой панели и фейкеров, что серьёзно повредило экосистему NPM и фактически привело к сбою.

Единственный надёжный способ минимизировать такие срывы — запустить собственное зеркало реестра пакетов. Когда внешние сервисы недоступны, изображение может оставаться онлайн; Когда официальный реестр удаляет старый пакет, зеркало может продолжать предоставлять услуги. Тот же принцип применим и к другим удалёным сервисам: если вы не запускаете собственный образ, доступность build pipeline сопоставима только с доступностью его сервисов.

Выбор запуска имиджа сервиса всегда является деликатным компромиссом. С одной стороны, такие реестры, как NPM, имеют специализированные инженерные и операционные команды, обладающие экспертизой для поддержания этих систем в онлайн. С другой стороны, гораздо проще запустить небольшой образ для небольшого набора зависимостей, чем все NPM-образы. Вы должны принимать зеркальные решения, исходя из специфики каждого сервиса, учитывая надёжность исторических внешних сервисов, а также доступность и потребности вашей команды в персонале.

Поставщики обеспечивают максимальную доступность

Простой способ обеспечить максимальную доступность зависимостей вашего проекта — добавить их вашему поставщику. Большинство менеджеров пакетов поддерживают некоторую форму «вендоринг», то есть вместо загрузок с внешних сервисов мы храним исходный код зависимостей в контроле версий, сосуществующий с нашим исходным кодом. Например, в Node это может выглядеть как комитинг node_modules в контроль версий.

Хотя это решение не идеальное (в зависимости от того, как настроен ваш поставщик и проект, что может сильно нагрузить ваш контроль версий), часто это самое простое и простое решение для максимальной доступности.

Ссылка:

Вход по гиперссылке виден.
Вход по гиперссылке виден.




Предыдущий:.NET/C# Используйте UnsafeAccessor для изменения содержимого полей только для чтения
Следующий:Angular Series 18 (32) ControlValueAccessor Управление пользовательскими формами
 Хозяин| Опубликовано 2025-4-30 10:10:23 |
О том, как использовать повторяемые сборки при создании пакетов NuGet на C#:

Вход по гиперссылке виден.
Вход по гиперссылке виден.
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com