A version tag now builds, signs and ships bisque-voice on five platforms

2 hours ago

Pull request 2 adds one file that matters, a 640 line release workflow. Push a tag that starts with v, and GitHub builds bisque-voice for five platforms, tests every build, signs the macOS ones, and publishes the results. The pull request body says only, update bisque-voice. The reasoning sits in the comments inside the workflow, so that's what this walks through.

Ask about this presentation

Chapters

  1. 0:00A version tag ships it
  2. 0:24Three stages
  3. 0:47Pinned model packs
  4. 1:10Five build legs
  5. 1:39Checks on every leg
  6. 2:11Real audio on Intel
  7. 2:38Signing and notarizing
  8. 3:04Verifiable downloads
  9. 3:31What to review
Show transcript
  1. Pull request 2 adds one file that matters, a 640 line release workflow. Push a tag that starts with v, and GitHub builds bisque-voice for five platforms, tests every build, signs the macOS ones, and publishes the results. The pull request body says only, update bisque-voice. The reasoning sits in the comments inside the workflow, so that's what this walks through.

    Slide text
    bisque-cloud/bisque-voice · .github/workflows/release.yml

    A version tag now ships bisque‑voice

    Five platforms built, tested, signed and published from one push.

  2. The workflow runs in stages. The packs job reads the published checksum of every model pack. Then the build job fans out across five runners, and each one builds, tests, smoke tests, signs and attests its binary. Finally the binaries go to download.bisque.today and to this repository's Releases. Every job runs on a GitHub hosted runner.

    Slide text
    Tag Packs Build Sign Verify

    Packs first, then builds, then publishing

    Packs Read the checksum of each model pack
    Build Five platforms: build, test, smoke test, sign, attest
    Publish download.bisque.today and GitHub Releases
  3. The packs job reads the published SHA-256 for ten model packs. That covers Kokoro, the Qwen3 clones and voices, the pronunciation data, and the aligners. Each checksum gets compiled into the binary, and a build with no checksum refuses to download that pack. So a pack has to be published before the release that pins it. If it isn't, the job stops with this message.

    Slide text
    Tag Packs Build Sign Verify

    Every binary pins the checksum of every model pack

    // packs job fails the release if a pack is missing
    $ver is not published yet;
    publish the pack before releasing
    a binary that pins it

    10 packs · SHA-256 compiled in as BISQUE_VOICE_PACK_SHA256_<ID>

  4. Four of the legs build the default feature set, Kokoro and the Qwen3 engines, on Mac Arm, Linux x86, Linux Arm and Windows. The Intel Mac leg is the exception. ONNX Runtime publishes no build for Intel macOS, so that binary carries the Qwen3 engines only, and reports Kokoro as unavailable with the reason. It also pins macOS 13 as the oldest version it must run on, because many surviving Intel Macs stop at Ventura.

    Slide text
    Tag Packs Build Sign Verify

    Five native builds, and Intel macOS leaves out Kokoro

    macOS Arm aarch64-apple-darwin
    Linux x86 x86_64-unknown-linux-gnu
    Linux Arm aarch64-unknown-linux-gnu
    Windows x86_64-pc-windows-msvc
    macOS Intel ONNX Runtime publishes no Intel macOS build, so it builds with --no-default-features and targets macOS 13.0
  5. First, the tag has to match the version in Cargo.toml. The published path is immutable, so a mismatch would ship a binary whose version names another release. Second, the tests run against the real packs, because the comments point out a skipped test never fails. Third, the smoke test starts the binary, runs doctor, and checks that every checksum was compiled in. It also checks that the number of installable engines equals the number pinned, so a forgotten checksum breaks the build, not someone's download.

    Slide text
    Tag Packs Build Sign Verify

    Each leg proves its binary before anything is signed

    Tag matches the crate a tag that differs from the Cargo.toml version fails the build
    Tests see real packs "a skipped test never fails", so the exact packs are fetched and verified
    Smoke test counts pins engines reporting installable must equal engines pinned
  6. The Intel binary can't run Kokoro, so it gets a stronger test. It downloads the published 0.6B clone pack, verifies its checksum, and synthesizes a sentence to an mp3. The step fails if the output reports no duration or the file is empty. The comment says it plainly: the engines list saying the right thing is not audio. The smoke test also confirms that installing Kokoro on this build refuses, and says why.

    Slide text
    Tag Packs Build Sign Verify

    The Intel leg synthesizes real speech

    bisque-voice \
      --text "This narration was
        synthesized on an Intel Mac,
        as a release check." \
      --voice qwen3-clone-06b:default \
      --out smoke.mp3

    "engines --json saying the right thing is not audio."

    Also checked: install kokoro must refuse, citing Intel Macs

  7. On the two Apple legs, the workflow imports the signing certificate into a temporary keychain, signs the binary with the Developer ID, then verifies the signature. Notarization follows, using credentials from repository secrets. The binary requests no entitlements, and the comment explains why. install.sh checks the same team ID, and this pull request fixes its comment to point at release.yml.

    Slide text
    Tag Packs Build Sign Verify

    Both macOS binaries are signed and notarized

    codesign --force --options=runtime \
      --sign "$DEVELOPER_ID_NAME" --timestamp "$BIN"
    codesign --verify --strict --verbose=2 "$BIN"

    "it holds no credentials and never touches the Keychain, so a bare hardened-runtime signature is enough."

  8. Every binary and every archive gets a build provenance attestation. So anyone can run gh attestation verify and confirm the download was built in this repository, from this commit, by this workflow. The secrets sit in a release environment that only v tags can use, and only repository admins can create those tags. Uploads authenticate with the workflow's own GitHub identity, so there's no stored cloud key to leak.

    Slide text
    Tag Packs Build Sign Verify

    Anyone can check that a download was built here

    gh attestation verify bisque-voice \
      --repo bisque-cloud/bisque-voice
    Secrets live in the release environment, which only v* tags can use
    Uploads sign in with the workflow's own GitHub identity, with no stored cloud key
  9. One limit to keep in mind. The release depends on the model packs being published first, and an unpublished pack stops the whole run. Publishing to the download site and to Releases is the part to read most closely. The other two changes are small. The README loses its joke about being written in Rust, and the install.sh comment now names release.yml. Pushing a version tag now ships bisque-voice.

    Slide text
    Open pull request · bisque-cloud/bisque-voice #2

    Read the publish steps closely before tagging

    The release is only as good as the packs: an unpublished pack stops the whole run.

    Also in this pull request
    README drops "Oh, and did I mention that it's written in Rust."
    install.sh comment points at release.yml

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built in New York with ❤️