revise November 2019 build articles
Build and deploy / deploy (push) Successful in 15s

This commit is contained in:
2026-07-31 11:07:56 +03:00
parent 3e06278fc2
commit 8e2ea8dee8
7 changed files with 701 additions and 1 deletions
@@ -0,0 +1,46 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1240" role="img" aria-labelledby="title desc">
<title id="title">Диагностика различающихся чистых сборок</title>
<desc id="desc">Вертикальная схема начинает с двух чистых запусков, сравнивает их входы, затем разветвляется к регистрации различия либо к сравнению output manifest и первому отличающемуся файлу.</desc>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
<path d="M0 0L10 5L0 10z" fill="#60758d"/>
</marker>
<marker id="bad-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
<path d="M0 0L10 5L0 10z" fill="#c54646"/>
</marker>
</defs>
<rect width="720" height="1240" fill="#f8fafc"/>
<rect x="42" y="34" width="636" height="112" rx="18" fill="#17324d"/>
<text x="360" y="80" text-anchor="middle" fill="#ffffff" font-family="Arial, sans-serif" font-size="28" font-weight="700">Две чистые сборки: входы, затем bundle</text>
<text x="360" y="116" text-anchor="middle" fill="#d8e7f3" font-family="Arial, sans-serif" font-size="21">Сначала доказываем условия сравнения.</text>
<rect x="74" y="190" width="572" height="122" rx="18" fill="#e9f3ff" stroke="#3182ce" stroke-width="3"/>
<text x="360" y="234" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">Прогон A</text>
<text x="360" y="272" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">npm ci → build → first manifest</text>
<path d="M360 312v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="356" width="572" height="122" rx="18" fill="#e9f3ff" stroke="#3182ce" stroke-width="3"/>
<text x="360" y="400" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">Прогон B</text>
<text x="360" y="438" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">npm ci → build → second manifest</text>
<path d="M360 478v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="522" width="572" height="148" rx="18" fill="#f3ecff" stroke="#805ad5" stroke-width="3"/>
<text x="360" y="566" text-anchor="middle" fill="#2d2360" font-family="Arial, sans-serif" font-size="27" font-weight="700">Сравнить входы</text>
<text x="360" y="604" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="21">commit, lockfile hash, Node, npm и команда</text>
<text x="360" y="634" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="20">любая разница останавливает сравнение output</text>
<path d="M360 670v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="714" width="572" height="200" rx="18" fill="#ffffff" stroke="#805ad5" stroke-width="3"/>
<text x="360" y="758" text-anchor="middle" fill="#2d2360" font-family="Arial, sans-serif" font-size="27" font-weight="700">Входы совпали?</text>
<rect x="102" y="786" width="516" height="48" rx="12" fill="#fff0f0" stroke="#c54646" stroke-width="2"/>
<text x="360" y="818" text-anchor="middle" fill="#a12f2f" font-family="Arial, sans-serif" font-size="20" font-weight="700">Нет → записать различие и повторить условия</text>
<rect x="102" y="850" width="516" height="48" rx="12" fill="#e8fff3" stroke="#279665" stroke-width="2"/>
<text x="360" y="882" text-anchor="middle" fill="#145a3c" font-family="Arial, sans-serif" font-size="20" font-weight="700">Да → сравнить полный output manifest</text>
<path d="M360 914v36" stroke="#c54646" stroke-width="5" stroke-dasharray="12 10" marker-end="url(#bad-arrow)"/>
<rect x="74" y="958" width="572" height="118" rx="18" fill="#fff7ed" stroke="#dd6b20" stroke-width="3"/>
<text x="360" y="994" text-anchor="middle" fill="#7c2d12" font-family="Arial, sans-serif" font-size="21" font-weight="700">Если manifest различается:</text>
<text x="360" y="1030" text-anchor="middle" fill="#7c2d12" font-family="Arial, sans-serif" font-size="26" font-weight="700">первый differing file</text>
<text x="360" y="1060" text-anchor="middle" fill="#9a4c16" font-family="Arial, sans-serif" font-size="20">его bytes ведут к конкретному входу</text>
<text x="360" y="1142" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">Не начинать с cache: сначала наблюдение.</text>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@@ -0,0 +1,45 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1160" role="img" aria-labelledby="title desc">
<title id="title">Граница lockfile и остальных входов сборки</title>
<desc id="desc">Вертикальная схема показывает, что commit и lockfile фиксируются в репозитории, а runtime и config нужно назвать отдельно до вычисления manifest и диагностики расхождения.</desc>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
<path d="M0 0L10 5L0 10z" fill="#60758d"/>
</marker>
<marker id="bad-arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
<path d="M0 0L10 5L0 10z" fill="#c54646"/>
</marker>
</defs>
<rect width="720" height="1160" fill="#f8fafc"/>
<rect x="42" y="34" width="636" height="112" rx="18" fill="#17324d"/>
<text x="360" y="80" text-anchor="middle" fill="#ffffff" font-family="Arial, sans-serif" font-size="28" font-weight="700">Lockfile не закрывает все входы</text>
<text x="360" y="116" text-anchor="middle" fill="#d8e7f3" font-family="Arial, sans-serif" font-size="21">Фиксируем репозиторий и называем внешнюю среду.</text>
<rect x="74" y="190" width="572" height="126" rx="18" fill="#e8fff3" stroke="#279665" stroke-width="3"/>
<text x="360" y="234" text-anchor="middle" fill="#145a3c" font-family="Arial, sans-serif" font-size="27" font-weight="700">Зафиксировано в репозитории</text>
<text x="360" y="272" text-anchor="middle" fill="#24684b" font-family="Arial, sans-serif" font-size="21">commit и package-lock</text>
<text x="360" y="300" text-anchor="middle" fill="#24684b" font-family="Arial, sans-serif" font-size="20">исходники и разрешённое дерево пакетов</text>
<path d="M360 316v38" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="362" width="572" height="140" rx="18" fill="#fff7ed" stroke="#dd6b20" stroke-width="3"/>
<text x="360" y="406" text-anchor="middle" fill="#7c2d12" font-family="Arial, sans-serif" font-size="27" font-weight="700">Нужно назвать отдельно</text>
<text x="360" y="444" text-anchor="middle" fill="#9a4c16" font-family="Arial, sans-serif" font-size="21">runtime, config, env и время</text>
<text x="360" y="474" text-anchor="middle" fill="#9a4c16" font-family="Arial, sans-serif" font-size="20">иначе одинаковый lockfile ничего не доказывает</text>
<path d="M360 502v38" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="548" width="572" height="126" rx="18" fill="#f3ecff" stroke="#805ad5" stroke-width="3"/>
<text x="360" y="592" text-anchor="middle" fill="#2d2360" font-family="Arial, sans-serif" font-size="27" font-weight="700">build(inputs)</text>
<text x="360" y="630" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="21">webpack и plugins читают только названные входы</text>
<text x="360" y="658" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="20">неназванный вход остаётся риском</text>
<path d="M360 674v38" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="720" width="572" height="118" rx="18" fill="#e9f3ff" stroke="#3182ce" stroke-width="3"/>
<text x="360" y="764" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">manifest SHA-256</text>
<text x="360" y="802" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">сортируем путь и digest каждого файла</text>
<path d="M360 838v38" stroke="#c54646" stroke-width="5" stroke-dasharray="12 10" marker-end="url(#bad-arrow)"/>
<rect x="74" y="884" width="572" height="132" rx="18" fill="#fff0f0" stroke="#c54646" stroke-width="3"/>
<text x="360" y="930" text-anchor="middle" fill="#a12f2f" font-family="Arial, sans-serif" font-size="27" font-weight="700">Manifest различается?</text>
<text x="360" y="968" text-anchor="middle" fill="#a12f2f" font-family="Arial, sans-serif" font-size="21">сначала открыть первый differing file</text>
<text x="360" y="996" text-anchor="middle" fill="#a12f2f" font-family="Arial, sans-serif" font-size="20">не начинать расследование с очистки cache</text>
<text x="360" y="1102" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">Хеш фиксирует факт, причина живёт во входах.</text>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@@ -0,0 +1,45 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1280" role="img" aria-labelledby="title desc">
<title id="title">Контракт входов воспроизводимой сборки</title>
<desc id="desc">Вертикальная схема ведёт от зафиксированных исходников, зависимостей и среды к чистой установке, сборке и сортированному manifest с хешами файлов.</desc>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
<path d="M0 0L10 5L0 10z" fill="#60758d"/>
</marker>
</defs>
<rect width="720" height="1280" fill="#f8fafc"/>
<rect x="42" y="34" width="636" height="112" rx="18" fill="#17324d"/>
<text x="360" y="80" text-anchor="middle" fill="#ffffff" font-family="Arial, sans-serif" font-size="28" font-weight="700">Сначала входы, затем output</text>
<text x="360" y="116" text-anchor="middle" fill="#d8e7f3" font-family="Arial, sans-serif" font-size="21">Одинаковая команда не отменяет контракт среды.</text>
<rect x="74" y="190" width="572" height="118" rx="18" fill="#e9f3ff" stroke="#3182ce" stroke-width="3"/>
<text x="360" y="234" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">1. Исходный код</text>
<text x="360" y="272" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">git commit задаёт точное дерево файлов</text>
<path d="M360 308v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="352" width="572" height="118" rx="18" fill="#edf7ff" stroke="#3182ce" stroke-width="3"/>
<text x="360" y="396" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">2. Зависимости</text>
<text x="360" y="434" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">package-lock плюс чистый npm ci</text>
<path d="M360 470v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="514" width="572" height="140" rx="18" fill="#fff7ed" stroke="#dd6b20" stroke-width="3"/>
<text x="360" y="558" text-anchor="middle" fill="#17324d" font-family="Arial, sans-serif" font-size="27" font-weight="700">3. Среда и команда</text>
<text x="360" y="596" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">Node, npm, mode и build-флаги записаны явно</text>
<text x="360" y="626" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="20">время и случайность — отдельные входы</text>
<path d="M360 654v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="698" width="572" height="126" rx="18" fill="#f3ecff" stroke="#805ad5" stroke-width="3"/>
<text x="360" y="742" text-anchor="middle" fill="#2d2360" font-family="Arial, sans-serif" font-size="27" font-weight="700">Чистая установка</text>
<text x="360" y="780" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="21">не переписывает manifest и lockfile</text>
<text x="360" y="808" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="20">перед запуском build</text>
<path d="M360 824v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="74" y="868" width="572" height="118" rx="18" fill="#f3ecff" stroke="#805ad5" stroke-width="3"/>
<text x="360" y="912" text-anchor="middle" fill="#2d2360" font-family="Arial, sans-serif" font-size="27" font-weight="700">Сборка</text>
<text x="360" y="950" text-anchor="middle" fill="#4d3b78" font-family="Arial, sans-serif" font-size="21">производит deployable files</text>
<path d="M360 986v36" stroke="#60758d" stroke-width="5" marker-end="url(#arrow)"/>
<rect x="58" y="1030" width="604" height="128" rx="18" fill="#e8fff3" stroke="#279665" stroke-width="3"/>
<text x="360" y="1076" text-anchor="middle" fill="#145a3c" font-family="Arial, sans-serif" font-size="25" font-weight="700">Сортированный manifest SHA-256</text>
<text x="360" y="1114" text-anchor="middle" fill="#24684b" font-family="Arial, sans-serif" font-size="21">полный путь и хеш каждого deployable file</text>
<text x="360" y="1220" text-anchor="middle" fill="#425d73" font-family="Arial, sans-serif" font-size="21">Сравниваем весь список, а не один bundle.</text>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB