Case study / Development & build workflows

Move between services.
Keep the workflow familiar.

Problem
Cross-service work required managing separate repositories, branches, dependencies, and setup steps. Reliable release builds depended on a dedicated machine.
My contribution
I proposed and led the monorepo migration, preserved repository histories, and built Nix project environments, task workflows, and Linux release builds.
What changed
The team used shared project environments and development/build workflows. The dedicated build machine was retired.
Outcome
I observed fewer version conflicts and setup questions, easier project switching, and easier cross-service changes. These are qualitative observations.
Context
Volt Labs / Multiple applications
My contribution
Migration, environments & workflows
Team use
Project environments, tasks & release builds

A change could begin with a tour of the repositories.

Starting multiple services was cumbersome. Developers had to keep track of which branch each separate repository was on, then deal with the dependencies and commands for the project they needed next.

Consolidating the repositories addressed part of that friction. Making the projects easier to work with also required explicit environments, consistent task commands, and a way to supply application configuration.

Bring the projects together.
Bring their history with them.

I proposed and led the migration into a monorepo. The migration procedure worked on temporary repository copies, relocated their files into project subdirectories, and merged the histories into the destination repository. The original remotes were left intact.

That retained the history behind the code while giving cross-service work a shared repository context. These were existing applications built by many engineers; my work was the migration and the platform workflows around them.

Let the project carry its development environment.

I built Nix environments and introduced just and Doppler. The whole engineering team used the project environments: enter with nix develop, then start the application with just run.

The Rust project flakes read their toolchain definition from the project and supplied the supporting libraries and build tools. This gave developers a defined environment when moving from one service to another.

The task runner supplied a consistent interface. Its shell ran through Doppler, loading configuration into the application’s process. Developers could use the task without manually reproducing that configuration-loading step.

Conceptual responsibilities / Development and release paths

Monorepo / Multiple projects

Project code + Nix environment + task commands

Doppler supplies configuration to task processes.

Local development

just run starts a project.
devenv up coordinates local services.

Release build

Nix-provided toolchain
+ Zig cross-compilation
→ Linux release binary

Project environments support two paths: local service orchestration and Linux release compilation.

04 / Linux release builds

I unplugged the dedicated build machine.

Make the build environment part of the workflow.

Previously, reliable production builds depended on a dedicated machine. I built the Zig cross-compilation workflow: the Nix shell provided the Rust toolchain, Zig, and cargo-zigbuild; the release task targeted x86-64 Linux with musl.

The team used the Nix/Zig Linux release-build workflow, and the dedicated machine was retired.

Start the system together.

At the repository level, devenv coordinated application processes using their project task commands and included supporting local services. This addressed the other part of the original problem: bringing multiple services up together.

I used whole-system startup through devenv up. The team used the project environments and task workflows; wider adoption of whole-system startup is unknown.

Less friction between projects.

  • Fewer version conflicts
  • Easier switching between projects
  • Fewer setup questions
  • Easier changes spanning services

These were changes I observed in the team’s day-to-day work. The monorepo brought the code together; the environments and workflows made it easier to work across that code.

Start a conversation