Setting up CI/CD (continuous integration/continuous deployment) for your Unity projects can save you a ton of time. You don’t have to use your own machine to make builds with each update. You can distribute your game to playtesters, clients, or app stores much faster. (Personally, I use it for game jams where not all artists or musicians have experience with Unity. They can experience the progress much quicker.) The downside is it can be challenging to set up the first few times you do it. But no worries! In this guide, I’ll walk you step by step through how to set up CI/CD for your Unity projects.

Fair warning, this is a long and somewhat complicated process. But it has hands down been worth it in my personal experience. Be patient and take the time to learn what is happening. Bookmark this page and come back to it later if you need.

I’ll be using GitHub Actions to handle the build process and deploying to my Itch.io page for my playtests. This guide assumes you know the basics of those two platforms. You do not need to understand them in depth. I’ll provide a template and show you what to adjust.

Unity Project Setup

The first step in setting up CI/CD in your Unity project is, of course, having a Unity project. But we need to configure it in a certain way for the automation side of things later.

Create a new Unity project or open an existing one. Go to File -> Build Settings. On the panel that opens, click WebGL and click “Switch Platform”.

Here, I have an empty Unity project and have already switched my platform in the build settings. (Note: the button has converted to say “Build” instead of “Switch Platform”.)

Once you have switched platforms, click the Player Settings… button from the Build Settings panel. (Alternatively, you can select Edit -> Project Settings. Then choose “Player” from the panel that pops up.)

On the Player Settings panel, make sure you have WebGL selected. Then click the dropdown arrow for Publishing Settings. Make you options match mine below. Specifically, we want Compression Format to be Gzip and the Decompression Fallback enabled.

Note, you can adjust these settings. But I only recommend doing so if you know what they do and can properly adjust the YAML files later in this guide.

Create the Git Repository

Go to your GitHub page. Create a new repository. All the settings are completely up to you. Personally, I recommend adding a README file as well as a .gitignore file using the Unity template.

Open your Command Prompt or Terminal window. Navigate to the root of your Unity project using the cd (for “change directory”). For example, for my project I would use:

cd C:\Users\mitchell.opitz\Desktop\sandbox\gameDev\Junker TD

Note, you will want this to be where your Assets, Library, Log, etc., directories are located. Make sure they are not in a subdirectory.

Here, we’ll do four things, one line at a time. First, initialize a new repository. Next, set the origin to the GitHub repository we just created. Then, make sure you are on the same branch as the GitHub repository. Finally, pull the README and .gitignore files from the origin to our local environment.

git init
git remote add origin https://github.com/MitchellOpitz/Junker-TD.git
  :: replace URL with your GitHub repository address
git checkout -b main
  :: replace 'main' with whatever your default branch is on GitHub repository.
git pull origin main
  :: again, replace 'main' with whatever your default branch is on GitHub repository.

If all was successful, you should now see the README and .gitignore files in your local project directory.

Create the Unity Secret Key

In order for our CI/CD to be fully automated, you’ll need to get your Unity license number. This will be used by the build action (more on that later). To get the license number, we’ll need to create a GitHub Actions workflow to produce a Unity Activation File (.afl) and use that to request the license number from Unity.

Create the Activation Workflow

First, create a new directory in your project called .github. (The period before is important. Make sure that’s in there.) Within that directory, create a subdirectory called “workflows”. And within “workflows” create a new file called “activation.yml”.

Open the activation.yml file and paste the following:

name: Get Unity license activation file 🔐

on: workflow_dispatch

jobs:
  requestManualActivationFile:
    name: Request manual activation file 🔑
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - uses: webbertakken/unity-request-manual-activation-file@v2
        id: getManualLicenseFile

      - uses: actions/upload-artifact@v2
        with:
          name: Manual Activation File
          path: ${{ steps.getManualLicenseFile.outputs.filePath }}

Save the activation.yml file and close it.

This workflow file will be the same for any future Unity CI/CD projects you want to set up. I recommend saving this in a special “CI/CD Template” directory somewhere on your computer. We’ll be adding to this directory later.

Push Changes to GitHub

We’ve got the changes on our local computer. Now we need to put them on GitHub. So head back into your command prompt/terminal.

