Automate product releases with GitHub Actions

This guide will show you how to automatically release new versions of your software built in GitHub actions on Moonbase using our core API.

Getting started

To access the API for your account, start by creating an API key if you don't have one already by going to your Moonbase account settings. API keys allow access to a slew of endpoints documented in our Core API reference, and can be used by adding an Api-Key header to your requests.

Basic process

1. Prepare downloads

A product release in Moonbase can have multiple downloadable files. For each of the files you want part of a release, you need to prepare it and get the URL to upload to:

curl -X 'POST' 'https://demo.moonbase.sh/api/downloads/prepare?contentType=application%2foctet-stream' \
  -H 'Api-Key: mb_a52c7...'

Be sure to substitute demo with your account ID, and the contentType query parameter with the content type of whatever you want to upload. For binaries, application/octet-stream is usually the right choice, but for other file types there will be other MIME types.

The above request will respond with a key and a URL in a JSON object like this: { "key": "demo/eaefa...", "url": "https://..." }. Using these, you can proceed to upload the file with a PUT request to the given URL.

2. Upload file

Using the URL from the previous response, you can initiate an upload. The API key used previously is not necessary for this step as the URL is pre-authorized:

curl --upload-file file_key.txt $URL \
  -H 'Content-Type: application/octet-stream'

Repeat the above to steps for each file you want to be part of your release, and preserve the keys returned for each one.

3. Create a release

Once all the files are uploaded, we can create the release in Moonbase. The request needs to contain an array of all files you want part of the release, with a name and platform indicator for each file. Platform can be one of Windows | Mac | Linux | Universal, and is used for interface indicators and suggestions when your customers are downloading the software.

curl -X 'POST' 'https://demo.moonbase.sh/api/products/example-product/releases/new?publishImmediately=true' \
  -H 'Api-Key: mb_a52c7...' \
  -H 'Content-Type: application/json' \
  -d '{
  "version": {
    "major": 1,
    "minor": 0,
    "patch": 0
  },
  "downloads": [
    {
      "name": "Installer.exe",
      "platform": "Windows",
      "key": "'$KEY'"
    }
  ]
}'

Releases in Moonbase are versioned based on semantic versioning to allow for a number of strategies regarding pricing and distribution. The major, minor and patch are all components for this semantic version identifier. To learn more about semantic versioning, read more at https://semver.org.

If you would rather do a automatic upload, but manual publication, set the publishImmediately query parameter to false, or remove it entirely. You can then publish it from the Moonbase app yourself:

Making a GitHub Action

With the above, we can build the following action to automatically release software.

name: Moonbase Continuous Deployment

on:
  push:
    branches:
      - main

jobs:
  moonbase-cd:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@master

      - name: Build application
        run: make build # This is dependant on how you build your binaries

      - name: Prepare download
        run: |
          echo "DL_JSON=$(curl -X 'POST' \
            'https://demo.moonbase.sh/api/downloads/prepare?contentType=application%2foctet-stream' \
            -H 'Api-Key: ${{ secrets.MOONBASE_API_KEY }}')" \
            >> $GITHUB_ENV

      - name: Upload binary
        env:
          URL: ${{ fromJson(env.DL_JSON).url }}
        run: |
          curl --upload-file installer.exe $URL \
            -H 'Content-Type: application/octet-stream'

      - name: Create Moonbase release
        env:
          KEY: ${{ fromJson(env.DL_JSON).key }}
        run: |
          curl -X 'POST' 'https://demo.moonbase.sh/api/products/example-product/releases/new' \
            -H 'Api-Key: ${{ secrets.MOONBASE_API_KEY }}' \
            -H 'Content-Type: application/json' \
            -d '{
                "version": {
                    "major": 1,
                    "minor": 0,
                    "patch": 0
                },
                "downloads": [
                    {
                        "name": "installer.exe",
                        "platform": "Windows",
                        "key": "'$KEY'"
                    }
                ]
            }'

Be sure to plug in your favourite versioning tool to automatically increment the semantic version too!

Bonus: notifying users

Once you publish a new release in Moonbase, all customers will immediately have access to download the new version. But how will they know about it? One way is to use the licensing flow that you might already be using, as in the metadata of any license is the current release version of the product that the license has been issued for. If you opt for a flow where you periodically re-validate license activations, new metadata will contain updated product version numbers. Using this metadata, you can build UIs to notify your users about new versions being available. Learn more about the metadata available for license activations in our licensing API reference.

Was this page helpful?