Getting started
GitHub Actions for Unity provide the fastest and easiest way to automatically test and build any Unity project.
There are a few parts to setting up a workflow. Steps may slightly differ depending on each license type.
Prerequisites
- A Unity project, checked into a GitHub repository
- A Unity license — personal, plus, pro, or a Unity Personal serial (see Activation for how to obtain and configure one)
- Familiarity with GitHub Actions basics (a
.github/workflowsYAML file, jobs, and steps) — if this is new to you, read the note below first
Quick start
Copy this into .github/workflows/main.yml to test and build a WebGL project on every push. It's
the same Simple Example shown again further down this page — this copy exists
so there's something to paste before reading the rest of the page.
name: Actions 😎
on: [push, pull_request]
jobs:
build:
name: Build my project ✨
runs-on: ubuntu-latest
steps:
# Checkout
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
# Cache
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-
# Test
- name: Run tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
# Build
- name: Build project
uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
targetPlatform: WebGL
# Output
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
UNITY_LICENSE, UNITY_EMAIL, or UNITY_PASSWORD?This example assumes you already have Unity activation secrets configured. If you don't yet, see Activation first — it walks through personal, professional, and floating license setup.
This example assumes your Unity project is in the root of your repository, and builds a single target (WebGL). More variations — Git LFS caching, parallel builds, multi-platform matrices — are in Workflow examples below.
Mental model
Overall steps
- Understand how Github Actions work.
- Configure a license for Unity.
- Set up a workflow for your project.
- Result: Merge pull requests with more confidence.
Setting up a workflow
Setting up a workflow is easy!
Create a file called .github/workflows/main.yml in your repository and configure the following
steps;
- Checkout your repository using Checkout.
- Cache Unity Library folder using Cache.
- Configure your test job using Test Runner.
- Configure your build job using Builder.
- Deploy your application.
Note: all steps will be explained in the next chapters.
Support
First time using GitHub Actions?
Read the official documentation on how to setup a workflow.
Any subsequent steps assume you have read the above.
Supported Unity versions
Unity Actions are using game-ci/docker since unity-builder
version 2. Any version in this list can be used.
Something not working?
- Check Common issues — activation failures, license errors, and other problems reported most often.
- Check the FAQ for answers to general questions about GameCI.
Choosing a target platform
The examples below default to WebGL, but targetPlatform accepts any value from the
supported platforms list. A few common ones:
- WebGL
- Windows
- Linux
- Android
- uses: game-ci/unity-builder@v4
with:
targetPlatform: WebGL
- uses: game-ci/unity-builder@v4
with:
targetPlatform: StandaloneWindows64
- uses: game-ci/unity-builder@v4
with:
targetPlatform: StandaloneLinux64
- uses: game-ci/unity-builder@v4
with:
targetPlatform: Android
Swap the targetPlatform line into any of the full examples below.
Workflow examples
Below are workflow examples displaying various levels of complexity.
It is recommended to start from the Simple Example and work your way down the page.
Simple example
This example tests your project then builds it for a single target (WebGL in this case). It will run sequentially.
This example assumes that your Unity project is in the root of your repository.
name: Actions 😎
on: [push, pull_request]
jobs:
build:
name: Build my project ✨
runs-on: ubuntu-latest
steps:
# Checkout
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
# Cache
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-
# Test
- name: Run tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
# Build
- name: Build project
uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
targetPlatform: WebGL
# Output
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
Simple example with Git LFS
If you are using GitHub's git-lfs hosting service to store your large binary assets, you will want to cache them to avoid consuming massive amounts of bandwidth. The extra steps in this example try to restore your git-lfs assets from a cache before doing a git lfs pull.
name: Actions 😎
on: [push, pull_request]
jobs:
build:
name: Build my project ✨
runs-on: ubuntu-latest
steps:
# Checkout (without LFS)
- name: Checkout repository
uses: actions/checkout@v4
# Git LFS
- name: Create LFS file list
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
- name: Restore LFS cache
uses: actions/cache@v3
id: lfs-cache
with:
path: .git/lfs
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}
- name: Git LFS Pull
run: |
git lfs pull
git add .
git reset --hard
# Cache
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-
# Test
- name: Run tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
# Build
- name: Build project
uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
targetPlatform: WebGL
# Output
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
Parallel execution of Tests and Builds
This will run tests in parallel with the Build, in this case for Windows 64bit.
This example assumes that your Unity project is in the root of your repository.
name: Actions 😎
on: [push, pull_request]
jobs:
test:
name: Test my project 🧪
runs-on: ubuntu-latest
steps:
# Checkout
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
# Cache
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-
# Test
- name: Run tests
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
build:
name: Build my project ✨
runs-on: ubuntu-latest
steps:
# Checkout
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
# Cache
- uses: actions/cache@v3
with:
path: Library
key: Library-${{ hashFiles('Assets/**', 'Packages/**', 'ProjectSettings/**') }}
restore-keys: |
Library-
# Build
- name: Build project
uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
targetPlatform: StandaloneWindows64
allowDirtyBuild: true
# Output
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
Advanced IL2CPP example
This example leverages the powerful Github Actions construct called a matrix to test and build for multiple versions of Unity and several target platforms in parallel.
IL2CPP builds require the base operating system to match the build target.
Below is an example to build for all supported platforms with the IL2CPP scripting backend enabled in the project settings.
Note: Tests are currently only compatible on Linux hosts.
name: Actions 😎
on: [push, pull_request]
jobs:
buildAndTestForLinuxBasedPlatforms:
name: Build for ${{ matrix.targetPlatform }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2019.4.1f1
- 2020.2.1f1
targetPlatform:
- StandaloneLinux64 # Build a Linux 64-bit standalone.
- iOS # Build an iOS player.
- Android # Build an Android player.
- WebGL # WebGL.
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true
- uses: actions/cache@v3
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-${{
hashFiles(matrix.projectPath) }}
restore-keys: |
Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-
Library-${{ matrix.projectPath }}-
Library-
- uses: game-ci/unity-test-runner@v4
id: testRunner
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: Test results (all modes)
path: ${{ steps.testRunner.outputs.artifactsPath }}
- if: matrix.targetPlatform == 'Android'
uses: jlumbroso/free-disk-[email protected]
- uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
customParameters: '-myParameter myValue -myBoolean -ThirdParameter andItsValue'
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
buildForWindowsBasedPlatforms:
name: Build for ${{ matrix.targetPlatform }}
runs-on: windows-2022
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2019.4.1f1
- 2020.2.1f1
targetPlatform:
- StandaloneWindows # Build a Windows 32-bit standalone.
- StandaloneWindows64 # Build a Windows 64-bit standalone.
- tvOS # Build an AppleTV player.
- WSAPlayer # Build a UWP App.
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true
- uses: actions/cache@v3
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-${{
hashFiles(matrix.projectPath) }}
restore-keys: |
Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-
Library-${{ matrix.projectPath }}-
Library-
- uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
customParameters: '-myParameter myValue -myBoolean -ThirdParameter andItsValue'
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
buildForMacOSBasedPlatforms:
name: Build for ${{ matrix.targetPlatform }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
projectPath:
- test-project
unityVersion:
- 2019.4.1f1
- 2020.2.1f1
targetPlatform:
- StandaloneOSX # Build a macOS standalone.
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
lfs: true
- uses: actions/cache@v3
with:
path: ${{ matrix.projectPath }}/Library
key: Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-${{
hashFiles(matrix.projectPath) }}
restore-keys: |
Library-${{ matrix.projectPath }}-${{ matrix.targetPlatform }}-
Library-${{ matrix.projectPath }}-
Library-
- uses: game-ci/unity-builder@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: ${{ matrix.projectPath }}
unityVersion: ${{ matrix.unityVersion }}
targetPlatform: ${{ matrix.targetPlatform }}
customParameters: '-myParameter myValue -myBoolean -ThirdParameter andItsValue'
- uses: actions/upload-artifact@v4
with:
name: Build
path: build
Video Tutorial
This video was recorded using an earlier version of the GameCI GitHub Actions for Unity — some
details (action versions, Cache step syntax) are outdated. Treat it as a conceptual walkthrough
of the overall flow, not a copy-paste reference; the Simple example above and
the Activation page reflect the current setup.