Skip to content
This repository has been archived by the owner on Apr 28, 2023. It is now read-only.
/ devon Public archive

A tool to help you *dev on* your stuff

License

Notifications You must be signed in to change notification settings

redbubble/devon

Repository files navigation

Devon, for starting systems in dev

Because it's time to do dev on our stuff!

Installation

Homebrew

If you're on a Mac, you can use Homebrew to install Devon:

brew tap redbubble/devon
brew install devon

Download release from GitHub

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.

Compile from source

You can of course clone this repo using git clone [email protected]:redbubble/devon and build Devon yourself if you wish.

Usage

In an application repo

devon start

starts the local application (whose repo is the current working directory) in Development mode, with its dependencies in Dependency mode (see Modes).

From another directory

devon start <repo-name>

starts the named application in Development mode, with its dependencies in Dependency mode (see Modes).

Options

--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.

Modes

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:

  1. development, which is used when you are actively making changes to an application, and
  2. dependency, 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.

Configuring your application

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

Influencing ideas

Apps should document how to run them in dev

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.

Apps should document their dependencies on other apps

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.

The best documentation can be used for automation, too!

Documentation can give us certainty. Once we have certainty (and consistent formatting), we can automate.

Convention over (but not instead of!) configuration

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.

Important assumptions

All app repos live in the same place

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

One app should never be started in 2 modes at the same time

I (Lucas) can't think of a sane use case for that, so I'm pretty sure this assumption is safe.

Applications run in the background

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.

All dependency relationships are the same

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.

Development

Trello board

Pre-commit hooks (optional)

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.

Releasing

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:

  1. Bump the VERSION variable in Makefile in a way that fits with Semantic Versioning.

  2. Invoke the release target using make:

    make release
    
  3. 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!