Algolia and Gitlab CI/CD

How to automate building and pushing the search-index

Thursday, March 19, 2020

Still working on my blog workflow I was looking for a way where I can work on my blog from my laptop while I’m on the road, from my desktop at home and even from my iPad.

The Hugo theme “Clean White” uses Algolia for searching the site. The documentation of the theme clearly explains how to build and upload the search-index but that would make my setup less portable.

Local build

The documentation of the Clean White Hugo theme has its own chapter on how to setup the Algolia site search.

The setup expects npm installed and that you have a working Algolia account.

The first three steps are required for each environment.

1) Setup NPM

Go to your Hugo project directory and perform the following commands:

npm init
npm install atomic-algolia --save

‘npm init’ creates the file ‘package.json’ and requires your input.

2) Add NPM script to ‘package.json’

Open up the newly created file package.json, add the following line in the ‘scripts’ section:

"algolia": "atomic-algolia"

The partial ‘package.json’:


  "scripts": {
    "algolia": "atomic-algolia",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

3) Build the site

Building the Hugo site.

hugo

The site is created in the directory ‘public’. The Hugo theme also generates the file ‘algolia.json’ in the root of that directory. You need its location in the next step.

4) Create ‘.env’-file

Create a new file in the root of your Hugo project called .env, and add the following contents:

ALGOLIA_APP_ID={{ YOUR_APP_ID }}
ALGOLIA_ADMIN_KEY={{ YOUR_ADMIN_KEY }}
ALGOLIA_INDEX_NAME={{ YOUR_INDEX_NAME }}
ALGOLIA_INDEX_FILE="public/algolia.json"

Replace the ‘{{ YOUR_* }}’ variables with the data from your Algolia configuration.

5) Push the index to Algolia

The following command pushes your index to Algolia.

npm run algolia

6) Enable Algolia search in your config

Add the following variables to your Hugo config so the search page can get access to algolia index data in the cloud:

algolia_search = true
algolia_appId = {{ YOUR_APP_ID }}
algolia_indexName = {{ YOUR_INDEX_NAME }}
algolia_apiKey = {{ YOUR_ADMIN_KEY }}

Replace the ‘{{ YOUR_* }}’ variables with the data from your Algolia configuration.

My partial ‘config.toml’


  # algolia site search
  algolia_search = true
  algolia_appId = "TUA18W3MMF"
  algolia_indexName = "prod_yourwebsite"
  algolia_apiKey = "e467301c0d283b53e48127c5c2c56419"

Automating local vs remote

In the local setup steps 3 and 5 need to be repeated each time something changes in your content. Steps 1, 2, 4 and 6 are just for the initial setup.

These local steps create a lot of extra files on your system. This has a smell to it but for now I just want to reproduce the same workflow on Gitlab. ELMO

The automated steps

To automate these steps on Gitlab steps 1, 2, 3 and 5 need to be performed on each build. Step 4 and 6 cover the setup of the Algolia credentials.

The image used by the Gitlab runner is a very basic. In a previous post I described my experiences with these limitations so I came prepared 😉.

NPM

On my local workstation Node.js and the Node Package Manager (npm) were already installed. It needs to be added to the base Hugo image provided by Gitlab.

The installation and configuration of npm and the algolia module is handled in the ‘before_script’ section of the ‘.gitlab-ci.yml’:


before_script:
  - apk add npm
  - npm init -y
  - npm install atomic-algolia --save

This covers the npm requirement the first step and the first part of step 2.

Automatically add-atomic-algolia.sh

In the second part of step 2 we added the algolia module to the file ‘package.json’. To add the line I used ‘sed’.

Sed is not installed by default so we add anothe line in the ‘before_script’ section:


before_script:
  - apk add npm
  - npm init -y
  - npm install atomic-algolia --save
  - apk add sed

The following sed-command adds the algolia module line to the ‘scripts’ section of the file ‘package.json’:

sed -i 's|"test"|"algolia": "atomic-algolia", "test"|' package.json

NOTE: The ‘sed’-syntax on Linux is different from its syntax on a Mac. To test it on your Mac: sed -i '.tmp' 's|"test"|"algolia": "atomic-algolia", "test"|' package.json

I tried to add the sed-comand to the CI/CD configuration file, that was not succesfull. Something with quoting the command on the commandline, my workaround was to create a one-line bash script with just the the sed-command.

The bash-script is called from the ‘script’ section of the ‘.gitlab-ci.yml’:

...
before_script:
  - apk add npm
  - npm init -y
  - npm install atomic-algolia --save
  - apk add sed
...
pages:
  script:
    - ./add-atomic-algolia.sh
...

Full GitLab CI/CD

In the full version of our CI/CD configuration file we added the step 3 (building the site) and step 5 (pushing the algolia index) in the ‘script’ section.

The complete file ‘.gitlab-ci.yml’:

# All available Hugo versions are listed here: https://gitlab.com/pages/hugo/container_registry
image: registry.gitlab.com/pages/hugo:latest

variables:
  GIT_SUBMODULE_STRATEGY: recursive

before_script:
  - apk add npm                         # Install Add Node.js and npm
  - npm init -y                         # Initialize the Node.js environment
  - npm install atomic-algolia --save   # Instal the atomic-algolia module
  - apk add sed                         # Install GNU sed

pages:
  script:
    - ./add-atomic-algolia.sh           # Add the algolia module to 'package.json'
    - hugo                              # Build the site
    - npm run algolia                   # Push the Algolia search-index
  artifacts:
    paths:
      - public
  only:
    - master

Final words

The initial goal was to automate the local manual steps to generate and upload the algolia-index. Did we succeed in that? I guess “yes” but along the way there was this feeling of a sub-optimal solution.

Things where I have my doubts:

  • Is npm only used to upload an optimized version of the Algolia index? Maybe consider using a Go-based library?
  • Can the atomic-algolia module optimise the index in this setup?

Despite the doubts it just works, I now have a CI/CD setup that can just upload changes and Gitlab CI/CD handles the rest.