Further to my earlier post on automating deployment of my blog I found a small flaw with my method and have decided to fix it.

My current approach uses Jekyll's --unpublished to control if unpublished posts are included or not. The problem with this is that both versions of the site include all the static content, regardless of whether it is required by the "public" facing version or not.

That is not ideal. To rectify this I have used the recipe suggested on the Jekyll Environments documentation page:

To switch part of your config settings depending on the environment, use the build command option, for example --config _config.yml,_config_development.yml. Settings in later files override settings in earlier files.

Jekyll configuration changes

I have added a new directory called unpublished to my assets directory and changed the exclude list in _config.yml to include it:

exclude:
  - README
  - Gemfile
  - Gemfile.lock
  - '*.bash'
  - assets/unpublished

For the "private" blog I have created a new configuration file, called _config-production-private.yml and in it specific both that unpublished posts should be included (removing the need to specify the command-line option) and NOT included unpublised assets in the exclude list:

unpublished: True
exclude:
  - README
  - Gemfile
  - Gemfile.lock
  - '*.bash'

These changes allow me to switch between generating sites with/without the unpublished posts by either specifying --config _config.yml,_config-production-private.yml or --config _config.yml(or leaving it off altogether as this is the default).

Deployment script changes

Part of configuration management solution I had devised, previously, used a simple bash script. This script takes 1 argument, the destination directory to generate the site into and passed any other arguments straight through to the jekyll command.

I modified this script to check for the JEKYLL_ENV environment variable and if there is a matching _config-$JEKYLL_ENV.yml file automatically add it to the default and pass to Jekyll with --config.

It does some sanity checking and installs Jekyll, Bundler and any other required gems first but this is the relevant part (this used to be a single line jekyll build -d $DEST_DIR "$@":

# Figure out if there's an environment-specific configuration file
if [[ -z $JEKYLL_ENV ]]
then
		# This is Jekyll's built in default, but we're about to use
		# this to test for an extra configuration file (so we might
		# want to be able to have a 'development' one) and it can
		# help to be explicit.
		JEKYLL_ENV=development
fi

echo "Building in $JEKYLL_ENV environment."
if [[ -e _config-$JEKYLL_ENV.yml ]]
then
		configs=_config.yml,_config-$JEKYLL_ENV.yml
else
		configs=_config.yml
fi
echo "Using configuration file(s): $configs"

jekyll build --config $configs -d $DEST_DIR "$@"

Now the deployment of the public/private version is simply controlled by setting JEKYLL_ENV="production" or JEKYLL_ENV="production-private".