Automated building and releasing Plugins on Github with Github Actions

fundamental recorder seems to be built on a newer version of ubuntu, probably 22.04. it wont work with 18.04

That would be surprising. By the way, Recorder is not in Fundamental:

i used this the other day to test it out and it worked great, but i just added it to a new repo i created, followed all the same steps, and for some reason when pushing my new tag (“v2.0.0”), all the action’s steps run except the publish step, which is “skipped” for some reason. any ideas?

EDIT: well, whatever it was, it’s working now after creating a new tag for v2.0.1. not sure what i did wrong last time, but it’s working now.

QQ: do you plan to keep this repo up to date?

There are two issues that will require an update shortly:

Node.js 12 actions are deprecated. For more information see: GitHub Actions: All Actions will begin running on Node16 instead of Node12 - The GitHub Blog. Please update the following actions to use Node.js 16: actions/checkout, actions/upload-artifact, actions/checkout

macOS-latest pipelines will use macOS-12 soon. For more details, see https://github.com/actions/runner-images/issues/6384

Edit: Apologies if you have already addressed these issues, I just realised that I have not updated my actions recently, so these may not be a factor…

i’m wondering about this as well. been noticing several deprecation warnings over the last month or so, and have been unsure what to do about them, if anything.

I think the actions itself must be updated, you can check the status at GitHub Actions repository.

Other then that, you have to update your workflow by yourself, as I just gave this as an example. I updated now the example repository.

3 Likes

I needed to change indeed some actions to make warnings disappear. It should be fine now. The remaining warnings have to be fixed by the actions.

2 Likes

I updated the Toolchain Docker image to version 10.

The Make target plugin-build-linux-x64 has changed to plugin-build-lin-x64, so in the file .github/workflows/build-plugin.yml the line platform: [win-x64, linux-x64] needs to be changed to platform: [win-x64, lin-x64].

name: Build VCV Rack Plugin
on: [push, pull_request]

env:
  rack-sdk-version: 2.3.0
  rack-plugin-toolchain-dir: /home/build/rack-plugin-toolchain

defaults:
  run:
    shell: bash

jobs:

  modify-plugin-version:
    name: Modify plugin version
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - run: |
          gitrev=`git rev-parse --short HEAD`
          pluginversion=`jq -r '.version' plugin.json`
          echo "Set plugin version from $pluginversion to $pluginversion-$gitrev"
          cat <<< `jq --arg VERSION "$pluginversion-$gitrev" '.version=$VERSION' plugin.json` > plugin.json
        # only modify plugin version if no tag was created
        if: "! startsWith(github.ref, 'refs/tags/v')"

  build:
    name: ${{ matrix.platform }}
    needs: modify-plugin-version
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/qno/rack-plugin-toolchain-win-linux
      options: --user root
    strategy:
      matrix:
        platform: [win-x64, lin-x64]
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - name: Build plugin
        run: |
          export PLUGIN_DIR=$GITHUB_WORKSPACE
          pushd ${{ env.rack-plugin-toolchain-dir }}
          make plugin-build-${{ matrix.platform }}
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          path: ${{ env.rack-plugin-toolchain-dir }}/plugin-build
          name: ${{ matrix.platform }}

  build-mac:
    name: mac
    needs: modify-plugin-version
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        platform: [x64, arm64]
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - name: Get Rack-SDK
        run: |
          pushd $HOME
          curl -o Rack-SDK.zip https://vcvrack.com/downloads/Rack-SDK-${{ env.rack-sdk-version }}-mac-${{ matrix.platform }}.zip
          unzip Rack-SDK.zip
      - name: Build plugin
        run: |
          CROSS_COMPILE_TARGET_x64=x86_64-apple-darwin
          CROSS_COMPILE_TARGET_arm64=arm64-apple-darwin
          export RACK_DIR=$HOME/Rack-SDK
          export CROSS_COMPILE=$CROSS_COMPILE_TARGET_${{ matrix.platform }}
          make dep
          make dist
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          path: dist/*.vcvplugin
          name: mac-${{ matrix.platform }}

  publish:
    name: Publish plugin
    # only create a release if a tag was created that is called e.g. v1.2.3
    # see also https://vcvrack.com/manual/Manifest#version
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    needs:  [build, build-mac]
    steps:
      - uses: actions/checkout@v3
      - uses: FranzDiebold/github-env-vars-action@v2
      - name: Check if plugin version matches tag
        run: |
          pluginversion=`jq -r '.version' plugin.json`
          if [ "v$pluginversion" != "${{ env.CI_REF_NAME }}" ]; then
            echo "Plugin version from plugin.json 'v$pluginversion' doesn't match with tag version '${{ env.CI_REF_NAME }}'"
            exit 1
          fi
      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ github.ref }}
          name: Release ${{ env.CI_REF_NAME }}
          body: |
            ${{ env.CI_REPOSITORY_NAME }} VCV Rack Plugin ${{ env.CI_REF_NAME }}
          draft: false
          prerelease: false
      - uses: actions/download-artifact@v3
        with:
          path: _artifacts
      - name: Upload release assets
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          file: _artifacts/**/*.vcvplugin
          tag: ${{ github.ref }}
          file_glob: true
