chore(deps): три места, где сборка не воспроизводится — лок-призрак, глоб и неприпинованный сайдкар #3213

Merged
bot-backend merged 1 commit from chore/deps-hygiene-dockerfiles into main 2026-08-29 11:20:58 +00:00
Collaborator

Ничего не апгрейдит. Убирает три способа собрать образ не тем, что лежит в репозитории.

1. tradein-mvp/backend/uv.lock — удалён

Файл был untracked и в .gitignore с рождения. Мера — uv-workspace: сборка берёт корневой tradein-mvp/uv.lock (context: ./tradein-mvp, COPY pyproject.toml uv.lock ./ + uv sync --frozen). Лок, созданный uv lock из backend/, не читает никто — и он тихо разошёлся с рабочим. На 2026-08-29 в нём:

pillow 12.2.0 · starlette 1.0.1 · python-multipart 0.0.29 · pydantic-settings 2.14.1 · weasyprint 68.1

Пять пакетов с открытыми advisory, которых в реальной сборке Меры нет вообще. Именно этот файл подмешал пять фантомных строк в OSV-скан текущей серии — я на них сам чуть не начал чинить то, чего нет.

Строка в .gitignore остаётся (второй лок не нужен), но теперь с объяснением почему — иначе следующий читатель снимет ignore и закоммитит призрак.

2. backend/Dockerfile — глоб и молчаливый фолбэк

COPY pyproject.toml uv.lock* ./
RUN ... if [ -f uv.lock ]; then uv sync --frozen --no-dev; else uv sync --no-dev; fi

Глоб плюс фолбэк означали: лок пропал — сборка не падает, а молча переключается на резолв «свежайшее из диапазонов pyproject». Образ собрался бы с версиями, которых никто не видел ни в одном PR, и воспроизвести прод-сборку было бы нечем. Теперь uv.lock обязателен: его пропажа роняет COPY, то есть даёт красный билд вместо незаметной подмены зависимостей.

Контекст сборки ./backend (deploy.yml:220,243,342,361), backend/uv.lock — tracked. Проверено.

3. tradein-mvp/browser/Dockerfile — сайдкар без единого пина

RUN pip install --no-cache-dir "camoufox[geoip]" aiohttp

