About giterminism

To ensure consistency and guarantee reproducibility, werf introduces the so-called mechanism of giterminism. Its name comes from a combination of the words git and determinism and refers to “deterministic Git” mode. In this mode, werf reads the configuration and build context from the current project repository commit and, by default, does not permit the use of external dependencies.

Any user drift from giterminism must be documented in a dedicated werf-giterminism.yaml file so that the configuration management process remains meaningful and the usage is transparent to all participants of the delivery cycle.

Excluding unused files

werf does not permit working with uncommitted and untracked files in Git. If files are not required, they should be explicitly excluded using the .gitignore and .helmignore files.

Using uncommitted and untracked files in debugging and development

When debugging and developing, making changes to project files can be inconvenient due to the need to create intermediate commits. We are implementing a development mode to streamline this process and at the same time keep the general logic of the project unchanged.

In current versions, development mode (activated by the --dev option) allows you to work with the worktree state of the project’s Git repository as well as with tracked and untracked files. werf ignores changes based on the rules defined in .gitignore as well as the rules set by the user using the --dev-ignore=<glob> option (can be used multiple times).

Enabling nondeterministic functionality on a case-by-case basis

werf.yaml templating

Functions of the Go templating engine

env

Using env makes it difficult to share and reproduce the configuration in CI jobs and among developers, because the value of the environment variable affects the final digest of the images being built, so the value must be the same at all stages of the CI pipeline and in local development during reproduction.

The env function can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

Assembling

Dockerfile image

contextAddFiles

Using the contextAddFiles directive complicates configuration sharing and reproducibility in CI jobs and among developers, since file data affects the final digest of the built images and must be identical at all stages of the CI pipeline and in local development during reproduction.

The contextAddFiles directive can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

Stapel image

fromLatest

When using fromLatest, werf factors in the real base image digest when calculating the build image digest. Thus, using this directive can break the reproducibility of earlier builds. Changing the base image in the container registry would render all previously built images unusable.

  • Any preceding jobs of the CI pipeline (e.g., converge) will not run without first rebuilding the image, once the base image in the container registry has been changed.
  • Changing the base image in the container registry will result in unexpected CI pipeline failures. Suppose the change occurs after a successful build. In this case, subsequent jobs will fail because the final image digest has been changed along with the base image digest.

As an alternative, we recommend using an immutable tag or periodically changing the value of fromCacheVersion to ensure a manageable and predictable application lifecycle.

The fromLatest directive can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

git
branch

Using the branch directive (the default is master branch) when working with arbitrary git repositories can break reproducibility of previous builds. werf uses the history of a git repository to calculate the digest of the image being built. Thus, a new commit in a branch will render all previously built images unusable.

  • The existing jobs of the CI pipeline (e.g., converge) will not run and will require rebuilding the image if the branch’s HEAD has been changed.
  • Out-of-order commits to a branch can cause the CI pipeline to fail for no apparent reason. Suppose, a change has been made after the build process has been successfully completed. In this case, all the related CI pipeline jobs will fail due to changes in digests of the images being built, along with the HEAD of the corresponding branch.

As an alternative, we recommend using an immutable link, tag, or commit to guarantee a manageable and predictable application lifecycle.

The branch directive can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

mount
build_dir

Using the build_dir mounting directive may lead to unpredictable behavior if used in parallel and potentially affect reproducibility and reliability.

The build_dir directive can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

fromPath

The use of the fromPath mounting directive may result in unpredictable behavior if used in parallel and potentially affect reproducibility and reliability. The data in the mount directory does not affect the final digest of the built image, which may result in invalid images as well as hard to track problems.

The fromPath directive can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.

Deploying

The –use-custom-tag option

The use of tag aliases with immutable values (e.g., %image%-master) makes previous deploys unreproducible and requires setting the imagePullPolicy: Always policy for each image when configuring application containers in the Helm chart.

The --use-custom-tag oprion can be activated using werf-giterminism.yaml, but we strongly recommend that you carefully consider the possible implications of this.