Gitlab: Build Previews

Setting up build previews for static sites on Gitlab

Problem

When building a website on #gitlab, I would love to have a way to generate a preview of each PR. That way I can easily see what the change will look like before deploying it to production.

Solution

This is possible to accomplish in #gitlab without having to integrate any other tools or any hacky configuration. But there are a few steps to it.

Step 1

Update the .gitlab-ci.yml file to include the following environment variables.

environment:
  name: 'preview/$CI_COMMIT_REF_NAME'
  url: 'https://$CI_PROJECT_NAMESPACE.gitlab.io/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/build/index.html'

This configures Gitlab to add a "Review App" link to your Merge Requests. In this case, the review app will link to the build artifacts folder.

Screenshot of Gitlab merge request review app link

If applicable, make sure to include the subgroup path in the link above (between /-/ and $CI_PROJECT_NAME).

Step 2

Then make sure that your static site generator generates the site for the URL above. This is to ensure that any links point at the right place (e.g. links to other pages or CSS resources).

For example, for a ReactJS app you just need to define the PUBLIC_URL variable before build:

variables:
  PUBLIC_URL: '/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/build'

The process to accomplish this will depend on your project.

If applicable, make sure to include the subgroup path in the link above (between /-/ and $CI_PROJECT_NAME).

`

Full example

This is a build step I added to one of my ReactJS projects.

build/preview:
  image: node:latest
  stage: build
  except:
    - main
  environment:
    name: 'preview/$CI_COMMIT_REF_NAME'
    url: 'https://$CI_PROJECT_NAMESPACE.gitlab.io/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/build/index.html'
  variables:
    PUBLIC_URL: '/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/build'
  before_script:
    - make npm/install
  script:
    - make npm/build
  artifacts:
    paths:
      - build/*
    expire_in: 7 days

From my phasmophobia-guide ReactJS app

Details

The key to this process is that build artifacts behave just like regular web pages. They can be opened as a normal website and they can be referenced as regular CSS or JS resources.

This means you do not need to add the review app for this to work. You can manually navigate to the build artifacts and open up the index.html file to load the page. The review app just makes this extra handy by adding a direct link to the merge request.

The environment name is the name that appears next to the merge request link. It can be anything, but I like to include the branch name in the name to make it clearer what is being previewed.

environment:
  name: 'preview/$CI_COMMIT_REF_NAME'

The environment URL defines where the link will go. This should be some page within your static website. In this case I am linking to the main index.html page, but you could point it at any page.

environment:
  url: 'https://$CI_PROJECT_NAMESPACE.gitlab.io/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/build/index.html'

Make sure that the ../artifacts/build/.. path matches up with the artifacts path in the build definition. In my example I am adding the build/ folder as an artifact, that is why the URL includes /build/.

If I were to add another folder as an artifact (e.g. public/) I would have to change the URL to reflect that (e.g. ../artifacts/public/..).

Related