What is an artifact?

Artifact is a special image that is used by images and artifacts to isolate the build process and build tools resources (environments, software, data).

Artifact cannot be tagged like image and used as standalone application.

Using artifacts, you can independently assemble an unlimited number of components, and also solving the following problems:

  • The application can consist of a set of components, and each has its dependencies. With a standard assembly, you should rebuild all every time, but you want to assemble each one on-demand.
  • Components need to be assembled in other environments.

Importing resources from artifacts are described in import directive in destination image config section (image or artifact).

Configuration

The configuration of the artifact is not much different from the configuration of image. Each artifact should be described in a separate artifact config section.

The instructions associated with the from stage, namely the base image and mounts, and also imports remain unchanged.

The docker_instructions stage and the corresponding instructions are not supported for the artifact. An artifact is an assembly tool and only the data stored in it is required.

The remaining stages and instructions are considered further separately.

Naming

artifact: <artifact name>

Artifact images are declared with artifact directive: artifact: <artifact name>. Unlike the naming of the image, the artifact has no limitations associated with docker naming convention, as used only internal.

artifact: "application assets"

Adding source code from git repositories

Unlike with image, artifact stage conveyor has no gitCache and gitLatestPatch stages.

werf implements optional dependence on changes in git repositories for artifacts. Thus, by default werf ignores them and artifact image is cached after the first assembly, but you can specify any dependencies for assembly instructions

Read about working with git repositories in the corresponding article.

Running assembly instructions

Directives and user stages remain unchanged: beforeInstall, install, beforeSetup and setup.

If there are no dependencies on files specified in git stageDependencies directive for user stages, the image is cached after the first build and will no longer be reassembled while the related stages exist in stages storage.

If the artifact should be rebuilt on any change in the related git repository, you should specify the stageDependency **/* for any user stage, e.g., for install stage:

git:
- to: /
  stageDependencies:
    install: "**/*"

Read about working with assembly instructions in the corresponding article.

Using artifacts

Unlike stapel image, stapel artifact does not have a git latest patch stage.

Git latest patch stage is supposed to be updated on every commit, which brings new changes to files. Stapel artifact though is recommended to be used as a deeply cached image, which will be updated in rare cases, when some special files changed.

For example: import git into stapel artifact and rebuild assets in this artifact only when dependent assets files in git has changes. For every other change in git where non-dependent files has been changed assets will not be rebuilt.

However in the case when there is a need to bring changes of any git files into stapel artifact (to build Go application for example) user should define git.stageDependencies of some stage that needs these files explicitly as * pattern:

git:
- add: /
  to: /app
  stageDependencies:
    setup:
    - "*"

In this case every change in git files will result in artifact rebuild, all stapel images that import this artifact will also be rebuilt.

NOTE User should employ multiple separate git.add directive invocations in every stapel image and stapel artifact that needs git files — it is an optimal way to add git files into any image. Adding git files to artifact and then importing it into image using import directive is not recommended.

All directives

artifact: <artifact_name>
from: <image>
fromLatest: <bool>
herebyIAdmitThatFromLatestMightBreakReproducibility: <bool>
fromCacheVersion: <version>
fromImage: <image_name>
fromImageArtifact: <artifact_name>
git:
# local git
- add: <absolute path in git repository>
  to: <absolute path inside image>
  owner: <owner>
  group: <group>
  includePaths:
  - <path or glob relative to path in add>
  excludePaths:
  - <path or glob relative to path in add>
  stageDependencies:
    install:
    - <path or glob relative to path in add>
    beforeSetup:
    - <path or glob relative to path in add>
    setup:
    - <path or glob relative to path in add>
# remote git
- url: <git repo url>
  branch: <branch name>
  herebyIAdmitThatBranchMightBreakReproducibility: <bool>
  commit: <commit>
  tag: <tag>
  add: <absolute path in git repository>
  to: <absolute path inside image>
  owner: <owner>
  group: <group>
  includePaths:
  - <path or glob relative to path in add>
  excludePaths:
  - <path or glob relative to path in add>
  stageDependencies:
    install:
    - <path or glob relative to path in add>
    beforeSetup:
    - <path or glob relative to path in add>
    setup:
    - <path or glob relative to path in add>
shell:
  beforeInstall:
  - <cmd>
  install:
  - <cmd>
  beforeSetup:
  - <cmd>
  setup:
  - <cmd>
  cacheVersion: <version>
  beforeInstallCacheVersion: <version>
  installCacheVersion: <version>
  beforeSetupCacheVersion: <version>
  setupCacheVersion: <version>
ansible:
  beforeInstall:
  - <task>
  install:
  - <task>
  beforeSetup:
  - <task>
  setup:
  - <task>
  cacheVersion: <version>
  beforeInstallCacheVersion: <version>
  installCacheVersion: <version>
  beforeSetupCacheVersion: <version>
  setupCacheVersion: <version>
mount:
- from: build_dir
  to: <absolute_path>
- from: tmp_dir
  to: <absolute_path>
- fromPath: <absolute_or_relative_path>
  to: <absolute_path>
import:
- artifact: <artifact name>
  image: <image name>
  stage: <stage name>
  before: <install || setup>
  after: <install || setup>
  add: <absolute path>
  to: <absolute path>
  owner: <owner>
  group: <group>
  includePaths:
  - <relative path or glob>
  excludePaths:
  - <relative path or glob>
asLayers: <bool>