Dev Environment Protocol

What Every Dev Environment Should Provide

Regardless of underlying technology, each dev environment should ideally provide a set of commands that, without the need for arguments, achieve common goals for doing development.

There are two groups of scripts: those that setup the environment (which I call the Foundational Core) and those that are using during development (which I call the Workspace).

Foundational Core - Setting Up the Environment

The dev environment itself should be scripted, and this should be distinctly managed from dev tasks. For example, the scripts to start/stop the dev environment itself should not be in bin/.

“Sustainable Dev Environments with Docker and Bash” prescribes the dx/ directory to hold the scripts for managing the dev envrionment. These scripts support a common workflow for vituralized environments: build, start, execute tasks, shutdown:

G Shutdown     Shutdown         dx/stop   Build     Build         dx/build   Start     Start         dx/start   Build->Start Exec     Execute         dx/exec   Start->Exec Exec->Shutdown DevCommands     Development         bin/\*   Exec->DevCommands

Diagram showing Build (dx/build) leading to Start (dx/start), leading to Execute (dx/exec). Execute connects to Development (this bin/* commands discussed above), but also leads to Shutdown (dx/stop)

Command
Purpose
Purpose Notes
dx/build

Build or download anything needed.

Build or download anything needed.

The team should determine the cadence for running this command. Everyone would naturally run it once to first set up their dev environment, however it may be desriable to run it many times per week to ensure any needed libraries or artifacts are up to date.

dx/start

Start up the environment and services

Start up the environment and services

This should do whatever is needed to start up the environment for the app, including any ancillary services like dev databases. This would not necessarily handle app-specific initialization of the contents or behavior of the service. It would merely make them available.

dx/exec «command»
dx/exec \
  «command»

Run a command in the dev environment

Run a command in the dev environment

This assumes a virtualized environment where commands are run inside a container or virtual machine. If the dev environment is the local computer, this is not needed.

dx/stop

Shutdown the environment

Shutdown the environment

This powers down any services and virtualized environments.

Workspace - During Development

Once the Foundational Core (dev environment) is set up, the scripts in the Workspace will automate common tasks. They are ideally managed as command-line scripts, as this affords the widest variety of integrations with other tools.

These support a common developer workflow of setup, iterate building & running, then test. Note that some frameworks (such as Ruby on Rails) provide scripts for you, and you should use those in lieu of these.

G cluster_dev       Iterate             bin/dev       Setup     Setup         bin/setup   Build     Build         bin/build   Setup->Build Run     Run         bin/run   Build->Run Run->Build Test     Test         bin/ci   Run->Test

Diagram showing Setup (bin/setup) leading to an Iterate cycle. Iterate contains two nodes that point back and forth to each other: Build (bin/build) and Run (bin/run). The Iterate box then leads to Test (bin/ci).

Command
Purpose
Purpose Notes
bin/setup

Perform any app-specific setup

Perform any app-specific setup

This should not perform dev environment-specific setup. This script should make needed assumptions about the dev environment (e.g. programming language runtimes, OS versions). It can optionally check that these assumptions are met and provide an error message.

bin/build

Build any needed artifacts

Build any needed artifacts

This should run any needed dev tools one time only. This can be optional, depending on the underlying technology. Examples might be producing a static website from tempaltes, or compiling CSS.

bin/run

Run the system locally

Run the system locally

This should only run what is needed for the system to work. It should not run any dev tools, automated builds or tests.

bin/ci

Run tests and quality checks

Run tests and quality checks

This should run everything needed to assure the app is safe to deploy. This includes automated tests, linters, security checks, etc.

bin/dev

Run the app in dev mode, rebuilding artifacts as needed.

Run the app in dev mode, rebuilding artifacts as needed.

This should build and start the app for local development, including any automatic re-building or re-loading. A basic example of this, using bin/run and bin/build would be:

trap killgroup SIGINT

killgroup() {
  echo "Killing everything..."
  kill 0
}

bin/build &
bin/run &
wait

Note that this may be radically different depending on the underlying technology. For example, Ruby on Rails provides its own script for this that achieves the same goal without using underlying scripts.

trap killgroup SIGINT

killgroup() {
  echo "Killing everything..."
  kill 0
}

bin/build &
bin/run &
wait