Що таке lockfile і чому CI має ставити саме ті версії залежностей

BasicsDevOpsCI/CDSupply ChainJavaScript

Lockfile фіксує точні версії залежностей, щоб локальна машина, CI і production збирали однаковий набір пакетів

Lockfile часто виглядає як дивний великий файл, який заважає злиттю гілок. Але для команди це один із найважливіших файлів у проєкті: він відповідає за те, щоб усі ставили однакові залежності.

Якщо lockfile немає або CI його ігнорує, проєкт може працювати на машині одного розробника, падати в іншого і збиратися третім набором пакетів на сервері. Це неприємно для дебагу, тестів і безпеки.

Що саме означає lockfile

Lockfile - це файл, який створює менеджер пакетів після розв’язання залежностей. У JavaScript-проєктах це може бути package-lock.json, pnpm-lock.yaml або yarn.lock. В інших екосистемах назви інші, але ідея схожа: зафіксувати точний результат вибору пакетів.

Manifest-файл на кшталт package.json описує, що проєкту потрібно. Там часто є діапазон версій: наприклад, дозволити будь-який сумісний patch або minor release. Lockfile показує, що було обрано насправді: конкретні версії, транзитивні залежності, джерела пакетів і контрольні дані.

Тому lockfile не є шумом. Це знімок dependency tree, який команда хоче повторити.

Чому CI має ставити саме ці версії

CI потрібен не для творчого підбору залежностей, а для перевірки коду. Якщо кожен запуск CI може самостійно оновити залежності, тест перевіряє не тільки ваш pull request, а ще й випадкові зміни з registry.

Правильний режим такий:

  • розробник свідомо оновлює залежність;
  • менеджер пакетів змінює manifest і lockfile;
  • pull request показує ці зміни;
  • code review дивиться, що саме оновилося;
  • CI встановлює залежності з lockfile без переписування;
  • тести та SCA перевіряють результат.

Це дає відтворюваність. Якщо збірка впала, команда знає, що набір пакетів не змінився непомітно між локальною машиною і CI.

Як це виглядає в реальному проєкті

Для npm типова команда в CI:

npm ci

Вона очікує наявний package-lock.json і встановлює залежності чисто з нього. Якщо manifest і lockfile не узгоджені, це має бути помилка, а не мовчазне виправлення.

Для pnpm у CI зазвичай використовують frozen install:

pnpm install --frozen-lockfile

Для Yarn сучасний еквівалент:

yarn install --immutable

Сенс однаковий: CI не повинен сам вирішувати, які версії поставити. Він має перевірити, що репозиторій уже містить повний і узгоджений dependency state.

Де новачок найчастіше помиляється

Помилка 1: не комітити lockfile

Для застосунків lockfile зазвичай треба комітити. Інакше кожен встановлює залежності трохи по-своєму, а CI не має стабільного джерела правди.

Помилка 2: видаляти lockfile під час конфлікту

Конфлікти в lockfile справді неприємні. Але видалити файл і згенерувати його випадково - поганий ремонт. Краще оновити гілку, перевстановити залежності правильним менеджером пакетів і уважно подивитися diff.

Помилка 3: не читати зміни lockfile у review

Якщо pull request змінює одну залежність, а lockfile показує десятки нових транзитивних залежностей, це варто помітити. Не треба читати кожен рядок як роман, але треба бачити масштаб і напрям зміни.

Помилка 4: дозволяти CI переписувати lockfile

CI, який після install залишає змінений lockfile, сигналізує про проблему. Такий build має падати або просити оновити lockfile в pull request.

Lockfile і безпека

Lockfile допомагає не лише з повторюваними збірками. Він також робить dependency scanning точнішим. SCA бачить не абстрактний діапазон версій, а конкретні пакети, які реально потрапляють у збірку.

Це важливо для supply chain:

  • простіше зрозуміти, яка версія пакета в production;
  • легше повторити інцидент або баг;
  • dependency update стає видимим у pull request;
  • SBOM може точніше описати artifact;
  • підозріла зміна пакета не ховається за звичайним install.

Lockfile не робить проєкт безпечним автоматично, але прибирає багато випадковості.

Практичний процес для команди

  1. Виберіть один менеджер пакетів для проєкту.
  2. Закомітьте відповідний lockfile.
  3. Запишіть локальну команду встановлення в README.
  4. У CI використовуйте strict або frozen install.
  5. Не дозволяйте CI автоматично комітити lockfile.
  6. Перевіряйте dependency diff у pull request.
  7. Після оновлення пакетів запускайте тести й SCA.

Короткий висновок

Lockfile - це не службове сміття, а договір команди про точний набір залежностей. Він робить збірку повторюваною, CI чесним, review зрозумілішим, а перевірки безпеки конкретнішими.

Якщо коротко: manifest каже, що проєкт хоче; lockfile каже, що проєкт реально отримав. CI має довіряти другому і не вигадувати новий dependency tree на кожному запуску.

Офіційні джерела:

Короткий чеклист

  • Переконатися, що lockfile закомічений у репозиторій.
  • У CI запускати команду, яка не переписує lockfile.
  • Перевіряти зміни lockfile у pull request.
  • Після оновлення залежностей запускати тести та SCA.
  • Не видаляти lockfile для випадкового виправлення конфлікту.
  • Документувати команду встановлення для локальної роботи й CI.

Prompt Pack: перевірити lockfile-політику в проєкті

Допоможи перевірити, чи правильно проєкт працює з lockfile. Вхідні дані: - стек і менеджер пакетів; - назва lockfile у репозиторії; - команда локального встановлення залежностей; - команда встановлення в CI; - чи дозволено CI змінювати lockfile; - приклад pull request, де змінилися залежності; - чи є SCA або dependency scanning; - де збирається production artifact. Поверни: 1. короткий verdict, чи lockfile використовується правильно; 2. яку команду запускати локально; 3. яку команду запускати в CI; 4. які зміни lockfile мають проходити code review; 5. які ризики є для reproducible build і supply chain; 6. короткий checklist для команди. Формат: verdict, local workflow, CI workflow, review rules, risks, checklist.