Setting up Gitlab CI for Unreal Engine 4


Note: This tutorial was last updated at 25 August 2019.
There seem to have been some changes to Gitlab CI and especially execution of batch files. The tutorial has been updated to use PowerShell and should be easier to configure.


This tutorial provides documentation and resources on how to configure Gitlab CI to compile and build your Unreal Engine 4 project.

For our university project, we needed a solution for Unreal Engine 4 build automation. After trying Jenkins CI but running into network limitations due to the university network we started using Gitlab CI to automate our builds.

This tutorial and files are based on the great Jenkins tutorial by Zack Devine, check it out if you want to use Jenkins instead!


Prerequisites

Before you begin: Set up your Gitlab repository as normal and clone it to your desktop. You can go ahead and add your Unreal Engine 4 project to the repository.

This documentation is solely meant to configure a Gitlab runner on Windows servers and desktops. This may work on GNU/Linux build servers but the included scripts have only been tested for Windows desktops.

We will configure our pipeline so that it will only archive our builds during scheduled builds and manual builds started through the Gitlab interface. This way you prevent flooding your disk space with archived builds.


Setting up the Runner

Gitlab uses runners to run the jobs defined in the .gitlab-ci.yml file (which we will create in the last step of this tutorial). We will set up a Windows desktop as our runner.

Download the runner executable from https://docs.gitlab.com/runner/install/windows.html and follow the installation process described in the documentation.

Register the Runner
Now we need to register our runner. Inside your Gitlab project go to Settings -> CI/CD -> General pipelines settings and obtain the runner token.

Follow the registration progress described in https://docs.gitlab.com/runner/register/#windows but do not enter any tags when prompted. Finally, pick Shell as your executor after which we should have our runner set up.

Configure the Build Scripts
Copy the contents of the build script below and move them to another folder. For example: C:/BuildScripts/.
Make sure you provide the $env:enginepath with the path to your engine.
$ErrorActionPreference = "Stop"

echo "Running on $env:computername..."

& {
	echo "Preparing Runner Variables..."
	
	# required runner variables
	$env:enginepath="C:\PATH_TO\Epic Games"
	$env:projectname=$PROJECT_NAME
	$env:engineversion=$ENGINE_VERSION
	$env:projectpath=$CI_PROJECT_DIR
	$env:buildconfig=$BUILD_CONFIGURATION
	$env:runnerid=$CI_RUNNER_ID
	$env:branch=$CI_COMMIT_REF_NAME
	$env:revision=$CI_COMMIT_SHORT_SHA

	# archive directory
	$env:archivename=$ARCHIVE_NAME
	$env:buildlocation="$env:projectpath\Build\$env:projectname"

	echo "==============================================="
	echo "Starting build for project $env:projectname..."
	echo "Using engine version $env:engineversion..."
	echo "Using build configuration: $env:buildconfig..."
	echo "Using runner $env:runnerid for this job..."
	echo "Archive name: $env:archivename"
	echo "==============================================="
}

& "$env:enginepath\$env:engineversion\Engine\Binaries\DotNET\UnrealBuildTool.exe" -projectfiles -project="$env:projectpath\unrealproject\$env:projectname.uproject" -game -rocket -progress

echo "==============================================="
echo "Compile stage..."
echo "==============================================="

& "$env:enginepath\$env:engineversion\Engine\Binaries\DotNET\UnrealBuildTool.exe" $env:projectname $env:buildconfig Win64 -project="$env:projectpath\unrealproject\$env:projectname.uproject" -rocket -editorrecompile -progress -noubtmakefiles -NoHotReloadFromIDE -2017

echo "==============================================="
echo "Build and Cook..."
echo "==============================================="

& "$env:enginepath\$env:engineversion\Engine\Build\BatchFiles\RunUAT.bat" BuildCookRun -project="$env:projectpath\unrealproject\$env:projectname.uproject" -noP4 -platform=Win64 -clientconfig="$env:buildconfig" -cook -allmaps -build -stage -pak -archive -archivedirectory="$env:buildlocation"

echo "==============================================="
echo "Archiving the artifact..."
echo "==============================================="

& Compress-Archive -Path "$env:buildlocation" -DestinationPath "$env:projectpath/Build/$env:archivename.zip"

echo "Archive created..."

if(!$?) { Exit $LASTEXITCODE }

Creating a Gitlab Pipeline

Once we have our runner set up we can configure our pipeline. Start by creating a .gitlab-ci.yml file inside your repository. This file tells the Gitlab runner what to do when a pipeline is triggered.

Add the following to the .gitlab-ci.yml file and make sure you configure the Project Settings variables to suit your project.
# Gitlab Continues Integration for Unreal Engine 4
variables:
  GIT_STRATEGY: none
  GIT_CHECKOUT: "false"
  ErrorActionPreference: STOP

  # Unreal Engine 4 Project Settings
  PROJECT_NAME: "YOUR_PROJECT_NAME"
  ENGINE_VERSION: "UE_4.22"
  BUILD_CONFIGURATION: "Development"
  ARCHIVE_NAME: "$PROJECT_NAME-$BUILD_CONFIGURATION-rev$CI_COMMIT_SHORT_SHA-x64"

stages:
  - buildproject
  - package

buildproject:
  stage: buildproject
  variables:
    GIT_STRATEGY: fetch
    GIT_CHECKOUT: "true"
  script:
    - "buildscripts/buildproject.ps1"

package:
  stage: package
  only:
    - web         # only upload the artifact when the build has been started through the interface
    - schedules   # only upload the artifact when the build has been started through a schedule
  script:
    - echo "Uploading the artifacts to Gitlab..."
  artifacts:
    paths:
      - Build/$ARCHIVE_NAME.zip
    expire_in: 1 week


Commit the file and your pipeline should be triggered! Gitlab will now build and compile your project every time files are pushed to your repository. It will archive the build only when triggered through the web interface or on a scheduled time.

Finally, you might want to add Slack Notifications.

If you have any questions, suggestions or feedback feel free to contact me.


Share this Post: