Dependency pinning controls which external components are used when generating a software artifact. Instead of resolving whichever release currently satisfies a broad constraint, the build uses explicitly selected dependency versions or immutable content identifiers. Dependencies include application libraries, container base images, compiler toolchains, build plugins, and operating-system packages. In cloud CI/CD pipelines, this reduces situations where unchanged source code produces a different application because an upstream component changed.
A dependency manifest and a lockfile serve different purposes. A manifest can describe acceptable versions, while a lockfile records the resolved dependency graph, including indirect dependencies where the package manager supports it. Pinning only a top-level library is insufficient if that library's transitive dependencies can still resolve differently. Commit the relevant lockfile alongside the source code and configure CI to install from it without silently updating dependency selections.
For example, a Node.js build can run npm ci against a committed package-lock.json. This command requires the manifest and lockfile to agree and does not rewrite them during installation. A Python workflow can install a fully pinned requirements file with pip's --require-hashes option, provided all required dependencies are explicitly listed and have acceptable hashes. Hash validation adds content-integrity checking; a version number alone does not prove that downloaded bytes match a previously approved package.
Container builds require similar discipline. A base-image reference such as python:3.12 can move to a newer image, even though the Dockerfile remains unchanged. Referencing an image by digest fixes its content identity. However, a Dockerfile that subsequently installs unpinned packages from a changing operating-system repository can still produce different results. Build-image versions, package repository availability, target architecture, and downloaded build tools also affect the resulting artifact.
In a cloud build service, dependency installation belongs in version-controlled build instructions. Fetch dependencies from controlled repositories, verify available integrity metadata, and fail the build when locked dependencies cannot be obtained rather than silently substituting newer versions. Record the source revision and dependency metadata with the generated artifact. Build the release artifact once, then promote that same artifact through testing and production instead of rebuilding separately for each environment.
Pinning is not equivalent to caching, vulnerability scanning, or complete reproducibility. A cache accelerates downloads but does not define the required versions, and pinned packages can still contain vulnerabilities. Byte-for-byte reproducibility also requires control over timestamps, compiler behavior, and other environmental inputs. Manage the maintenance trade-off through reviewed dependency-update changes, automated tests, vulnerability checks, and an emergency patch process. For artifact-generation questions, distinguish controlled build inputs from merely storing build outputs: both matter, but artifact storage alone cannot prevent dependency drift.