Skip to main content
Version: v4 (current)

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/workflows YAML 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
Need 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

  1. Understand how Github Actions work.
  2. Configure a license for Unity.
  3. Set up a workflow for your project.
  4. 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;

  1. Checkout your repository using Checkout.
  2. Cache Unity Library folder using Cache.
  3. Configure your test job using Test Runner.
  4. Configure your build job using Builder.
  5. 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:

- uses: game-ci/unity-builder@v4
with:
targetPlatform: WebGL

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.