Go to file
Kasper Juul Hermansen 9d428feaef
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
chore(deps): update rust crate tracing to v0.1.41
2024-11-28 01:30:18 +00:00
crates feat: use derive 2024-10-27 12:05:30 +01:00
templates feat: add bare 2024-08-23 21:51:42 +02:00
.drone.yml feat: add bare 2024-08-23 21:51:42 +02:00
.gitignore feat: add bare 2024-08-23 21:51:42 +02:00
Cargo.lock chore(deps): update rust crate tracing to v0.1.41 2024-11-28 01:30:18 +00:00
Cargo.toml feat: use derive 2024-10-27 12:05:30 +01:00
cuddle.yaml feat: add bare 2024-08-23 21:51:42 +02:00
README.md docs: add docs 2024-08-23 22:48:14 +02:00
renovate.json Add renovate.json 2022-10-25 20:35:20 +00:00

Cuddle

Cuddle aims to reduce the complexity of building code projects. It allows either individuals or organisations to share scripts and workflows, as well as keep a dynamic inventory of their code.

At its most basic allows enforcing a schema for projects, further it allows the sharing of scripts, pipelines, templates, and much more.

cuddle init

Cuddle is meant to be used in the degree that it makes sense for you, it can be adopted quickly to improve code sharing, and be fully bought into to provide a full suite of project level solutions to offload requirements of developers. Start small with scripts and plans, and gradually adopt features from there as you need them.

Usage

Cuddle is primarily a cli based tool, but ships with optional server components. Server components helps enhance the features of cuddle, such that variables can be enforced at runtime, actions be downloaded instead of built and much more. It all works on a gradual adoption process, so as an operator you can gradually add features as you mature and need them.

A cuddle workflow is split up into:

  • Projects: A project is what most users interface with, you can think of it as the cockpit of a car. You can use all the bells and whistles, but somebody else has built up all the user journeys you're interacting with.
  • Plans: A plan is the engine room of the car, it ties together components, features and requirements for use in the cockpit. The plan usually faciliates most of the infrastructure an application stands to outsource. Such as scripts to run, build, test an application, build its templates for deployment, run pipelines, common actions. Plans specialize in building preciely what the projects needs, as such your organisation or yourself, should only have a handful of them at most. To further reduce duplication of work between plans, components can be used to abstract common features required by plans, such as templating, individual components for templates.
  • Components: Components are a slice of features not useful in of itself, but used by plans to further their behavior, a sample component may be a template part, which includes a list of allowed ip addresses for internal communication, it may be how to build an ingress, ship a docker container to a registry, basically small individual components useful for a larger whole.
  • Actions: are code units that can take a variety of forms, golang, rust, bash, what have you. All of them are accessed by cuddle do, individual components can take the form of actions, if desired
  • Global: Is a set of actions and features that are available anywhere a user might need them. For example it can be a solution to easily log into production environments, release code to production, get the menu from the canteen, etc.
  • Personal: Is a config an org can decide the users and develoeprs fill out, it can help other tooling better enhance the experience. For example it may be useful to always have the developers email available, if for example we want to trigger an automatic login for them.

Init

cuddle init will bootstrap a project either from scratch, or just adding required cuddle.toml parts.

A cuddle.toml is required to access project level cuddle commands. Such as cuddle do, cuddle get, cuddle validate, etc.

cuddle.toml looks something like this:

[project]
name = "some-cuddle-project"
owner = "kjuulh"

What is generated out of the box is a bare project. A bare project doesn't share any features, or enforce any requirements on its schema from its plan. It is most useful for projects that doesn't fit any mold, or for individual users simply testing out the framework.

Actions

cuddle actions are project level scripts that can take a variety of forms. Actions are invoked via. cuddle do when inside of a project, most projects won't build actions themselves, instead they will depend on what their plan provides for them.

Actions can be bootstrapped via. cuddle init actions, an action is slice of a cli. Cuddle provides a convenient way of building them, such that they are easy to build, maintain and operate. Most actions are written in either golang or rust, but bash and lua is also available.

[project]
# ...  

[project.actions.run]
type = "bash"
command = """
  cargo run -p some-cuddle-project -- $@
"""

This action can be invoked via.

cuddle do run

Scripts are also based on convention, so if a rust action is used:

cuddle init action rust

Nothing will be added to the cuddle.toml instead you'll receive a actions/rust/ project where you can fill out the clis according to the template given.

Plans

Plans are a crucial component for code sharing, enforcement of values, metrics and so on. Plans provide a predefined journey for how to work with a specific type of application. I.e. what does our organisation think a Rust application look like?

Plans are maintained via. the plan section of the cuddle.toml file

[plan]
git = "https://github.com/kjuulh/some-cuddle-plan.git"
branch = "main"

# Alternatively
plan = "https://github.com/kjuulh/some-cuddle-plan.git" # if you want the default

[project]
# ...

A plan itself will be maintained via. a cuddle.plan.toml file.

cuddle init plan
[plan]
name = "some-cuddle-plan"

[plan.components]
canteen = {git = "https://github.com/kjuulh/canteen"}
ingress = {git = "https://github.com/kjuulh/cuddle-ingress"}
ip-allowlist = {git = "https://github.com/kjuulh/ip-allowlist"}