In order to contribute to this project, please follow all listed guidelines in this document.
Our architecture leans on 12factor.net principles and is designed to be platform agnostic. There should be strong separation between generic Capact business logic and platform-specific implementation, such as Kubernetes, CloudFoundry, OpenShift, and similar.
We are using Make targets to execute commonly used development tasks. All development tools should be placed in hack folder.
We assume that the Go and Docker is installed both on CI and on a local machine in a proper version. Currently, all scripts don't validate it.
If tool is written in a different language, then we use Docker to run that tool, e.g.
quicktype for Go struct generation from JSON Schemas.
All tools should:
SKIP_DEPS_INSTALLATIONenvironment variable that can be set to
false. If set to
falsedependencies should be installed to a tempdir and cleaned up after execution.
- define its stable versions in ./lib/const.sh file.
- works both on a local machine and on CI.
NOTE: We are not using dedicated GitHub Actions on CI as we want to have a control and deterministic executions of our tools both on CI and local machines.
For assertions in Go unit-tests we are using testify library as this gives as simple matchers functions which we do not have to write by ourselves.
It is used by default by the Kubebuilder which we used for boostraping Kubernetes controller, and we see value in that if it comes for integration tests. Thanks to BDD approach the integration tests are more readable and describes better tested contract. Additionally, you can use such assertions out-of-the-box:
Consistently()to ensure that the given state remains same over a duration of time.
Eventually()to repeat a given function every interval seconds until function’s output matches what’s expected.
In the Capact project, we use the structured logging concept.
With structured logging, we associate a constant log message with some variable key-value pairs. For instance, suppose we wanted to log that we were starting HTTP server for a given application. In the Go standard library logger, you would write:
log.Printf("starting %s HTTP server on addr %s", appName, svrAddr)
With structured logging, you write:
logger.Info("starting HTTP server", "app", appName, "addr", svrAddr)
Read this document if you want to learn more about logging practices in the Kubernetes engine domain.
While it's possible to use other log levels, it's recommended that you stick with
Read this article to understand why other levels are obsolete and lead to inconsistent logs.