# cuddle ## What is Cuddle Cuddle at its heart is a tool to extend your repository project from common components to provide essential features, such as building the project, deploying it, scaffolding code, or any other cross cutting feature that is useful across your fleet of projects. Cuddle exists to provide a golden path development for projects that are setup from common templates, such as a rust-web-service, rust-cli, go-service etc. Cuddle allows a small team of developers to develop curated development tools targeted directly at what your developers needs to succeed. ## How Cuddle by itself doesn't ship anything, it is a composition tool, but provides some foundational components that a platform team can choose to compose to achieve the result they want. A common graph of dependencies will look like so: - A golang service - Depends on a github.com/kjuulh/cuddle-golang-service-plan - Composes over - docker build (Build pipelien) - docker push (Push artifacts) - kustomize (Compose actual manifest for deployment) - kjuulh/release-manager (Deliver the manifest to deployment mechanism) This means that no matter how many golang services we've got we only need a single plan to service all of your users. ### Composition Cuddle is a purely composition based tool, it means that it allows splitting cross cutting needs into many small chunks which can then be included in your service. The way the services are usually created is that usually all the field are templated, or setup with default configurations just to give a hint that those features are available. ```nickel let { Vars, .. } = import "github/kjuulh/cuddle" in let { GoPlan, .. } = import "github/kjuulh/cuddle-go-service-plan" in { vars = { name = "some-service", owner = "kjuulh" }, go_plan = { version = "1.22", database = true, messagequeue = true, cache = true, external = true, internal = true, deployment = { dev = { cron = { schedule = "* 0 * * *", http = "/refresh-cache" } env = { "openai.user" = "kjuulh" # Creates a env var with OPENAI_USER for the service "openai.key" = { # Creates a env var with OPENAI_KEY managed by vault from_vault = { path = "/some/path/to/key" } } } } } } } & Vars & GoPlan ``` A component has the same setup, but includes a different key to define what it requires ```nickel let { Vars, Component .. } = import "github/kjuulh/cuddle" in { vars = { name = "docker build", owner = "kjuulh" }, component = { actions = { docker_build = { type = rust path = "actions/docker_build" } } } } & Vars & Component ``` A plan is usually a composition of other components. ```nickel let { Vars, Component, .. } = import "github/kjuulh/cuddle" in let { ServicePlan, .. } = import "github/kjuulh/cuddle/services" in # in this case a service plan only really requires implementing a few actions { vars = { name = "docker build", owner = "kjuulh" }, component = { actions = { ci = { # CI is now required to be implemented for the nickel spec to be parsed successfully type = rust path = "actions/ci" } } } } & Vars & Component & ServicePlan ```