Závislosti
Co je lockfile?
Lockfile zaznamenává přesnou verzi každé závislosti, kterou správce balíčků vyřešil, přímé i tranzitivní, aby další instalace dostala stejný strom. Je to nejlepší plán, jaký pro build máte. Není to ale záznam toho, co build skutečně použil.
Aktualizováno
Co lockfile zaznamenává
Váš manifest, například package.json nebo pyproject.toml, uvádí balíčky, na kterých
závisíte, a rozsahy verzí, které připouštíte. Správce balíčků z těchto rozsahů udělá přesné verze pro celý strom,
včetně tranzitivních závislostí, a výsledek zapíše do lockfilu.
Dokumentace npm popisuje package-lock.json tak, že popisuje „the exact tree that was generated,
such that subsequent installs are able to generate identical trees“.
Jeden záznam v package-lock.json vypadá takto:
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-...",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
}
}
- version je zvolená přesná verze.
- resolved udává, odkud byl balíček stažen: URL tarballu v registru nebo URL gitu s commitem.
- integrity je hash Subresource Integrity tarballu, takže pozměněné stažení selže.
- dependencies jsou jeho vlastní závislosti, a tak se skládá strom neboli graf závislostí.
Lockfily podle správce balíčků
| Správce balíčků | Lockfile | Instalace bez jeho změny |
|---|---|---|
| npm | package-lock.json | npm ci |
| Yarn (Berry) | yarn.lock | yarn install --immutable |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile |
| uv | uv.lock | uv sync --locked |
| Poetry | poetry.lock | poetry install |
| Cargo | Cargo.lock | cargo build --locked |
| Bundler | Gemfile.lock | bundle config set frozen true |
| Go modules | Verze v go.mod a kontrolní součty v go.sum |
Příkazy buildu ve výchozím stavu go.mod neaktualizují |
U samotného pip se běžně jako náhrada používá requirements.txt s přesnými verzemi. Připíná to, co
uvádí, ale vše, co vynechá, se při každé instalaci vyřeší znovu.
V CI instalujte se zmrazeným lockfilem
Lockfile pomůže, jen když z něj build instaluje. Obyčejný npm install může aktualizovat
package-lock.json, když už neodpovídá package.json, a build tak potichu vyřeší nový
strom. npm ci je určený pro automatizovaná prostředí:
- Vyžaduje
package-lock.jsonnebonpm-shrinkwrap.json. - Pokud se lockfile a
package.jsonneshodují, skončí chybou, místo aby lockfile aktualizoval. - Nejprve odstraní existující
node_modules. - Nikdy nezapisuje do
package.jsonani do lockfilu.
Ostatní příkazy v tabulce výše dělají totéž pro své správce balíčků.
Aplikace a knihovny
U aplikací a všeho, co nasazujete, lockfile commitujte. U knihoven zamyká jen váš vlastní vývoj a CI: npm nikdy
nepublikuje package-lock.json a mimo kořenový projekt ho ignoruje. Aplikace, které vaši knihovnu
instalují, si její závislosti vyřeší samy v rámci vašich rozsahů verzí. Jedinou výjimkou v npm je
npm-shrinkwrap.json, který se publikuje a má přednost a který by většina knihoven používat neměla.
Proč lockfile není záznamem toho, co jste vydali
Lockfile je plán pro jednoho správce balíčků v jednom projektu. Build, který vytvořil vaše vydání, udělal víc, než že se tímto plánem řídil:
- Možná ho vůbec nepoužil. Instalace bez zmrazení, chybějící lockfile nebo druhý lockfile v monorepu znamenají, že se strom vyřešil jinak než podle souboru, na který se díváte.
- Cache. Balíčky obnovené z cache CI se nainstalují, aniž by se stahovaly, a cache obnovená podle částečného klíče může být starší než aktuální lockfile. Viz co cache GitHub Actions skrývá.
- Nástroje buildu. Setup actions, kompilátory, lintery a generátory kódu přicházejí jinými kanály s vlastními stromy závislostí.
-
Stahování a instalační skripty.
curlv kroku buildu nebo instalační skript balíčku stahuje kód, který žádný lockfile neuvádí: skrytou závislost. - Základní image. Build kontejneru stahuje image a balíčky operačního systému, které stojí mimo všechny jazykové lockfily.
Hashe integrity s ničím z toho nepomohou. Dokazují, že balíčky v lockfilu nebyly pozměněny; o tom, co build stáhl mimo něj, neříkají nic. Nástroje SCA, které z lockfilu dělají SBOM, dědí stejná slepá místa.
Zaznamenejte build, lockfile si nechte
Lockfily dál commitujte a instalujte z nich se zmrazením. Díky nim jsou buildy opakovatelné, i když samy o sobě nezajistí reprodukovatelný build. Pro záznam toho, co vydání obsahuje, zaznamenává CRACI samotný build: proxy, která rozumí balíčkům, na jeho runnerech GitHub Actions zaznamenává každý balíček, který každý job stáhne, včetně balíčků obnovených z cache CI, a SBOM každého jobu uvádí svou vlastní úplnost. Tento záznam dává úplnější obraz používaných závislostí než sken lockfilu. Viz SBOM z doby buildu, nebo si rezervujte demo a porovnejte obojí na jednom z vašich vlastních buildů.
Lockfily: časté dotazy
Co je lockfile?
Lockfile je soubor, do kterého správce balíčků zaznamená přesnou verzi každé vyřešené závislosti, přímé i tranzitivní, spolu s tím, odkud pochází, a kontrolním součtem. Pozdější instalace ho čtou, aby reprodukovaly stejný strom, místo aby znovu řešily rozsahy verzí.
Mám lockfile commitovat?
Ano, u aplikací a všeho, co nasazujete. Bez commitnutého lockfilu každá čistá instalace znovu řeší rozsahy verzí a může natáhnout nové tranzitivní verze. Commitujte ho a v CI z něj instalujte se zmrazením, například přes npm ci.
Připíná lockfile i tranzitivní závislosti?
Ano. To je jeho hlavní úkol. Manifest uvádí jen vaše přímé závislosti a jejich povolené rozsahy; lockfile zaznamenává přesnou verzi zvolenou pro každý balíček ve stromu.
Platí lockfily i pro knihovny, které publikuji?
Pro vaše uživatele ne. Například npm nikdy nepublikuje package-lock.json a mimo kořenový projekt ho ignoruje. Aplikace, které vaši knihovnu instalují, si její závislosti vyřeší samy v rámci rozsahů, které povoluje váš package.json.
K čemu slouží pole integrity v package-lock.json?
Obsahuje hash Subresource Integrity tarballu balíčku, obvykle sha512. npm proti němu stažený balíček ověří, takže pozměněný tarball zamčené verze se nenainstaluje. Chrání balíčky v lockfilu, ne nic, co build stáhne mimo něj.
Je lockfile totéž co SBOM?
Ne. Lockfile je vstup: plán, kterým se správce balíčků řídí v jednom projektu. SBOM je inventář vydání. Nástroje SCA často z lockfilu dělají SBOM, což funguje, když build nainstaloval přesně lockfile a nic jiného.
Porovnejte svůj lockfile se svým buildem
Spusťte jedno workflow na CRACI a postavte jeho zaznamenanou SBOM stažených balíčků vedle toho, co říká váš lockfile.
Rezervujte si demo