---
# System prepended metadata

title: Adding Components to the build process
tags: [Proposals]

---

# Adding Components to the build process
###### tags: `Proposals`

[toc]

## Synopsis

The following instructions complement Akri [Development](https://github.com/deislabs/akri/blob/main/docs/development.md) and assume that you've already created a new Rust project member for Akri (hopefully using a skeleton generated by [Protocol "skeleton-builder:](https://github.com/deislabs/akri/issues/133). This document intends to summarize the multiple, independents steps necessary to get your component building as part of Akri's build process.

## Assumptions

+ A new Akri module written in Rust called `${MEMBER_NAME}` has been created within (a fork of) Akri's GitHub repo
+ `${MEMBER_NAME}` is in `${MEMBER_PATH}`subdirectory (this should be a relative reference omitting `./`).

## Architectures

Akri builds for 3 architectures and these are referenced using different names by different platforms:

|Generic|Rust|Docker|
|-------|----|------|
|AMD64|x86_64|amd64|
|ARM32|armv7|arm32v7|
|ARM64|aarch64|arm64v8|

## Akri `./Cargo.toml`

+ Add `${MEMBER_PATH}` to the list of `member` in Akri's `./Cargo.toml'
+ For convenience (!) match `${MEMBER_PATH}/Cargo.toml` version property to the current Akri version (in `./version.txt`)
+ See [Versioning](#Versioning)

Pseudo-code
```bash
sed \
--in-place \
--regexp-extended \
"s|^members = \[(.*)\]|^members = \[\1\, \"${MEMBER_PATH}\"]|g" \
./Cargo.toml
```

## `.dockerignore`

Akri's Cargo Cross build process generates debug and release binaries for each architecture. These files are stored for in e.g. `./target/x86_64-unknown-linux-gnu/release` for AMD64 (`x86_64`) release build. These files must be *un-excluded* from the `.dockerignore` file.

Add entries to `.dockerignore` for each [Architecture](#Architectures). The following pseudo-code must be added:

```bash=
for ARCH in "aarch64" "armv7" "x86_64"
do
  NAME="${ARCH}-unknown-linux-gnu"
  for TYPE in "debug" "release"
  do
    echo "!target/${NAME}/${TYPE}/${MEMBER_NAME}"
  done
done
```

## GitHub Actions

The build process containerizes the cross-platform Rust binaries. It uses GitHub Actions to do this. Each Akri component has a GitHub Actions file.

+ Create `.github/workflows/build-${MEMBER_NAME}-container.yml`
+ Copy the content of one of the existing workflows
+ Search and replace content so that it matches `${MEMBER_NAME}`

Depending on the workflow's `on` trigger events, this Action may be triggered on subsequent pushes.

## Update `CHANGELOG.md`

## Versioning

Versioning is controlled by a state file (./version.txt) containing Akri's current SemVer and `./version.sh` which is the process that bumps and checks version increases.

You will need to revise `./version.sh` in 2 (!) places to ensure that `${MEMBER_PATH}/Cargo.toml` is bumped by `./version.sh`.

```bash
sed \
--in-place \
--regexp-extended \
"s|CARGO_FILES=\"(.*)\"|CARGO_FILES=\"\1 \$BASEDIR/${MEMBER_PATH}/Cargo.toml\"|g" \
./version.sh
```
Then:

+ `./version.sh -c -s`
+ `./version.sh -u -p`

## Makefile

You will need to add `${MEMBER_NAME}` to Akri's Makefile `./build/akri-containers.mk`.

> **NOTE** Makefiles reference variables as `$(NAME)`. In the following, to differentiate, you must replace values of the form `${NAME}` (braces) e.g. `${MEMBER_NAME}`

+ Update comments
  + `make akri-[controller|...|${MEMBER_NAME}]`
  + `BUILD_AMD64=1 BUILD_ARM32=0 BUILD_ARM64=1 make akri-[controller|...|${MEMBER_NAME}`
+ Append to `.PHONY` section `akri-${MEMBER_NAME}: akri-build akri-docker-${MEMBER_NAME}`
+ `akri-docker-build: ... ${MEMBER_NAME}-build`
+ Create 3 sections (see below) `${MEMBER_NAME}-build`
+ Append to `akri-docker-push-per-arch: ... ${MEMBER_NAME}-docker-per-arch`
+ Append to `akri-docker-push-multi-arch-push: ... ${MEMBER_NAME}-docker-multi-arch-push`

|MAKE|SHORT|LONG|
|----|-----|----|
|amd64|AMD64|AMD64|
|arm32|ARM32|ARM32V7|
|arm64|ARM64|ARM64V8|

```bash
NAME=${MEMBER_NAME}-build
${NAME}: ${NAME}-amd64 ${NAME}-arm32 ${NAME}-arm64
```
The following section content must be repeated for each of the architectures. However this section uses a mixture of `MAKE`, `SHORT` and `LONG` architecture names as defined above:

```Make
${NAME}-[[MAKE]]:
ifeq (1, ${BUILD_[[SHORT]]})
    docker build $(CACHE_OPTION) --file=$(DOCKERFILE_DIR)/Dockerfile.${MEMBER_NAME} --tag=$(PREFIX)/${MEMBER_NAME}:$(LABEL_PREFIX)-$($[[LONG]]_SUFFIX) \
  --build-arg PLATFORM=$(${[[LONG]]_SUFFIX) .
endif
```
And:

```Make
NAME=${MEMBER_NAME}-docker-per-arch
${NAME}: ${NAME}-amd64 ${NAME}-arm32 ${NAME}-arm64
```
The following section content must be repeated for each of the architectures:

```Make
${NAME}-[[MAKE]]:
ifeq (1, ${BUILD_[[SHORT]]})
    docker push $(PREFIX)/${MEMBER_NAME}:$(LABEL_PREFIX)-$([[LONG]]_SUFFIX)
endif
```
And finally:

```Make
NAME=${MEMBER_NAME}-docker-multi-arch-create
${NAME}:
```
And, for each architecture:

```Make
ifeq (1, ${BUILD_[[SHORT]]})
	$(ENABLE_DOCKER_MANIFEST) docker manifest create --amend $(PREFIX)/${MEMBER_NAME}:$(LABEL_PREFIX) $(PREFIX)/${MEMBER_NAME}:$(LABEL_PREFIX)-$([[LONG]]_SUFFIX)
endif
```
## Dockerfile

Create a file `./build/containers/Dockerfile.${MEMBER_NAME}`.

You may replicate the content from another Dockerfile but be careful to revise it to reflect your `${MEMBER_NAME}` details.

## Helm

You should revise Akri's Helm Chart (`./deployment/helm`) to incorporate `${MEMBER_NAME}`. You will probably need to add a section (called `${MEMBER_NAME}`) to `Values.yml`.

> **NOTE** Helm uses camelCase naming, revise your `${MEMBER_NAME}` to be camelCase when using it in Helm templates.

You may wish to replicate an existing section to ensure consistency.

Then create a template for your `${MEMBER_NAME}` in `./deployment/helm/templates/${MEMBER_NAME}.yaml` (**NB** `.yaml`). You may wish to use e.g. `agent.yaml` as a guide.

