Continuous Integration for Nintendo Game Boy development using GitHub Actions

I previously posted about writing Hello World for the Nintendo Game Boy using the GBDK.

I’ve been meaning to spend some quality time with GitHub Actions and found the perfect excuse – doing Continuous Integration for Game Boy development 😀. I bet I can count the people that are interested in this topic in the entire world on one hand! In any case it was a great excuse to learn GitHub Actions 🤖.

After much trial and error, although admittedly a lot less than I thought! I ended up with the below GitHub Actions workflow, this contains a single job with multiple steps that does the following:

  • Triggers when code is pushed to the main branch of the repo
  • Checks out the code in the repo
  • Downloads a copy of GBDK from https://github.com/gbdk-2020/gbdk-2020/releases/latest/download/gbdk-win.zip and extracts the contents to the Windows based runner for the Action (this is required to compile the code)
  • Uses lcc.exe (from the GBDK) to build the C source file (main.c) into a Game Boy ROM (helloworld.gb)
  • Creates a release using a random number (generated using PowerShell) for the tag and release name
  • Uploads the helloworld.gb ROM to the release
name: Game Boy CI
# Controls when the workflow will run
on:
  # Triggers the workflow on push
  push:
    branches: [ main ]
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: windows-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      - name: Compile C source code into .GB ROM file
        run: |
          Invoke-WebRequest -Uri https://github.com/gbdk-2020/gbdk-2020/releases/latest/download/gbdk-win.zip -Outfile GBDK.zip
          Expand-Archive GBDK.zip -DestinationPath GBDK
          ./"GBDK\gbdk\bin\lcc.exe" -o helloworld.gb main.c
          echo "RANDOM=$(Get-Random)" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
        with:
          tag_name: ${{env.RANDOM}}
          release_name: Release ${{env.RANDOM}}
          draft: false
          prerelease: false
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 
          asset_path: helloworld.gb
          asset_name: helloworld.gb
          asset_content_type: application/octet-stream

Here’s the Action in “action”

…and here is the result, a freshly compiled GB ROM.

Here is a direct link to the repo, if you’d like a closer look.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s