title | description |
---|---|
Development environments |
Getting set up to work on new projects |
- New working environments are set up quickly, easily, and consistently (ideally with a single command).
- Team- or project-wide configuration changes are rolled out without needing a lot of communication and coordination.
- Projects adopting favored technologies leverage common, simple set-up.
- Developers using common tools (mac, bash, homebrew, nvm...) get productive without any special set-up.
- Developers choosing less common tools are still productive, if necessary using the basic set-up as a guide.
- Projects default to configuration values that are appropriate for development (just as they run in "development" mode by default).
- Both local and containerized development are supported, with minimal duplication.
- Sensitive values are never committed to repositories, whether open- or closed-source.
- Other things being equal, less configuration, simpler-setup, and fewer dependencies are better than more.
Setup tooling is optimized for a default set of tools:
- Mac computers
bash
shell- Homebrew for installing and managing supporting services
- Docker for containerization
- asdf for managing ruby and nodeJS versions
- hokusai for managing deployed applications
- VSCode for text editing
- awscli for AWS operations
Developers who find other tools compelling may need to adapt setup procedures to their choices. For the sake of simplicity, we avoid making setup tooling heavily conditional on local choices.
The shared setup script🔒 installs these tools, and individual projects' setups may depend on them.
These choices can and should be improved (by RFC-style pull request), but care should be taken to update any dependent projects.
Project's READMEs should clearly document the commands necessary for fresh set-up, ideally just reviewing and
running a ./bin/setup
script (or whatever is idiomatic for that stack). E.g.:
Review the
bin/setup
script and run it or the equivalent steps for your environment.
The script should:
- install dependencies such as data stores
- install necessary language runtimes/versions
- initialize configuration with values that are appropriate for development (ideally none)
- install packages (rubygems, node modules, etc.)
- create and seed databases, if appropriate
- ideally be idempotent (i.e., re-running setup should work to update an existing environment)
- be clearly organized and commented, so it can serve as a guide in incompatible environments
By convention, projects load configuration values from both:
- a
.env.shared
file with sensitive and common configuration values - a
.env
file with any developer-specific overrides (or empty)
These files are excluded from source-control. The setup command initializes them, updating .env.shared
from a
private S3 location.
Local ruby development depends on the foreman
utility and a .foreman
file
(e.g.) to respect these files. Local node.js development
depends on node-foreman and the --env
argument
(e.g.).
Docker-based development respects these files by listing both in docker's env_file
property
(e.g.).
To update shared configuration values, first ensure that you have the latest version of .env.shared
from s3:
aws s3 cp s3://artsy-citadel/<project>/.env.shared ./
Then simply modify and re-upload it to its shared location as
.env.<project>
. E.g.:
aws s3 cp .env.shared s3://artsy-citadel/<project>/.env.shared
If you are adding a new configuration value and need it reflected on remote environments, check this doc