5 Likes

Hi @qno, I just wanted to take the time to thank you for your efforts in sharing this work with all of us VCV Rack developers. It is tremendously helpful to be able to cross-compile for all platforms every time I push a change to my plugin. Finding build errors before submitting is very nice! Thank you very much.

5 Likes

I updated the workflow, now using the recently introduced RACK-SDK-latest-$platform-$arch.zip SDK version. This will now also for the Mac builds always use the most recent version of the Rack-SDK.

name: Build VCV Rack Plugin
on: [push, pull_request]

env:
  rack-sdk-version: latest
  rack-plugin-toolchain-dir: /home/build/rack-plugin-toolchain

defaults:
  run:
    shell: bash

jobs:

  modify-plugin-version:
    name: Modify plugin version
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - run: |
          gitrev=`git rev-parse --short HEAD`
          pluginversion=`jq -r '.version' plugin.json`
          echo "Set plugin version from $pluginversion to $pluginversion-$gitrev"
          cat <<< `jq --arg VERSION "$pluginversion-$gitrev" '.version=$VERSION' plugin.json` > plugin.json
        # only modify plugin version if no tag was created
        if: "! startsWith(github.ref, 'refs/tags/v')"

  build:
    name: ${{ matrix.platform }}
    needs: modify-plugin-version
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/qno/rack-plugin-toolchain-win-linux
      options: --user root
    strategy:
      matrix:
        platform: [win-x64, lin-x64]
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - name: Build plugin
        run: |
          export PLUGIN_DIR=$GITHUB_WORKSPACE
          pushd ${{ env.rack-plugin-toolchain-dir }}
          make plugin-build-${{ matrix.platform }}
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          path: ${{ env.rack-plugin-toolchain-dir }}/plugin-build
          name: ${{ matrix.platform }}

  build-mac:
    name: mac
    needs: modify-plugin-version
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        platform: [x64, arm64]
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - uses: actions/cache@v3
        id: plugin-version-cache
        with:
          path: plugin.json
          key: ${{ github.sha }}-${{ github.run_id }}
      - name: Get Rack-SDK
        run: |
          pushd $HOME
          wget -O Rack-SDK.zip https://vcvrack.com/downloads/Rack-SDK-${{ env.rack-sdk-version }}-mac-${{ matrix.platform }}.zip
          unzip Rack-SDK.zip
      - name: Build plugin
        run: |
          CROSS_COMPILE_TARGET_x64=x86_64-apple-darwin
          CROSS_COMPILE_TARGET_arm64=arm64-apple-darwin
          export RACK_DIR=$HOME/Rack-SDK
          export CROSS_COMPILE=$CROSS_COMPILE_TARGET_${{ matrix.platform }}
          make dep
          make dist
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          path: dist/*.vcvplugin
          name: mac-${{ matrix.platform }}

  publish:
    name: Publish plugin
    # only create a release if a tag was created that is called e.g. v1.2.3
    # see also https://vcvrack.com/manual/Manifest#version
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    needs:  [build, build-mac]
    steps:
      - uses: actions/checkout@v3
      - uses: FranzDiebold/github-env-vars-action@v2
      - name: Check if plugin version matches tag
        run: |
          pluginversion=`jq -r '.version' plugin.json`
          if [ "v$pluginversion" != "${{ env.CI_REF_NAME }}" ]; then
            echo "Plugin version from plugin.json 'v$pluginversion' doesn't match with tag version '${{ env.CI_REF_NAME }}'"
            exit 1
          fi
      - name: Create Release
        uses: softprops/action-gh-release@v1
        with:
          tag_name: ${{ github.ref }}
          name: Release ${{ env.CI_REF_NAME }}
          body: |
            ${{ env.CI_REPOSITORY_NAME }} VCV Rack Plugin ${{ env.CI_REF_NAME }}
          draft: false
          prerelease: false
      - uses: actions/download-artifact@v3
        with:
          path: _artifacts
      - name: Upload release assets
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          file: _artifacts/**/*.vcvplugin
          tag: ${{ github.ref }}
          file_glob: true