Again, we’re going to do a few commands, one line at a time. (Note, you’ll still need to be at the same file path within the command prompt/terminal. So navigate back with cd if you closed the window.)

git add *
git commit -m "Add empty Unity project and Activation workflow"
  :: Feel free to change the commit message if you prefer a certain convention.
git push origin main

After these, you should see the files on your GitHub repository once you refresh the page.

Run the Activation Workflow

On your GitHub repository, navigate to the Actions tab. On the left side of the page, you’ll see the workflow we just created: “Get Unity license activation file”. Click on that workflow. Then click “Run workflow” on the right side of the page.

This process should only take a minute or two. Once you see the action has completed, you can click the title to view the details. This is also where we will find the activation file we need. Under Artifacts, click “Manual Activation File” to download it.

Get the Unity ULF File

Navigate to the downloads folder on your computer. You’ll find the Manual Activation File as a zip file. Go ahead and extract/unzip this file to produce the .alf file we need.

Next, head over to the Manual Activation page provided by Unity. Click the Browse button and choose the .alf file we just extracted.

On the next page, you’ll need to select some options about your version of Unity. For me, I’m using the Personal Edition but not in a professional capacity (yet!). Select the correct options for you. Click Next.

The final page will allow you to download the license file we ultimately need. Click Download license file.

This Unity license file will be the same for any future CI/CD projects. I recommend saving it to the “CI/CD Templates” directory you created earlier.

Add the Unity License to GitHub Secret Keys

Head back to your GitHub repository. This time, navigate to the Settings page. On the left menu, click Secrets and Variables -> Actions.

Here, click New Repository Secret. Name the secret “UNITY_LICENSE”. In the Secret field, paste the CONTENTS of the .ulf file we obtained. Click Add Secret.

Create the Itch.io Secret Key

Now that you have your Unity license secret key, the next step in setting up CI/CD is creating a secret key for Itch.io as well. Fortunately, this step is MUCH easier than getting the Unity license.

If you aren’t deploying to Itch.io, you can skip this step. There’s another step later in the template.yml file that you can skip as well. So keep an eye out for that.

Log into your Itch.io account. Go to your Account Settings page. Under the Developer panel, click API Keys. (You may need to log in or connect your GitHub account. Mine is already connected, so I don’t exactly remember the process here.)

Click the big red button that says “Generate new API key”. On the new API key that shows up, click “View” and copy the entire contents of the API key.

Now go back to your GitHub repository settings. Just like you did for the Unity license file, create a New repository secret (Settings -> Secrets and variables -> Actions). Name this one ITCH_IO_API_KEY. (You can change the name, but make note of it. You’ll need the name later.) Paste in the API key you copied from Itch.Io into the Secret field.

Adjust Workflow Permissions

Before you create the actual build action, you need to adjust the workflow permissions of your GitHub repository. Without this step, you’ll get an error any time the build runs.

Still in your GitHub repository Settings, click on Code and Automation -> Actions -> General. Here, you’ll find some options for Workflow Permissions. Make sure the option for Read/Write permissions is selected, as well as check the option that allows GitHub Actions to create/approve pull requests.

IMPORTANT! If you are creating a template for future use like I suggested, this is likely the piece that will cause you issues in the future. To my knowledge, you cannot save these permissions to your GitHub account. Only to individual repositories. Be sure to check it every time.

It’s so important, I created an important section on the table of contents. If you ever forget, just come back to this page and find that IMPORTANT! link.

Create the Build Workflow

We need one last piece for our CI/CD to be set up for our Unity project: the build workflow. This very similar to the activation.yml file we created earlier.

Head back to your Unity project directory. Navigate to .github -> workflows. Create a new file. Call it template.yml. Open this new template.yml file and place the following:

name: GameCI Template 🎮

on: push

env:
  UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}

