No description
Find a file
kjuulh 9c5c242d91
fix: health watch UX improvements, 90s timeout, correct message
- Filter PENDING/UNSPECIFIED from display, show 'waiting for health agent...'
- Use HashSet for multi-destination dedup
- Fix timeout message to match actual duration
- Seed PENDING observation in scheduler with nats client on SchedulerInner
- Reduce Kustomization interval from 5m to 30s for faster reconciliation
- Add forest.sh/managed labels to service Deployment template
- Add --no-health flag to skip health monitoring

End-to-end verified: release → flux reconcile → agent reports → CLI shows HEALTHY in ~48s

Signed-off-by: kjuulh <contact@kjuulh.io>
2026-04-03 13:20:43 +02:00
.sqlx feat: add cos 2026-03-29 21:49:22 +02:00
ci fix: make ci:main pipeline pass 2026-04-01 00:15:42 +02:00
components wip: in-progress changes 2026-04-01 09:50:21 +02:00
crates fix: health watch UX improvements, 90s timeout, correct message 2026-04-03 13:20:43 +02:00
cue wip: in-progress changes 2026-04-01 09:50:21 +02:00
docs feat: add @- (stdin) and @path (file) value syntax to forest run 2026-04-02 23:12:51 +02:00
examples wip: in-progress changes 2026-04-01 09:50:21 +02:00
interface/proto/forest/v1 feat: add ReleaseHealthService server implementation 2026-04-03 00:32:46 +02:00
scripts
sdk/typescript feat: component protocol v2 with inter-component calls and dependency client codegen 2026-04-01 09:50:21 +02:00
TASKS feat: add forest.sh/* labels and annotations to Flux Kustomization CRs 2026-04-02 23:42:37 +02:00
tasks
templates feat: add cos 2026-03-29 21:49:22 +02:00
tests/e2e feat: add cos 2026-03-29 21:49:22 +02:00
todos/hyperlog
.dockerignore
.drone.yml
.gitignore feat: remove .env 2026-03-22 03:15:14 +01:00
.goreleaser.yaml feat: use proper user 2026-03-22 03:09:11 +01:00
.ignore
buf.gen.yaml
buf.yaml
Cargo.lock feat: add cos 2026-03-29 21:49:22 +02:00
Cargo.toml feat: add cos 2026-03-29 21:49:22 +02:00
CLAUDE.md
cuddle.yaml
Dockerfile.release
mise.toml feat: add cos 2026-03-29 21:49:22 +02:00
README.md
renovate.json
shuttle.yaml

Forest

Forest is a set of tools to help you design the development workflows you need. It is specifically built to allow you to share workflows and streamline boring tasks.

Example

With forest you can quickly compose a shareable workflow to initiate a starter kit for a service, builds to produce production ready artifacts, spin up a development environment, release production services, and more.

Install forest

bargo

cargo (b)install forest

brew

brew install forest/tap/forest  

Create service

forest init
> starter: github.com/forest/rust-service-starter
> name: my-starter-service
> http: y
cd my-starter-service

Build production grade artifact

forest run docker:build
> tag: my-service-starter:local

Development environment

forest run dev:up
> spins up: postgresql at tcp/5432

Deploy artifact

forest service release
> branch: main
> artifact: abc123 - $(date)
> release: y

Rollback service

forest service rollback
> artifact: abc123 - $(date)
> release: y

Architecture

Forest allows you to use standard components, either upstream from forest, or build your own. Often we see that you use wrap standard forest components in your own ways to make forest truly yours.

Project

Project is the place where actual work happens, it is in this context that forest components are executed.

A forest.toml is the artifact that describes your dependencies, or any local workflows you may've got

Component

Component can be thought of as a library or repository of logic, files or media. Components are what makes it possible to do docker:build as no-rust-docker is a component, that houses the build command, allowing the user to build the service in question into a production ready artifact

Components can be added to a project with the following:

forest add
> forest: rust_service:docker
# Rust is the language in question, service is the type of project we care about
# Docker is the component under this namespace

Components are generally language, and/or organisation specific, and can pull certain interfaces from upstream to get access to top level commands. Such as docker:build, which is a reserved key project, all others has to go through a namespace.

  • myorg/rust_service:docker
  • rust_service:docker # blessed upstream implementation of the docker interface for a rust service implementation
  • go_service:docker # blessed upstream implementation of the docker interface for a golang service implementation
  • docker # blessed upstream interface cannot be used on its own

Roadmap

  • Init system
    • Templating
  • Components
    • Local
    • Remote

Domain model

  • Projects: scoped by org and name, contains everything related to a single project. Such as dependencies, code, links and more, documentation.
  • Components: a forest runnable project. It can contain requirements, other dependencies. It is basically either a tool, or a set of requirements and features that make upstream development easier.
  • Dependencies: A project or component can have a set of dependencies. These are components to include. Each component can require certain things their upstream parts, and add certain functionality.
  • Requirements: A component can require information from upstream services. These requirements are extra bits of information that can either be provided at runtime via. args, or via. the project variables. A component has to implement the requirements and re-require them from their upstream.
  • Artifact: A project can be published via. artifacts. An artifact can be used by interested parties and can optionally be annotated. These can either be static, or dynamic. If static it acts as releases, if dynamic these can be released, rolled back, re-released. A static artifact can be upgraded to a dynamic artifact, but the other way around isn't possible