ess/README.md

261 lines
8.4 KiB
Markdown
Raw Normal View History

# ess (env sample sync)
2022-11-26 16:05:23 +00:00
2023-06-08 13:56:58 +00:00
[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://app.gitter.im/#/room/#env-sample-sync-dev:gitter.im)
2024-10-25 20:03:42 +00:00
Automatically keep `env.sample` files in sync with `.env`
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
---
2022-11-26 16:05:23 +00:00
`ess` transforms environment files containing secrets (e.g. `.env`, `.envrc`) into sample environment files (e.g.
2024-01-20 00:23:56 +00:00
`env.sample`) that may be safely checked into git.
2022-11-26 16:05:23 +00:00
2024-01-20 00:23:56 +00:00
`ess` may be run manually by running the cli executable, or automatically by installing the pre-commit hook with `ess install`
in any git repository. Installing `ess` as a git hook ensures that project environment files are automatically and safely
revision controlled when they change.
2022-11-26 16:05:23 +00:00
2024-01-20 00:23:56 +00:00
Doing so allows environment configurations to be shared across teams without leaking secrets.
## How it works
2024-01-20 00:23:56 +00:00
By default, `ess` checks the local directory for environment files named `.env`. The env file name is controlled by
the `--env-file` switch. Next, the environment file is parsed for environment variables. Environment variables
2024-01-20 00:23:56 +00:00
may be of the following forms:
```
# Standard environment variables
FOO=bar baz
FOO="bar baz"
FOO='bar baz'
# Envrc environment variable
export FOO=bar baz
export FOO="bar baz"
export FOO='bar baz'
```
By default, variable values are replaced with innert values named after the variable, e.g. `FOO=bar` is replaced by `FOO=<FOO>`.
Example values may be provided with the `--example` switch, e.g. `--exmaple=FOO="enter your foo here"` will set `FOO`'s
value as follows `FOO="enter your foo here"` in the sample file.
2024-01-20 00:23:56 +00:00
Finally, when all variables are replaced, the sample file is written with the sanitized variable values, along with all
2024-01-20 00:23:56 +00:00
non-variable strings from the file. By default the sample file is named `env.sample`, which is controlled by the `--env-sample`
switch.
2024-01-20 00:23:56 +00:00
Because `ess` permits non-variable strings in environment files, it means that both comments and script code (in the case
of `.envrc` files) is included in environment sample files. This allows environment files to not only be checked into git, but
documented with comments.
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
# Installation & Usage
`ess` can be run in three ways:
2023-05-29 16:54:11 +00:00
1. Manually
2. As a native git-hook
3. As a [pre-commit plugin](https://pre-commit.com/#install) (a utility for organizing pre-commit hooks)
## Installation
Installation is required to run `ess` manually, or as a native git hook. See [pre-commit configuration]
2023-09-09 07:49:30 +00:00
(#running-as-a-pre-commit-plugin) for pre-commit usage.
2023-05-29 16:54:11 +00:00
**Install from the releases page**
Download [the latest release](https://github.com/acaloiaro/ess/releases/latest) and add it to your `$PATH`.
2023-05-29 16:54:11 +00:00
**Install with `go install`**
2022-11-26 16:05:23 +00:00
```bash
go install github.com/acaloiaro/ess@latest
2023-05-29 16:54:11 +00:00
```
2022-11-26 16:05:23 +00:00
2023-09-09 07:49:30 +00:00
**Nix Flake**
This application may be added as a flake input
**flake.nix**
```nix
inputs.ess = {
url = "github:acaloiaro/ess";
2023-09-09 07:49:30 +00:00
inputs.nixpkgs.follows = "nixpkgs";
};
```
**configuration.nix**
```nix
users.users.<USERNAME>.packages = [
...
inputs.ess.packages.${system}.default
2023-09-09 07:49:30 +00:00
];
```
2024-10-10 17:51:28 +00:00
Or simply run directly
2023-09-09 07:49:30 +00:00
```bash
nix run github:acaloiaro/ess
2023-09-09 07:49:30 +00:00
```
2023-05-29 16:54:11 +00:00
## Running manually
`ess` can be run with no arguments to use defaults.
2023-05-29 16:54:11 +00:00
**Sync `.env` with `env.sample`**
```bash
ess
2022-11-26 16:05:23 +00:00
```
2023-05-29 16:54:11 +00:00
**With a non-default `.env` and `env.sample` location**
2022-11-26 16:05:23 +00:00
```bash
ess --env-file=.env-file-name --sample-file=env-sample-file-name
2023-05-29 16:54:11 +00:00
```
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
**Provide example values for variables**
By default, `ess` uses the name of environment variables in `<brackets>` as example values in `env.sample`,
2023-09-09 07:49:30 +00:00
e.g. `FOO=secret value` is replaced with `FOO=<FOO>`. This behavior is customizable wit the `--example` flag.
2023-05-29 16:54:11 +00:00
Add custom examples for variables `FOO` and `BAR`.
```bash
ess --example=FOO="must be a valid UUID" --example=BAR="bars must be a positive integer"
2023-05-29 16:54:11 +00:00
```
The above invocation yields the following `env.sample`
```bash
FOO=must be a valid UUID
BAR=bars must be a positive integer
```
## Running as a native git-hook
To add `ess` as a pre-commit git hook in a git repository, run:
2023-05-29 16:54:11 +00:00
```bash
ess install
2022-11-26 16:05:23 +00:00
```
This installs `ess` as a pre-commit git hook with default arguments.
2023-05-29 16:54:11 +00:00
The `install` command supports all [command flags](#command-flags).
If you need to change `ess` flags, simply run `ess install` again with the desired flags and
2023-09-09 07:49:30 +00:00
choose the overwrite [o] option when prompted what to do with the existing pre-commit hook.
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
## Running as a pre-commit plugin
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
This utility can be used as a [pre-commit plugin](https://pre-commit.com/#install)
2022-11-26 16:05:23 +00:00
## Add configuration
```bash
cat <<EOF >.pre-commit-config.yaml
2022-11-26 16:05:23 +00:00
repos:
- repo: https://github.com/acaloiaro/ess.git
2025-04-12 14:25:05 +00:00
rev: v2.18.0
2022-11-26 16:05:23 +00:00
hooks:
- id: ess
2022-11-26 16:05:23 +00:00
EOF
pre-commit install
2023-05-29 16:54:11 +00:00
git add .pre-commit-config.yaml
```
See [pre-commit configuration examples](#pre-commit-configuration-examples) for additional pre-commit documentation.
# Background
2023-09-09 07:49:30 +00:00
It's important to document the environment variables required to run applications, both in production and development. A
great way to do so is with `env.sample` files, but sample files tend to get out of date very quickly.
2023-05-29 16:54:11 +00:00
2024-10-10 17:51:28 +00:00
For example, let's say you're adding a new feature to your application, and it requires the variable `FOO` to be set.
2023-09-09 07:49:30 +00:00
While you're developing locally, you likely have a `.env` file that looks something like:
2023-05-29 16:54:11 +00:00
```bash
APPLICATION_SECRET=supersekrit
# I got this FOO from the detailed process documented at: http:://wiki.example.com/how_to_get_a_foo
FOO="My super secret value for foo"
```
2023-09-09 07:49:30 +00:00
Working on large teams, it's common to share these `.env` files somewhere secure where all developers have access to
them. Retrieval is often integrated into application startup and/or bootstrap processes.
2023-05-29 16:54:11 +00:00
2023-09-09 07:49:30 +00:00
But working on open source projects or teams with less trust and less shared infrastructure, it's more common to share
an `env.sample`. `ess` automatically keeps the sample file in sync with `.env`, so you don't have to. Your
2023-09-09 07:49:30 +00:00
`.env` file stays the same, and is automatically converted to the following `env.sample`:
2023-05-29 16:54:11 +00:00
```bash
APPLICATION_SECRET=<APPLICATION_SECRET>
# I got this FOO from the detailed process documented at: http:://wiki.example.com/how_to_get_a_foo
FOO=<FOO>
2022-11-26 16:05:23 +00:00
```
2023-05-29 16:54:11 +00:00
It's even possible to provide default/example values for every environment variables with the `--example` [flag](#command-flags).
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
## Command Flags
2022-11-26 16:05:23 +00:00
2023-09-09 07:49:30 +00:00
| Name | Description | Example | Default |
| --------------- | --------------------------------------------------- | --------------------------------------------------------- | ----------------------------- |
2023-05-30 02:07:35 +00:00
| `--env-file` | The name of the environment file | `--env-file=.secrets` | `--env-file=.env` |
2024-10-25 20:18:58 +00:00
| `--debug` | Enable debugging | `--debug` | `false` |
| `--skip-git-add` | Skip performing `git add` after syncing | `--skip-git-add` | `false` |
2023-05-30 02:07:35 +00:00
| `--sample-file` | The name of the sample environment file | `--sample-file=secrets.example` | `--sample-file=env.sample` |
2024-10-25 20:18:58 +00:00
| `--example` | Provide examples for specific environment variables | `--example=FOO="Example FOO" --example=BAR="Example BAR"` | `--example=VAR=<VAR>` |
2022-11-26 16:05:23 +00:00
2023-05-29 16:54:11 +00:00
## Pre-commit Configuration Examples
2022-11-26 16:05:23 +00:00
### Default configuration
```yml
repos:
- repo: https://github.com/acaloiaro/ess.git
2025-04-12 14:25:05 +00:00
rev: v2.18.0
2022-11-26 16:05:23 +00:00
hooks:
- id: ess
2022-11-26 16:05:23 +00:00
```
### Customize `.env` and `env.sample` paths
```yml
repos:
- repo: https://github.com/acaloiaro/ess.git
2025-04-12 14:25:05 +00:00
rev: v2.18.0
2022-11-26 16:05:23 +00:00
hooks:
- id: ess
2022-11-26 16:05:23 +00:00
args: ['--env-file=.env_file', '--sample-file=env_file.sample']
```
### Customize variable example values
2024-10-10 17:51:28 +00:00
Sometimes environment variables need to conform to specific formats, and it's necessary to provide better documentation.
2023-09-09 07:49:30 +00:00
For this reason, environment variable examples may be provided in lieu of the default behavior, which is to use the
environment variable name surrounded by `<brackets like this>` in sample files.
2022-11-26 16:05:23 +00:00
```yml
repos:
- repo: https://github.com/acaloiaro/ess.git
2025-04-12 14:25:05 +00:00
rev: v2.18.0
2022-11-26 16:05:23 +00:00
hooks:
- id: ess
2022-11-26 16:05:23 +00:00
args: [--example=FOO="Provide your foo here", --example=BAR="You can fetch bars from https://example.com/bars"]
```
2024-01-20 00:23:56 +00:00
Example environment file
2022-11-26 16:05:23 +00:00
`.env`
```
FOO=the_value_of_my_secret_foo
BAR=the_value_of_my_secret_bar
```
Example sample file output
`env.sample`
```bash
FOO=Provide your foo here
BAR=You can fetch bars from https://example.com/bars
```