У браузерного сайдкара нет лока вообще, так что любая пересборка образа — в том числе автоматическая, на несвязанном коммите — тянула свежайший camoufox, а вместе с ним другой playwright. Под который не написан sed-патч coreBundle.js в том же файле (#915/#918, null-guard для pageError.location); при несовпадении паттерна сборка падает по построению.

Запинено по факту работающего прод-контейнера tradein-browser: camoufox==0.5.5, playwright==1.60.0, aiohttp==3.14.3. playwright — явно, хотя и приходит транзитивно (camoufox 0.5.5 требует playwright<1.61): патч завязан на конкретную сборку драйвера, диапазон тут не годится. Наличие всех трёх версий на PyPI и совместимость camoufox 0.5.5 → playwright<1.61 проверены.

Заодно: комментарий, который врал в обе половины

«Апгрейд playwright невозможен — camoufox 0.4.11 pinned под Firefox+juggler»

camoufox не был запинен ни на что (см. строку pip install выше), а 0.4.11 в проде не стоит неизвестно с каких пор — контейнер сейчас несёт 0.5.5 и playwright 1.60.0. Переписано на то, как есть: апгрейд не заблокирован, но связан — playwright поднимается только вместе с camoufox и только с проверкой, что паттерны sed ещё на месте.

Риск

Пункты 1 и 2 не меняют результат сборки (лок как был корневой, так и остался; uv.lock как был на месте, так и остался). Пункт 3 пересоберёт образ сайдкара — ставя ровно то, что в нём уже работает.

Пункт 4 из 6 в цепочке апдейта зависимостей (после #3207, #3210, #3211).

Ничего не апгрейдит. Убирает три способа собрать образ не тем, что лежит в репозитории. ## 1. `tradein-mvp/backend/uv.lock` — удалён Файл был **untracked** и в `.gitignore` с рождения. Мера — uv-workspace: сборка берёт **корневой** `tradein-mvp/uv.lock` (`context: ./tradein-mvp`, `COPY pyproject.toml uv.lock ./` + `uv sync --frozen`). Лок, созданный `uv lock` из `backend/`, не читает никто — и он тихо разошёлся с рабочим. На 2026-08-29 в нём: `pillow` 12.2.0 · `starlette` 1.0.1 · `python-multipart` 0.0.29 · `pydantic-settings` 2.14.1 · `weasyprint` 68.1 Пять пакетов с открытыми advisory, которых в реальной сборке Меры нет вообще. Именно этот файл подмешал пять фантомных строк в OSV-скан текущей серии — я на них сам чуть не начал чинить то, чего нет. Строка в `.gitignore` остаётся (второй лок не нужен), но теперь с объяснением почему — иначе следующий читатель снимет ignore и закоммитит призрак. ## 2. `backend/Dockerfile` — глоб и молчаливый фолбэк ```dockerfile COPY pyproject.toml uv.lock* ./ RUN ... if [ -f uv.lock ]; then uv sync --frozen --no-dev; else uv sync --no-dev; fi ``` Глоб плюс фолбэк означали: лок пропал — сборка **не падает**, а молча переключается на резолв «свежайшее из диапазонов `pyproject`». Образ собрался бы с версиями, которых никто не видел ни в одном PR, и воспроизвести прод-сборку было бы нечем. Теперь `uv.lock` обязателен: его пропажа роняет `COPY`, то есть даёт красный билд вместо незаметной подмены зависимостей. Контекст сборки `./backend` (`deploy.yml:220,243,342,361`), `backend/uv.lock` — tracked. Проверено. ## 3. `tradein-mvp/browser/Dockerfile` — сайдкар без единого пина ```dockerfile RUN pip install --no-cache-dir "camoufox[geoip]" aiohttp ``` У браузерного сайдкара **нет лока вообще**, так что любая пересборка образа — в том числе автоматическая, на несвязанном коммите — тянула свежайший `camoufox`, а вместе с ним другой `playwright`. Под который **не написан** `sed`-патч `coreBundle.js` в том же файле (#915/#918, null-guard для `pageError.location`); при несовпадении паттерна сборка падает по построению. Запинено по факту работающего прод-контейнера `tradein-browser`: `camoufox==0.5.5`, `playwright==1.60.0`, `aiohttp==3.14.3`. `playwright` — явно, хотя и приходит транзитивно (`camoufox` 0.5.5 требует `playwright<1.61`): патч завязан на конкретную сборку драйвера, диапазон тут не годится. Наличие всех трёх версий на PyPI и совместимость `camoufox 0.5.5 → playwright<1.61` проверены. ### Заодно: комментарий, который врал в обе половины > «Апгрейд playwright невозможен — camoufox 0.4.11 pinned под Firefox+juggler» `camoufox` не был запинен ни на что (см. строку `pip install` выше), а 0.4.11 в проде не стоит неизвестно с каких пор — контейнер сейчас несёт **0.5.5** и **playwright 1.60.0**. Переписано на то, как есть: апгрейд не заблокирован, но связан — `playwright` поднимается только вместе с `camoufox` и только с проверкой, что паттерны `sed` ещё на месте. ## Риск Пункты 1 и 2 не меняют результат сборки (лок как был корневой, так и остался; `uv.lock` как был на месте, так и остался). Пункт 3 пересоберёт образ сайдкара — ставя ровно то, что в нём уже работает. Пункт 4 из 6 в цепочке апдейта зависимостей (после #3207, #3210, #3211).
bot-backend added 1 commit 2026-08-29 11:01:45 +00:00
chore(deps): три места, где сборка не воспроизводится — лок-призрак, глоб и неприпинованный сайдкар
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Successful in 1m9s
CI / openapi-codegen-check (pull_request) Successful in 2m23s
CI / backend-tests (pull_request) Successful in 18m6s
25bebadca5
Ничего не апгрейдит. Убирает три способа собрать образ не тем, что в репозитории.

1. tradein-mvp/backend/uv.lock — удалён (файл был untracked, в .gitignore
   с рождения). Мера — uv-workspace, сборка берёт КОРНЕВОЙ tradein-mvp/uv.lock
   (`context: ./tradein-mvp`, `COPY pyproject.toml uv.lock ./` + `uv sync
   --frozen`). Лок, созданный `uv lock` из backend/, не читает никто, и он тихо
   разошёлся с рабочим: на 2026-08-29 в нём pillow 12.2.0, starlette 1.0.1,
   python-multipart 0.0.29, pydantic-settings 2.14.1, weasyprint 68.1 — пять
   пакетов с открытыми advisory, которых в реальной сборке Меры нет вообще.
   Именно он подмешал пять фантомных строк в OSV-скан этой серии.
   Строка .gitignore остаётся (второй лок не нужен), но теперь с объяснением
   почему — иначе следующий читатель снимет ignore и закоммитит призрак.

2. backend/Dockerfile — `COPY pyproject.toml uv.lock* ./` + `if [ -f uv.lock ];
   then uv sync --frozen ...; else uv sync ...; fi` → без глоба и без фолбэка.
   Глоб + фолбэк означали: пропал лок — сборка не падает, а молча переключается
   на резолв «свежайшее из диапазонов pyproject». Образ собрался бы с версиями,
   которых никто не видел ни в одном PR. Теперь пропажа лока роняет COPY.

3. tradein-mvp/browser/Dockerfile — `pip install "camoufox[geoip]" aiohttp`
   без единого пина. У сайдкара нет лока вообще, так что любая пересборка (в том
   числе на несвязанном коммите) тянула свежайший camoufox, а с ним другой
   playwright — под который НЕ написан sed-патч coreBundle.js в том же файле.
   Запинено по факту прод-контейнера tradein-browser: camoufox 0.5.5,
   playwright 1.60.0, aiohttp 3.14.3. playwright явно, хотя и транзитивный
   (camoufox 0.5.5 → playwright<1.61): патч завязан на конкретную сборку драйвера.

   Там же переписан комментарий «Апгрейд playwright невозможен — camoufox 0.4.11
   pinned»: неверны обе половины. camoufox не был запинен ни на что, а 0.4.11
   в проде не стоит с неизвестно каких пор — контейнер сейчас несёт 0.5.5 и
   playwright 1.60.0.

Версии сняты с живого прод-контейнера, наличие на PyPI проверено.
bot-backend merged commit 8f5a87d4dc into main 2026-08-29 11:20:58 +00:00
bot-backend deleted branch chore/deps-hygiene-dockerfiles 2026-08-29 11:20:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3213
No description provided.