Continuous Delivery pipeline for Godot and

During the recent Godot Wild Jam 18, I implemented a full Continuous Delivery system to automatically publish Plague, our entry, on The pipeline relies on Github Actions, the same mechanism I use to build and deploy this very blog.

Setting up your own is easy peasy and possibly free!

⚒️ Pipeline overview

  1. Someone pushes to the master branch on the remote repo.
  2. The game is exported for all available platforms. In this case: Windows, Linux, MacOS and HTML5.
  3. A new Github release is created with attached files, one per platform.
  4. The release artifacts are pushed as new versions of the game to


🤖 Configure Godot exports

First, you need to setup the export settings in your Godot project. The official exporting guide explains it perfectly. The thing to keep in mind here is that the preset name will determine the name of the published artifact. For example, a preset called plague-mac will result in a release with an attached file called

In the case of our jam entry, we targetted MacOS, Windows, Linux and HTML5.


📦 Export the game

Create a .github/workflows/export_game.yaml file in your repo. We will tell our new action to run on every push to master. We don’t want new releases on commits that do not actually change the game. Our Godot project lives in the game folder, so we tell the action to only run if there are changes in that folder.

      - master
      - 'game/**'

For the actual export step, we will leverage the Godot Export Github action. The explains its usage very well.

Here’s our config in case it helps you. We setup the base version to be published, the links to download the Godot headless executable as well as the templates and tell it our project is located in the game folder in the repo. Whenever you interact with the same repo the action is being triggered from, you can use the secrets.GITHUB_TOKEN, which is automatically populated.

    runs-on: ubuntu-latest
    name: Export game
    - name: checkout
      uses: actions/checkout@v2.0.0
    - name: export
      uses: firebelley/godot-export@v1.1.0
        base_version: 0.1.0
        godot_template_version: 3.2.stable
        relative_project_path: ./game
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Whenever you push these changes to your repo, you should already start seeing jobs being triggered and releases being published.


🚢 Ship the game

Butler is the CLI, which lets you upload builds of your game. Our publish Github action will need to talk to using a valid API key. In order to get one, install butler and generate a key via butler login. Refer to the docs for the details.

Then, copy your Butler API key and go to and create a BUTLER_CREDENTIALS entry with the contents of the key.

Now create a .github/workflows/publish_game.yaml file in your repo. This action will run every time a new release is created or edited.

    types: [created, edited]

Our workflow needs to contain a job per platform we want to publish. Each job will leverage the Fetch GH Release Asset and Butler Push actions. We first download the latest release artifact for the platform we want to export and then we call the butler action to push the build to When pushing multiple times to the windows channel, each will be considered a new version of the same “product.

    runs-on: ubuntu-latest
      - name: download widows
        uses: dsaltares/fetch-gh-release-asset@master
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
      - name: release windows
        uses: josephbmanley/butler-publish-itchio-action@master
          CHANNEL: windows
          ITCH_GAME: plague
          ITCH_USER: dsaltares

That’s it! Once you push the publish workflow and make a change to the game, Github will export, create a new release and update your game on


On your game page, you should see something like:


✅ Advantages

It would be amazing if you let me know your thoughts on this solution. Maybe you have a much better automated process or ideas on how to improve this one!

comments powered by Disqus