How to keep your .env and .env.example of your Laravel application up to date

Keep your .env and .env.example in sync automatically with git hooks, so new developers never miss required values.

Zacharias Creutznacher Zacharias Creutznacher

Since the .env file is not under version control, it often happens that developers are missing new values, added by other developers, when they pull the latest version. Also the .env.example is often totally out of date, because the team forgot to add new values to it. That's a pain, when a new developer joins the team and tries to set up the project. Laravel offers a default to all env function calls, but thats often not enough. Sometimes you really want to make sure a env variable exists and the developer explicitly defines a value for it. Often .env files get shared around, sent via email or something like that. But this is not really a generic and solid solution. Best would be, if the .env.example would just stay up to date! Let's try to configure some githooks to ensure our .env and .env.example will never ever be outdated anymore!

#Install envy

To compare .env and .env.example files, we'll use a github package called envy, a great package developed by the awesome guys from worksome!

Install it via composer

 1composer require worksome/envy --dev

Create config file

 1php artisan envy:install

Now make sure .env and .env.example are listed in the environment_files variable in the config/envy.php

 1'environment_files' => [
 2    base_path('.env.example'),
 3    base_path('.env'),
 4],

#Setting up the git hooks

Add a shared git hook directory

We need to add some git hooks to our repository. But since the whole .git directory (which contains the default git hooks directory used by git) is also not under version control, we need to create a new directory, which we can add to git, cause for sure we want to share our hooks with the whole team!

 1cd myproject; mkdir .githooks

Add the hooks

The idea is to tell git to compare the both env files before one tries to commit and also after somebody pulls new changes. That means we need to add two git hooks, the pre-commit and the post-merge hooks. So if one tries to commit and forgot to add a new env variable to .env.example an error occurs and also after somebody pulls, and a new variable was merged to .env.example the developer gets notified that he/she should add this variable to his/her .env file.

 1touch .githooks/pre-commit; touch .githooks/post-merge

Since we use the same script in the pre-commit and post-merge hook, we add a new folder .githooks/scripts and put there the script which we then call inside both hooks (make sure to make them all executable with chmod +x).

 1mkdir .githooks/scripts; touch .githooks/scripts/envy-check

Apply the envy-check to the hooks

Now paste the following code to your envy-check script

 1#!/bin/bash
 2
 3SAIL=vendor/bin/sail
 4EXECUTOR=$SAIL
 5
 6SAILCHECK=$($SAIL php -v 2>&1 >/dev/null)
 7
 8if [[ $SAILCHECK == *"Sail is not running."* ]] || [[ $SAILCHECK == *"Docker is not running."* ]]; then
 9    EXECUTOR=php
10fi
11
12#xargs to remove whitespace
13CHECK=$($EXECUTOR artisan envy:sync --dry | xargs)
14
15RED='\033[0;31m'
16NC='\033[0m' # No Color
17
18if [ "$CHECK" != "There are no variables to sync!" ]
19then
20    printf "${RED}Some env variables are missing, please add them to the specified file before you go on:\n"
21    printf "$CHECK\n${NC}"
22    # exit 1 cancels the commit...
23	exit 1
24fi
25
26# exit 0 continues the commit...
27exit 0

Call the script inside the hooks

Call the envy-check script inside your pre-commit and post-merge hooks (make sure your hooks and the envy-check scripts are executable).

 1nano .githooks/pre-commit
 2nano .githooks/post-merge
 3
 4Paste the following content:
 5-----------
 6#!/bin/bash
 7
 8./.githooks/scripts/envy-check

Ensure that your hooks are used by the whole team

There is one problem left... Just adding a .githooks directory and add there, some script does not tell git to use these. Therefore we create a .gitconfig file and add the following lines:

 1cd myproject; nano .gitconfig
 2-------
 3[core]
 4hooksPath = .githooks

Now to make sure that git is using our defined .gitconfig we need to make some configuration. For this purpose there is noting better than a good old makefile. Just append these lines to your existing makefile or create a new one:

 1nano Makefile
 1enable-git-hooks::
 2	git config --local include.path ../.gitconfig

make sure to use a real tab indent here, important!

The make package should be on quite every linux-based OS, but if it's not installed on your system, go ahead and install it with sudo apt-get install make.

Now the only thing you need to do is tell your team and new joining developers to run this one-time command: cd myproject; make enable-git-hooks

Exclusion

Basically all default env vars which are maybe not predefined in the default .env file are getting excluded. Just check the exclusions array in the config/envy.php. If you for some reason also want to exclude some env vars, just list em here. Also notice, that envy as default only checks env vars in config/*.php, which is the best practice location to put your env vars. Actually you should not use env vars directly in the code, cause of caching issues.

Example - Pre-Commit Hook

Now lets asume you worked on a new feature which introduces a new env variable called FOO which is used in some of your config files. You finally finished the feature and want to commit, but forgot to add the env varbiable to .env.example. You type git commit -am "New Feature" and greate you cant commit and you get notified that some vars need to be added to .env.example:

Example - Post-Merge Hook

Also in reverse, if now a other team members pulls the lates code (he will not have the FOO env variable set), he gets notified, that there is a new env variable and he/she should define it in the .env.