Because it's time to do dev on our stuff!
If you're on a Mac, you can use Homebrew to install Devon:
brew tap redbubble/devon
brew install devon
You can download pre-compiled binaries from the Releases page. There are OSX and Linux archives for download, as well as RPM and DEB packages if that's your flavour.
You can of course clone this repo using git clone [email protected]:redbubble/devon
and build Devon yourself if you wish.
devon start
starts the local application (whose repo is the current working directory) in Development mode, with its dependencies in Dependency mode (see Modes).
devon start <repo-name>
starts the named application in Development mode, with its dependencies in Dependency mode (see Modes).
--mode
, -m
: Specify the mode. Default: development
--skip
, -s
: Names of any apps you don't want to start. Can be specified multiple times.
--verbose
, -v
: Print some more information about what's happening.
You can run applications in various modes, to suit particular dev/test scenarios. Want to run the web app without the background workers? Make a mode for it. Want to run both? Another mode. Using placeholder data instead of calling out to a dependency? You guessed it: add a mode!
In general, most apps should have at least two basic modes:
development
, which is used when you are actively making changes to an application, anddependency
, which is used when you need an app to be running (e.g. to satisfy a runtime dependency of an app you're working on), but you aren't planning on making changes to it.
See some examples in example.yaml
in the root of this repo.
To start an app with Devon, you will need a config file called devon.conf.yaml
in that app's Git repo. It should look something like this:
modes:
development:
start-command: ["bundle", "exec", "rails", "server"]
# `working-dir` is the directory where `start-command` and `stop-command`
# should be executed. Specify it relative to the repository root.
# Defaults to the repository root if unspecified.
working-dir: app
# Set any environment variables required by this mode
env:
- name: EXAMPLE_SERVICE_URL
value: https://example.com/
dependencies:
# `name` is the name of the dependency's git repo.
# `mode` is the name of the mode the dependency should be started in.
- name: some-app
mode: some-mode
- name: redbubble
mode: dependency
dependency:
start-command: ["dev/up.sh"]
stop-command: ["dev/down.sh"]
dependencies:
- name: some-app
mode: some-mode
- name: some-other-app
mode: maybe-some-other-mode
This is an extension of the idea behind the dev/up.sh
convention we've had for a long time now. Devon attempts to put a common interface on starting apps, so that if I'm hacking on an app for the first time, I don't have to worry about how to start it.
Just as we document our build-time dependencies with tools like bundler
or npm
, we should document our runtime dependencies. These are just as important when it comes to running the application.
Documentation can give us certainty. Once we have certainty (and consistent formatting), we can automate.
Devon's conventions currently take the form of stated assumptions, as documented below. The aim is to gradually introduce some flexibility around those assumptions (e.g. by making them configurable), but keep defaults that make sense, so you don't have to configure every little thing in order to get started.
By default, that place is ~/src
. You can override that by creating a config file called devon.yaml
in your ~/.config/devon
directory, with contents like this:
source-code-base-dir: /path/to/your/code
I (Lucas) can't think of a sane use case for that, so I'm pretty sure this assumption is safe.
Devon starts applications by running commands somewhat naively, waiting for each command to finish before starting the next. This means that applications can interrupt the starting process if they run in the foreground, instead of doing what we expect and starting a daemonised process. Because they never exit, subsequent applications wouldn't be able to start.
At the moment, a dependency relationship means "A depends on B to work properly, but A can start even if B isn't running." This is optimistic, since there is nothing stopping A from crashing if B is not available at startup.
This probably needs fixing with an actual dependency graph implementation -- the current implementation just builds a list that includes all the dependencies, with no information about which apps depend on which others. Hence, there's no reliable way to figure out what to start first.
This repo is set up to use pre-commit
to share Git pre-commit hooks. The config is in .pre-commit-config.yaml
. It's currently set up to check a few essential things:
- Files end with \n
- No trailing whitespace
- YAML formatting
- Golang formatting
This is to help prevent CI failures when Lucas forgets to run go fmt
before pushing his commits. You can use it too, but you don't have to. Install with brew install pre-commit
, then run pre-commit install
in the root of this repo.
See https://pre-commit.com for more info.
We use Goreleaser to create releases of Devon. There are a couple of requirements for it to work:
- You must have Goreleaser installed. You can get it from Homebrew.
- You must have the
GITHUB_TOKEN
environment variable set to a GitHub Personal Access Token.
Once you have those things in place:
-
Bump the
VERSION
variable inMakefile
in a way that fits with Semantic Versioning. -
Invoke the
release
target usingmake
:make release
-
Tell the world about the newly released magnificence! #eng-devon on Slack is a good place, as is #engineering. If you're especially proud, you could announce it in #released as well!