use cases

Checking a Draft GitHub Release Before Anyone Can Download It

Many projects don’t publish releases straight from CI. A tool such as GoReleaser builds everything and uploads it to a draft release on GitHub. A maintainer looks the draft over, edits the notes, and presses publish. Until then, nobody else can see it.

That review step is a good idea with one weakness: a person looking at a list of six file names can’t tell what’s inside them. The draft is the last moment a mistake is free to fix, and it’s exactly where an automatic check belongs.

Checking the Draft

rmqa reads a release straight from GitHub. Drafts have no public tag yet, so rmqa asks for the repository’s releases and picks the one with the tag name you give it. Drafts are only visible with a token, which rmqa takes from GITHUB_TOKEN or GH_TOKEN:

GITHUB_TOKEN=$(gh auth token) rmqa check --github acme/[email protected]

rmqa downloads every asset of the draft, opens each one, and checks the set against the manifest, exactly as it would check a local folder. Here the checksums file was written before the Windows zip finished uploading:

Checking github.com/acme/tidy release v2.3.0 for tidy 2.3.0

  ok    tidy_darwin_amd64.tar.gz  darwin/amd64
  ok    tidy_darwin_arm64.tar.gz  darwin/arm64
  ok    tidy_linux_amd64.tar.gz   linux/amd64
  ok    tidy_linux_arm64.tar.gz   linux/arm64
  ok    tidy_windows_amd64.zip    windows/amd64
  FAIL  SHA256SUMS
          tidy_windows_amd64.zip: is in the release but has no checksum here [checksum-missing-entry]

Not ready: 1 error, 0 warnings in 6 files.

The output above comes from a run against a stand-in for the GitHub API with the same files, since acme/tidy is an example project.

A GitHub Actions workflow where GoReleaser uploads a draft release and the rmqa action then checks the draft before anyone publishes it.

Without the check, the draft would have looked complete: six files, all the names right. Anyone verifying the Windows download against the checksums file would have found no line for it.

In the Workflow

Run the check as the last step of the job that made the draft. The action passes the workflow’s token, which can see drafts in its own repository:

- uses: goreleaser/goreleaser-action@v6
  with:
    args: release --clean
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check the draft release
  uses: softdevstudio/[email protected]
  with:
    github: ${{ github.repository }}@${{ github.ref_name }}

GoReleaser’s release.draft: true setting keeps the release a draft. When the rmqa step fails, the job goes red, the draft stays a draft, and the annotations on the run say which file is wrong and why.

Writing the Manifest From an Earlier Release

If the project already has good releases, the manifest can come from one of them:

GITHUB_TOKEN=$(gh auth token) rmqa init --github acme/[email protected] -o rmqa.toml

GoReleaser names archives like tidy_2.2.0_Darwin_x86_64.tar.gz by default. rmqa init recognises the version, Darwin and x86_64 in those names and writes name = "tidy_{version}_{os_name}_{arch_name}.{archive}", with each platform’s spelling stored in the manifest. The same manifest then checks every later version.