How to Publish Winget and Chocolatey Packages with Github Actions

7 min read

Greetings! Today we are excited to share that we now publish Dolt releases on both winget and Chocolatey, making Dolt even easier to install for our Windows users. Prior to this, Windows users had to visit Dolt's releases page to download and run the latest MSI.

Old documentation

Luckily, one of our users opened an issue notifying us that they want Dolt available through Chocolatey (turns out this had been a long requested issue), which prompted us to get our asses in gear and make it happen—which we did! We encourage all of our users to open issues for Dolt and DoltHub or to reach out to us in Discord if there's something we can do to better serve them.

TL;DR

You can now install the latest Dolt release on Windows using either winget:

$ winget install dolt

or choco:

$ choco install dolt --version=0.30.3

How We Publish winget and Chocolatey packages on Release

If you're curious about how we automatically publish Dolt to each of these package managers, stick around! I'll provide some of the details below.

Release button

Unfortunately, to release Dolt we don't have a super cool, gigantic, red release button (yet! 🤠). Instead we run a GitHub Actions workflow that builds the latest Dolt binaries and triggers a few asynchronous workflows. One of those workflows is housed in our dolthub/windows-msi-creator repository, and is responsible for building the MSI and posting it to a release's page under the "Assets" section. Here's a condensed view of the workflow that does this:

MSI workflow yaml

name: Upload Windows MSI to Dolt Release
on:
  repository_dispatch:
    types: [ upload-msi ]

jobs:
  get-release-id:
  ...
  get-version:
  ...
  build-release-binaries:
  ...

  upload-windows-msi:
  ...

  bump-dolt-packages:
    needs: [get-version, upload-windows-msi]
    runs-on: ubuntu-18.04
    steps:
      - name: Trigger Bump Winget
        uses: peter-evans/repository-dispatch@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          event-type: bump-winget
          repository: dolthub/dolt
          client-payload: '{"version": "${{ needs.get-version.outputs.version }}"}'
      - name: Trigger Bump Chocolatey
        uses: peter-evans/repository-dispatch@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }}
          event-type: bump-chocolatey
          repository: dolthub/chocolatey-packages
          client-payload: '{"version": "${{ needs.get-version.outputs.version }}"}'

As you can see from the workflow above, we run a few jobs that do the work of building and posting Dolt's MSI. get-release-id sets the release id we use in subsequent jobs and get-version does the same with the Dolt version number. build-release-binaries builds the binary used to create the MSI and finally upload-windows-msi creates the MSI from the binary then posts it to the release's page in our dolthub/dolt repository.

To start publishing packages on winget and Chocolatey, we added the bump-dolt-packages job, which simply kicks off two more asynchronous workflows that take care of the building and publishing of the latest Dolt packages.

The bump-winget workflow is defined below, and once triggered, uses wingetcreate to automatically create a winget pull request with the latest MSI:

winget workflow yaml

name: Bump Dolt on winget

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'SemVer format release tag, i.e. 0.24.5'
        required: true
  repository_dispatch:
    types: [ bump-winget ]

jobs:
  winget-bump:
    name: Bump Dolt winget
    runs-on: windows-2019
    defaults:
      run:
        shell: powershell
    steps:
      - name: Get version
        id: get_version
        run: |
          version=""
          if [ "${{ github.event_name }}" == "repository_dispatch" ]
          then
            version="${{ github.event.client_payload.version }}"
          else
            version="${{ github.event.inputs.version }}"
          fi
          if [[ $version == v* ]]; then
            version="${version:1}"
          fi
          echo "::set-output name=version::$version"
      - name: Create winget PR
        run: |
          iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
          .\wingetcreate.exe update DoltHub.Dolt -u $Env:URL -v $Env:VERSION -t $Env:TOKEN --submit
        env:
          TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
          VERSION: ${{ steps.get_version.outputs.version }}
          URL: ${{ format('https://github.com/dolthub/dolt/releases/download/v{0}/dolt-windows-amd64.msi', steps.get_version.outputs.version) }}

The bump-chocolatey workflow was a bit trickier to figure out, since there's no off-the-shelf Github Action Chocolatey package updater. So, we used Chocolatey's recommended Automatic Package Updater Module.

To start, we forked the template repository to create dolthub/chocolatey-packages, then added a workflow for creating and pushing the latest Dolt NuGet package the updater module produces.

Chocolatey workflow yaml

name: Bump Dolt on Chocolatey

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'SemVer format release tag, i.e. 0.24.5'
        required: true
      force:
        description: 'force push package'
        required: false
        default: 'false'
  repository_dispatch:
    types: [ bump-chocolatey ]

jobs:
  get-version:
    name: Get Version
    runs-on: ubuntu-18.04
    outputs:
      version: ${{ steps.get_version.outputs.version }}
    steps:
      - name: Get version
        id: get_version
        run: |
          version=""
          if [ "${{ github.event_name }}" == "repository_dispatch" ]
          then
            version="${{ github.event.client_payload.version }}"
          else
            version="${{ github.event.inputs.version }}"
          fi
          echo "::set-output name=version::$version"
  chocolatey-bump:
    needs: get-version
    name: Bump Dolt Chocolately
    runs-on: windows-2019
    defaults:
      run:
        shell: powershell
    steps:
      - uses: actions/checkout@v2
      - name: Install AU
        run: cinst au
      - name: Build Package
        working-directory: ./dolt
        run: |
          ./update.ps1
        env:
          au_Push: 'false'
          au_Force: ${{ github.event.inputs.force }}
          VERSION: ${{ needs.get-version.outputs.version }}
      - name: Test Package Installer
        working-directory: ./dolt
        run: Test-Package $Install
      - name: Dolt Version
        run: |
          refreshenv
          $env:Path += ';C:\Program Files\Dolt\bin\'
          dolt version
      - uses: EndBug/add-and-commit@v7
        with:
          message: "[ga-bump-dolt-chocolatey] Bumping Dolt on Chocolatey ${{ needs.get-version.outputs.version }}"
          add: "."
          cwd: "."
      - name: Push Package to Chocolatey
        run: Push-Package
        working-directory: ./dolt
        env:
          api_key: ${{ secrets.CHOCO_API_KEY }}
          au_Force: ${{ github.event.inputs.force }}

This workflow runs a custom update.ps1 script to download and build the version supplied by the repository_dispatch client payload. It then updates the dolt.nuspec file to match the latest version, and packages everything in a .nupkg.

As you can see in the above workflow, the Chocolatey Automatic Updater Module makes it really easy to test the newly created package with a single command, Test-Package $Install, and we take an additional step to actually run dolt version as a sanity check. Finally, pushing to Chocolatey is just as simple, with Push-Package.

That's basically it! Now on Dolt releases these asynchronous workflows get triggered and publish to the package managers we've specified. You'll also notice these workflow files handle workflow_dispatch events as well. It's a helpful practical measure for us to be able to trigger these various workflows manually, in the event that they fail. Happy yamling everyone!

Chocolatey workflow yaml

DoltHub is hiring! We want the builders of the future who are ready to disrupt the database industry and version the world's open data. We have a range of positions available, so if you're interested in working with us, let us know!

Curious about Dolt, DoltHub and versioned databases? There's no better place to get started than DoltHub.com where you can download Dolt, host your own public and private Dolt databases, or janky deploy any public database!

Questions, comments, or looking to start backing your application with a Dolt database? Get in touch with our team here or join us on Discord!

SHARE

JOIN THE DATA EVOLUTION

Get started with Dolt