Create a Unity to itch.io Deployment Pipeline Using Butler & Bash Scripting

townofdon

Don Juan Javier

Posted on January 22, 2022

Create a Unity to itch.io Deployment Pipeline Using Butler & Bash Scripting

I recently uploaded my first game to itch.io, and discovered that there is a nifty tool called Butler that allows uploading a build from the command line.

However, I wanted to streamline the build -> zip -> upload steps, so here's what I did:

1: Create WebGL build in Unity

First, I followed the official Unity docs for publishing WebGL games.

In the Unity Build Settings, I selected a WebGL build and made sure to turn compression off in Player Settings (Project Settings -> Player), after running into an issue with the build not working in the browser.

Disable compression in Unity Player Settings

Finally, I made sure all of my scenes were checked that I wanted to include, and selected Build (I also always use the Clean Build option). I used the default build path of ./Build.

Unity Build Settings

2: (Optional) add docker-compose to test WebGL build

After the build completed, I wanted to test things out before uploading to itch.io. I followed this guide to set up my own docker-compose file to run things locally.

BTW, getting Docker to work on a Windows machine took some effort... I had to enable CPU virtualization in my BIOS settings. I'm a BIOS noob, so that was a little scary, but I finally got things working, and docker-compose up worked like a charm.

3: Adding deploy.sh script

I wanted my script to automate two things:

  1. Packaging my build into a .zip file
  2. Uploading to itch.io via Butler

My Windows machine uses 7-Zip for archive creation/extraction, so I had to add 7-Zip to my Windows path. (Alternatively, I could have used the zip command, but it wasn't working for me - I didn't feel like going through the hassle of installing GoW just to use zip).

Next, I needed to install Butler and add it to my Windows path. I just added a directory called C:\Bin and placed the downloaded Butler folder there, and set the Windows path to C:\Bin\Butler.

After all was said and done, I could run the following commands:

# zip file to archive
ZIPFILE="/path/to/zipfile-to-create"
7z a $ZIPFILE "/path/to/Build" > NUL
Enter fullscreen mode Exit fullscreen mode

(Note, the > NUL above simply silences the output from the zip command; also NUL would be /dev/null on Mac/Linux).

# upload to itch.io
USERNAME="my-itch-io-username"
GAME="my-awesome-game"
CHANNEL="html"
VERSION=1.0.0
butler push $ZIPFILE "${USERNAME}/${GAME}:${CHANNEL}" --userversion $VERSION
Enter fullscreen mode Exit fullscreen mode

Viola! Everything worked like a charm, and my newly-uploaded .zip file now showed up in my edit game page.

Conclusion

Now that this script is in place, deploying new releases for my game is ridiculously easy. Hopefully this guide can help you streamline your game release cycle as well.

Deploy script in action

Here's my full deploy.sh script:

Config/deploy.sh

#!/bin/bash

USERNAME="my-itch-io-username"
GAME="my-awesome-game"
CHANNEL="html"

#
# COLORS
# see: https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux
#
NC='\033[0m'              # No Color
BLACK='\033[0;30m'        # Black
RED='\033[0;31m'          # Red
GREEN='\033[0;32m'        # Green
YELLOW='\033[0;33m'       # Yellow
BLUE='\033[0;34m'         # Blue
PURPLE='\033[0;35m'       # Purple
CYAN='\033[0;36m'         # Cyan
WHITE='\033[0;37m'        # White
GREY='\033[1;30m'         # Grey

#
# UTILS
#
log() {
  echo -e "${GREY}${1}${NC}"
}
info() {
  echo -e "${CYAN}${1}${NC}"
}
success() {
  echo -e "${GREEN}${1}${NC}"
}
warn() {
  echo -e "${YELLOW}${1}${NC}"
}
error() {
  echo -e "${RED}${1}${NC}"
}
prompt() {
  read -p "$1 " -n 1 -r
  echo    # (optional) move to a new line
  if [[ ! $REPLY =~ ^[Yy]$ ]]
  then
      warn "user cancelled."
      exit 1
  fi
}
assertFileExists() {
  if [ ! -f "$1" ]; then
      error "$1 does not exist."
      exit 1
  fi
}
assertDirExists() {
  if [ ! -d "$1" ]; then
      error "$1 does not exist."
      exit 1
  fi
}

#
# GET VERSION
#
VERSION=$(cat version.json \
  | grep version \
  | head -1 \
  | awk -F: '{ print $2 }' \
  | sed 's/[",]//g' \
  | tr -d '[[:space:]]')
SAFE_VERSION="${VERSION//./$'-'}"

#
# SCRIPT
#

info "WELCOME TO THE UNITY DEPLOYMENT SCRIPT!"
info "About to push version ${RED}${VERSION}${CYAN} - proceed?"
prompt "(y/n)"

assertFileExists "../Build/index.html"
mkdir -p "../Archives"
ZIPFILE="../Archives/build-${SAFE_VERSION}.zip"

log "creating zip archive for ${ZIPFILE}..."

# zip
7z a $ZIPFILE "../Build" > NUL

log "deploying to itch.io..."

# push to itch.io
butler push $ZIPFILE "${USERNAME}/${GAME}:${CHANNEL}" --userversion $VERSION

success "All done!"

Enter fullscreen mode Exit fullscreen mode

I also added a simple version file containing version info for my game to make it easy to update without needing to alter my script:

Config/version.json

{
  "version": "1.0.0"
}
Enter fullscreen mode Exit fullscreen mode

Cover Photo by Hello Lightbulb on Unsplash

💖 💪 🙅 🚩
townofdon
Don Juan Javier

Posted on January 22, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related