Posted on March 6, 2024 | #github, #godot, #web

thumbnail

Publish your Godot game to Itch.io with GitHub Actions

Always having to manually build and distribute your game is a hassle. Here is how I automated publishing HTML5 game to Itch.io - made in Godot 4 of course!

TLDR; Check out the yaml workflow file. Good luck!

Prerequisities

Step 1: Tokens

First we need an API Token for Itch.io. Head to the Account Settings > Developer > API Keys section. This link should also take you there. Generate a new API key.

itch-api-keys

Next up, you will need a dedicated GitHub token. Under your profile developer settings create a new token. Give it the repo permissions. Set the expiration date as you see fit.

github-token

Go to your project’s GitHub repo. In the repository settings you can input your new tokens secrets to be accessible in Actions.

github-action-secret

Step 2: Create export settings in Godot

If you export your project at least once, Godot will create a export_presets.cfg file in the root of the project. You can find the export settings in Project > Export.

Give a name to the export template. It may seem redundant, but end your export template name in the platform for which you are exporting! That means in my case, I ended the name with -web, because it’s a HTML export. Alternatively you could do -windows, -macos, -linux and so on. This is because the GitHub action we will be using uses this suffix to determine to which channel on Itch should the build be pushed.

godot-html-export

I’d also say setup the export path just to keep things tidy.

Step 3: GitHub Action

Finally you are ready to create the GitHub action. Your Itch.io token is in the repository secrets and Godot knows how to export your project.

GitHub actions are stored in a special .github folder. You can create it on the repo website or locally. It doesn’t really matter.

mkdir -p .github/workflows
touch .github/workflows/itchio-publish.yml

Trigger

The simplest trigger you can go for is on push to the master branch:

name: Publish to Itch.io

on:
  push:
    branches: ["master"]

If your game is not in the root of your project, you could trigger the action only when certain files change!

Jobs

Here are the steps of the action:

  1. Check out the code
  2. Export the game
  3. Upload it to itch

For exporting the project, I ended up using firebelley/godot-export action. I feel like it work extremely well for HTML builds. It automatically creates a .zip file, which is exactly what Itch wants. Convenient!

It needs links to the Godot version you are using as well as export templates. Go to this link and pick out your version of the engine.

In the Action’s README, the author says this about the godot_executable_download_url:

If you do not use the Linux Headless version exporting will fail.

In the Godot 3 days, there used to be a dedicated server build. This has been replaced by the --headless startup flag, so a x86_64 linux version is all you need for this.

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v3

      - name: Godot Export
        id: export
        uses: firebelley/godot-export@v5.2.1
        with:
          godot_executable_download_url: https://downloads.tuxfamily.org/godotengine/4.2/Godot_v4.2-stable_linux.x86_64.zip
          godot_export_templates_download_url: https://downloads.tuxfamily.org/godotengine/4.2/Godot_v4.2-stable_export_templates.tpz
          # If the game is in the root of your project
          relative_project_path: ./
          # Really handy for HTML exports!
          archive_output: true
          # Cache the Godot export templates and Godot executable,
          # so that they are not downloaded again every time.
          cache: true
        env:
          GITHUB_TOKEN: ${{secrets.GH_TOKEN}}

# ...

Now for the publish step. One quirk with Ayowel/butler-to-itch is how it uses the names of the exported files to determine which channels to upload the archive to.

Note how I’m using the output of the previous step to know where my exported game is located.

      - name: Publish to Itch
        uses: Ayowel/butler-to-itch@v1.0.0
        with:
          butler_key: ${{secrets.ITCHIO_TOKEN}}
          itch_user: struhy-xd
          itch_game: painted-mosaics
          version: ${{ github.ref_name }}
          files: "${{ steps.export.outputs.archive_directory }}/mosaics-web.zip"

I also considered using yeslayla/butler-publish-itchio-action. It’s configuration API seems to be nicer. But in the end, this one worked for me.

Beware: My itch username is struhy_xd, right? Well, not really. It contains an underscore. In my REAL username this is replaced by a dash. Go to any of your itch projects and look at the URL, just to be sure.

Finishing touch - play in browser

The GitHub action just uploads the exported game to the correct channel. By default they are all downloadable. If you want to have your game playable in browser, you have to tick the checkbox manually!

itch-play-in-browser

After that, it will stay marked for play in browser and all subsequent uploads will work as expected.

If you already had a HTML export uploaded, it might create a new HTML export next to it, rather than updating the old one. This might have something to do with Butler and the automated upload. Just delete the old one and set the new one to be playable :)


Thanks for reading!

You can see my own workflow file here.

Credit: An article by bitbrain has been of huge help. Thanks!