Introduction

This blog post is a follow up on my previous post which was talking about the architecture of that website. We are going to talk about CI/CD on gitlab and how to have a continuous integrations with Hugo and Workers site.

Gitlab

Before diving into the implementation steps, let’s take a look to the public documentation to understand better of CI/CD pipeline works on Gitlab. That article describe it.

As per that doc, the first step is to create a .gitlab-ci.yml file that you store in your repository’s root directory.

Let’s see how to do it and describe it step-by-step.

gitlab-ci yaml file

In my case I create the following file .gitlab-ci.yml:

image: "ubuntu:latest"

before_script:
    # Update and upgrade only the most important packages
    - apt-get update && apt-get dist-upgrade -y
    # Brew install for Hugo
    - apt-get install -y build-essential curl file git locales
    - locale-gen en_US.UTF-8
    - useradd -m -s /bin/bash linuxbrew
    - echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers
    - su linuxbrew sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
    - test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
    - echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
    - brew install hugo
    #Nodejs install
    - curl -sL https://deb.nodesource.com/setup_13.x | bash -
    - apt-get install -y nodejs
    #Check that we have the latest versions
    - npm version
    - hugo version
    #Install of wrangler
    - npm i @cloudflare/wrangler
    
staging:
    stage: test
    script:
        - CF_API_TOKEN=$CF_API_TOKEN npm run publish-staging
    except:
        - master

production:
    stage: deploy
    script:
        - CF_API_TOKEN=$CF_API_TOKEN npm run publish
    only:
        - master

Let’s have a look closer.

Into before script instruction I mentionned all dependencies needed to run npm, wrangler and hugo. I chose to start each time with a new docker image without any of those tools installed. By doing that, I am sure that I am running the latest version of those tools. All ressources used for that are listed here

Next part of the file is the definition of stages. Here I defined 2 stages, one is my staging environnement that will build my hugo pages with all drafts pages and then publish with wrangler on a dedicated subdomain: staging.vence.tech. For that stage I mentionned that it should apply to every branches except my master branch where I will define a specific behavior. The second stage which apply only to my master branch have specific instruction to build my pages on Hugo and then publish them on my main domain. Hugo will not build post that have a draft status.

We are almost done, the last piece before getting a working CI/CD pipeline is to use environnement variable. Here I need one for Warangler to pass my token API allowing me to push pages in my Workers + KV environnement. To do so, I have to configure my Gitlab under Settings > CI/CD and add my variables.

Token API creation

Maybe you are wondering how to generate that token on Cloudflare. It is quite easy and the configuration can be done on your Cloudflare account. Log in on Cloudflare dashboard and then go to your profile page. You can now click on API Tokens and create a new one. The permissions should be as follow:

  • Account level: Workers KV Storage:Edit
  • Account level: Workers Scripts:Edit
  • Zone level: Workers Routes:Edit

You have to choose the right account and zone. The last step on Cloudflare will ask you to activate your API token by doing an API call. After you will be able to use it in Wrangler.

Let’s now come back on gitlab, you have your API token and you can import that token into your Variables settings. Make sure that protected is not selected otherwise that variable will be only available for protected branch or protected tags. More details here

Congrats! You have now a working CI/CD pipeline in Gitlab that will be trigger each time you commit a new .md file into your gitlab repository. For the scripting part we used package.json that I introduced in my previous blog post here.

Next steps

As you may noticed, we are currently publishing draft version on a subdomain accessible by everyone. The next steps will be to lockdown that subdomain on Cloudflare to only give access to specific users. Stay tunned!

Ressources

To create my clean docker image, I leverage on those ressources:

To get further information on all CI/CD variables you can used within .gitlab-ci.yml, please refer to that document: