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
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
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
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
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.
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.
We may eventually provide convenient methods of running some Kargo components as native processes.
-
Launch or re-use an existing local Kubernetes cluster.
Any of the following options are viable:
- Docker Desktop
- OrbStack
- kind
- k3d
If you are a Docker Desktop user, you can follow these instructions to enable its built-in Kubernetes support.
infoA 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.
infoAlthough 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
OrbStack is a fast, lightweight, drop-in replacement for Docker Desktop for Mac OS only. You can follow these instructions to enable its built-in Kubernetes support.
infoA 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.
infoAlthough this is one of the fastest paths to a local Kubernetes cluster, be aware that OrbStack 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
If you have any Docker-compatible container runtime installed (including native Docker, Docker Desktop, or OrbStack), you can easily launch a disposable cluster to facilitate Kargo development using kind.
This option also requires ctlptl and Helm to be installed.
The following
make
target will launch a kind cluster with a local image registry wired into it, various port-forwarding rules pre-configured, and Kargo's prerequisites installed:make hack-kind-up
infoWhile this option is a bit more complex than using Docker Desktop or OrbStack directly, it offers the advantage of being fully-disposable. If your cluster reaches a state you are dissatisfied with, you can simply destroy it and launch a new one.
If you have any Docker-compatible container runtime installed (including native Docker, Docker Desktop, or OrbStack), you can easily launch a disposable cluster to facilitate Kargo development using k3d.
This option also requires ctlptl and Helm to be installed.
The following
make
target will launch a kind cluster with a local image registry wired into it, various port-forwarding rules pre-configured, and Kargo's prerequisites installed:make hack-k3d-up
infoWhile this option is a bit more complex than using Docker Desktop or OrbStack directly, it offers the advantage of being fully-disposable. If your cluster reaches a state you are dissatisfied with, you can simply destroy it and launch a new one.
Whichever approach you choose, your cluster will end up with recent, stable versions of cert-manager and Argo CD installed.
infoThe Argo CD dashboard will be exposed at localhost:30080.
The username and password are both
admin
.You may safely ignore any certificate warnings.
-
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.
warningIf 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.
infoTilt 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.
-
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 -
If necessary, access the Kargo UI at localhost:30082.
The admin account password is
admin
.You may safely ignore any certificate warnings.
-
When you are done with Tilt, interrupt the running
tilt up
process withctrl + 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
. -
Clean up your local Kubernetes cluster.
- Docker Desktop
- OrbStack
- kind
- k3d
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
OrbStack supports only a single Kubernetes cluster. If you are comfortable deleting not just just Kargo-related resources, but all your workloads and data, you can destroy the cluster with:
orb delete k8s
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
To destroy the cluster, use:
make hack-kind-down
infoThis command deliberately leaves your local image registry running so that if you resume work later, you are doing so with a local registry that’s already primed with most layers of Kargo’s image.
If you wish to stop the registry, use:
docker stop kargo-dev-registry
To destroy it, use:
docker rm -f kargo-dev-registry
To destroy the cluster, use:
make hack-k3d-down
infoThis command deliberately leaves your local image registry running so that if you resume work later, you are doing so with a local registry that’s already primed with most layers of Kargo’s image.
If you wish to stop the registry, use:
docker stop kargo-dev-registry
To destroy it, use:
docker rm -f kargo-dev-registry
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
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.