Skip to main content

Hacking on Kargo

Kargo is implemented in Go. For maximum productivity in your text editor or IDE, it is recommended that you have installed the latest stable releases of Go and applicable editor/IDE extensions, however, this is not strictly required to be successful.

Running Tests

In order to minimize the setup required to apply small changes and to reduce the incidence of tests passing locally, but failing during the continuous integration process due to environmental differences, we've made it easy to execute tests within a container that is maximally similar to those used in CI.

To take advantage of this, you only need make and Docker (or a Docker-compatible container-runtime).

To run all unit tests:

make hack-test-unit
info

If you wish to opt-out of executing the tests within a container (for performance reasons, perhaps), drop the hack- prefix from the target:

make test-unit

This will require Go to be installed locally.

Running Linters

It is also possible to execute a variety of different linters that perform static code analysis, detect code hygiene issues, assert adherence to project standards, etc. As with unit tests, we've made it easy to execute linters within a container that is maximally similar to those used in CI.

To lint Go code only:

make hack-lint-go

To lint generated protobuf definitions only:

make hack-lint-proto

To lint Helm charts only:

make hack-lint-charts

To run all linters with one command:

make hack-lint
info

If you wish to opt-out of executing any or all linters within a container (for performance reasons, perhaps), drop the hack- prefix from the desired target.

This will require quite a variety of tools to be installed locally, so we do not recommend this if you can avoid it.

Executing Code Generation

Anytime the contents of the api/ directory have been modified, a code generation process must be manually executed. As with tests and linters, this process is easy to execute within a container, which eliminates the need to install various tools or specific versions thereof:

make hack-codegen
info

If you wish to opt-out of executing code-generation within a container (for performance reasons, perhaps), drop the hack- prefix from the target:

make codegen

This will require quite a variety of tools to be installed locally, so we do not recommend this if you can avoid it.

Building the Image

To build source into a Docker image that will be tagged as kargo:dev, execute the following:

make hack-build
info

There is seldom a need to do this, as the next section will cover a better option for rapidly building and deploying Kargo from source.

tip

The Docker buildx machine required by the build process has to be created with the --driver-opt network=host option to allow it to access the (temporary) local image registry used for the base image.

If you encounter an error during the build process (e.g. failed to resolve source metadata for localhost:5001/kargo-base:latest-arm64 or granting entitlement network.host is not allowed by build daemon configuration), you may need to (re)create the machine using docker buildx create with this option set.

Iterating Quickly

This section focuses on the best approaches for gaining rapid feedback on changes you make to Kargo's code base.

The fastest path to learning whether changes you have applied work as desired is to execute unit tests as described in previous sections. If the changes you are applying are complex, it can also be advantageous to exercise them, end-to-end, as a user would. Because Kargo is dependent on a Kubernetes cluster, this raises the question of how Kargo can not only be built from source, but also deployed to a live Kubernetes cluster efficiently enough to enable a tight feedback loop as you continue iterating on your changes.

The remainder of this section covers the approaches we recommend for enabling this.

info

We may eventually provide convenient methods of running some Kargo components as native processes.

  1. Launch or re-use an existing local Kubernetes cluster.

    Any of the following options are viable:

    If you are a Docker Desktop user, you can follow these instructions to enable its built-in Kubernetes support.

    info

    A specific benefit of this option is that nothing special is required in terms of creating a local image registry connected to the cluster. Additionally, this approach requires no specific port-forwarding rules to be defined.

    info

    Although this is one of the fastest paths to a local Kubernetes cluster, be aware that Docker Desktop supports only a single Kubernetes cluster. If that cluster reaches a state you are dissatisfied with, resetting it will remove not just Kargo-related resources, but all your workloads and data.

    To install Kargo's prerequisites, you will need Helm installed first, and can then execute a convenient make target:

    make hack-install-prereqs

    Whichever approach you choose, your cluster will end up with recent, stable versions of cert-manager and Argo CD installed.

    info

    The Argo CD dashboard will be exposed at localhost:30080.

    The username and password are both admin.

    You may safely ignore any certificate warnings.

  2. Build and deploy Kargo from source:

    Tilt is a convenient tool that builds container images from source and seamlessly deploys them to a local Kubernetes cluster. More importantly, it enables developers to rapidly rebuild and replace running components with the click of a button.

    warning

    If using OrbStack, be advised it is only compatible with Tilt as of Tilt v0.33.6. Please use that version or greater.

    tilt up

    Tilt will also launch a web-based UI running at http://localhost:10350. Visit this in your web browser to view the build and deployment status of each Kargo component as well as the logs from each component.

    info

    Tilt is often configured to watch files and automatically rebuild and replace running components when their source code is changed. This is deliberately disabled for Kargo since the Docker image takes long enough to build that it’s better to conserve system resources by only rebuilding when you choose. The web UI makes it easy to identify components whose source has been altered. They can be rebuilt and replaced with a single click.

  3. If necessary, build the CLI from source:

    make hack-build-cli

    This will produce an executable at bin/kargo-<os>-<arch>.

    You can log in using:

    bin/kargo-<os>-<arch> login http://localhost:30081 \
    --admin \
    --password admin \
    --insecure-skip-tls-verify
  4. If necessary, access the Kargo UI at localhost:30082.

    The admin account password is admin.

    You may safely ignore any certificate warnings.

  5. When you are done with Tilt, interrupt the running tilt up process with ctrl + c. Components will remain running in the cluster, but Tilt will no longer be in control. If Tilt is restarted later, it will retake control of the already-running components.

    If you wish to undeploy everything Tilt has deployed for you, use tilt down.

  6. Clean up your local Kubernetes cluster.

    Docker Desktop supports only a single Kubernetes cluster. If you are comfortable deleting not just just Kargo-related resources, but all your workloads and data, the cluster can be reset from the Docker Desktop Dashboard.

    If, instead, you wish to preserve non-Kargo-related workloads and data, you will need to manually uninstall Kargo's prerequisites:

    make hack-uninstall-prereqs

Contributing to Documentation

Contributors should ensure that their changes are accompanied by relevant documentation updates. This helps maintain the project's sustainability. Pull requests with corresponding documentation updates are more likely to be merged faster.

To make this process smoother, you can refer to Docusaurus for guidance on writing and maintaining docs effectively.

Previewing Doc Changes Locally

After making your changes, preview the documentation locally to ensure everything renders correctly. You can either run it in a container or natively on your system.

To build and serve the docs inside a container:

make hack-serve-docs
info

If you wish to opt-out of executing code-generation within a container (for performance reasons, perhaps), drop the hack- prefix from the target to run the docs natively on your system:

make serve-docs

This will require quite a variety of tools to be installed locally, so we do not recommend this if you can avoid it.