jobs:         
 buildWebGL:
   name: Build for WebGL 🖥️
   runs-on: ubuntu-latest
   strategy:
     fail-fast: false
   steps:
     - name: Checkout code
       uses: actions/checkout@v3

     - 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

     - name: Restore Library cache
       uses: actions/cache@v3
       with:
         path: Library
         key: Library-build-WebGL
         restore-keys: |
           Library-build-
           Library-

     - uses: webbertakken/unity-builder@v2
       with:
         targetPlatform: WebGL

     - uses: actions/upload-artifact@v3
       with:
         name: build-WebGL
         path: build/WebGL
         
 deployPages:
   needs: buildWebGL
   name: Deploy to Itch.io 🚀
   runs-on: ubuntu-latest
   steps:
     - name: Checkout code
       uses: actions/checkout@v3

     - uses: actions/download-artifact@v2
       with:
         name: build-WebGL
         path: build

     - name: Display structure of root files
       run: ls -R
       working-directory: build/WebGL

     - name: Deploy 🚀
       uses: JamesIves/github-pages-deploy-action@4.1.4
       with:
         branch: itch-io
         folder: build/WebGL
         
     - uses: manleydev/butler-publish-itchio-action@master
       env:
         BUTLER_CREDENTIALS: ${{ secrets.ITCH_IO_API_KEY }}
         CHANNEL: HTML
         ITCH_GAME: Your-itch-game-name-here
         ITCH_USER: Your-itch-user-name-here
         BRANCH: itch-io
         PACKAGE: build/WebGL

If you are not deploying to Itch, you can remove everything from “deployPages:” down. The following information regarding Itch will also not apply.

The only thing you will need to adjust in this file is the last 4 lines. Specifically, the ITCH_GAME and ITCH_USER fields (and after the first time, you shouldn’t need to adjust the user field anymore). And for any CI/CD setups for future Unity projects, you’ll need to update the ITCH_GAME field each time.

The ITCH_GAME field will need to be precisely what you put in as the Project URL for your game on Itch. (If you haven’t already, you’ll also want to adjust the “Kind of project” field to be HTML.)

Once these changes have been made, save this template.yml file and close it.

If you are creating the “CI/CD Template” directory, the template.yml file will be the final file to go into it.

Push Build Workflow to GitHub Repository

The last step in setting up CI/CD for your Unity project is pushing the Build workflow to the GitHub repository. This step is nearly identical to when we committed the activation.yml file.

Start by opening up your command prompt/terminal window (if you closed the window). Navigate back to your project file path. We’ll use the same three lines, but change the commit message slightly. Again, reminder that these are done one line at a time.

git add *
git commit -m "Add Build workflow"
  :: Feel free to change the commit message if you prefer a certain convention.
git push origin main

Once this has been done, CI/CD should be set up for your Unity project. Congratulations!

Wait about 6-7 minutes (time depends on the complexity of your Unity project). Afterwards, you should see a new build notification in your Itch account and the game should appear on the appropriate page.

Troubleshooting

There are a LOT of steps in this process. In writing this article, I’ve made a handful of mistakes myself, truthfully. So I want to cover some of the most likely issues.

Activation Workflow Errors

Likely wasn’t copied precisely. In one of my runs, I had an error in my .yml simply because I had left the first character off. Try copying/pasting again or running the code through a YAML syntax checker.

Build Workflow Errors

This is the most likely place you’ll see errors. And there are a few things you may need to check.

  • Verify you copy and pasted everything correctly and run through a YAML syntax checker.
  • Confirm you have copied ALL contents from the Unity .ulf file into the secret key. (NOT the .alf file.)
  • Check you have set workflow permissions to read AND write.
  • Make sure your secret key names match your template.yml file. If you name things differently than I have in this guide, this could get off a bit.
  • Confirm you have the correct ITCH_GAME project URL and ITCH_NAME for your account.

Conclusion

Hopefully you now have a working CI/CD pipeline for your Unity project! It’s a long process, especially the first few times you do it. But it has saved me countless hours waiting for builds or sending things to game jam teammates. And after a time or two, you get used to the process and it goes much quicker. And the template helps, of course.

I’d really appreciate your feedback on this process. There are a lot of steps and I want to make sure I covered everything. If you go through it and find issues, please be sure to let me know in the comments below. I’ll correct anything as soon as possible.

If you found this article helpful, please be sure to share it on your favorite social media platform, Discord server, or wherever you like to get your game development information.