7 Likes

Hi @qno, I notice you switched from using curl to wget. I’m curious why you changed that.

Because with curl it is not possible to rename the file when the download url has been redirected, which just works fine with wget.

1 Like

I’m trying out your script (thank you so much btw, this is so useful!) but getting an error when trying to create a release. The builds on each platform succeed but the Publish Plugin step fails with the following error:

👩‍🏭 Creating new GitHub release for tag refs/tags/v2.0.1...
⚠️ GitHub release failed with status: 403
undefined
retrying... (2 retries remaining)
👩‍🏭 Creating new GitHub release for tag refs/tags/v2.0.1...
⚠️ GitHub release failed with status: 403
undefined
retrying... (1 retries remaining)
👩‍🏭 Creating new GitHub release for tag refs/tags/v2.0.1...
⚠️ GitHub release failed with status: 403
undefined
retrying... (0 retries remaining)
❌ Too many retries. Aborting...
Error: Too many retries.

I’m using the same version number in plugin.json and the git tag. What am I doing wrong?

Here’s a link to the failed job: Build VCV Rack Plugin · epadilla/patina@c48da1f · GitHub

Thanks!

Most likely permissions. Put the following at the top of your workflow:

name: Build VCV Rack Plugin
permissions:
  contents: write
...
2 Likes

That fixed it! Thank you

1 Like

Just as a heads-up (or an appeal for help), a few days ago I started seeing this warning in GitHub actions:

Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3, actions/cache@v3. For more information see: GitHub Actions: Transitioning from Node 16 to Node 20 - The GitHub Blog.

Might be blatantly obvious what to do, I admit, but figured that since this is the place where the knowledge is…

mahlen

Oh I saw that too

A quick google convinced me swapping v3 to v4 would do it but I didnt try that yet

I was just doing the same thing. I’ve verified in the history notes for both cache and checkout that the v4 versions are on node 20.

I just pushed these changes to one of my repos, and I’ll let y’all know what happens.

1 Like

Thanks Paul!

Depending on your particular workflow, you’ll probably have multiple references to these actions, so make sure you update them all.

In addition to actions/checkout and actions/cache, I had to update actions/upload-artifact, actions/download-artifact.

actions/upload-artifact has breaking changes as artifacts are now immutable, but you can add overwrite: true to the with:.

I still have one last node deprecation warning for svenstaro/upload-release-action@v2 for my “nightlies”. The repo for the action includes the change (from 3 months ago) to use node 20, but apparently requires a new release to carry the change. The latest issue opened last week is about the node 16 deprecation, requesting a release.

I don’t know what to do about this one.

For now I’m tolerating the warning. Everything seems to be working with the updates to all the actions with available updates.

2 Likes