Skip to content

Publish a signed and notarized macOS desktop DMG with releases #642

Description

@RanaAhmar

Problem

The desktop workflow already builds a macOS DMG, but the public GitHub releases currently expose container assets only. That leaves macOS users needing to clone the repository and build the desktop app themselves.

Proposal

Publish the macOS desktop installer as a GitHub Release asset.

  • Upload the Apple Silicon DMG produced by the desktop workflow to the corresponding release.
  • Sign it with an Apple Developer ID certificate, notarize it with Apple, and staple the notarization ticket so Gatekeeper accepts the download without an unidentified-developer warning.
  • Document the supported macOS architecture(s) and installation path in the release notes.
  • Consider adding an Intel or universal build if that remains a supported target.

Context

I successfully built the existing desktop target on Apple Silicon. The current workflow already produces a DMG and verifies an ad-hoc signature, so this appears to be mainly a release-publishing and Apple signing/notarization integration task.

I would be happy to prepare a focused PR after maintainers confirm the preferred release trigger, asset naming, and how they want signing credentials managed.

Activity

  1. Hotragn commented on Sep 30, 2026

    @Hotragn
    Contributor

    Not a maintainer, but you asked three questions before starting and the repo already answers two of them, so here is what I found — plus one wrinkle that I think is the real design question.

    First, this is a named, deliberately deferred step rather than an oversight. desktop.yml:50:

    The three artifacts. Not bundle, which signs and notarizes: that is S7 and needs certificates this workflow deliberately does not hold.

    and the ad-hoc signature you saw is APPLE_SIGNING_IDENTITY: '-' at :106. So signing and notarization are tracked as S7. Worth referencing that in your PR, so a maintainer reads it as picking up S7 rather than a new idea arriving from outside the plan.

    How signing credentials are managed — answered by precedent. Windows is already done, in desktop-signing.yml with docs/windows-signing.md, and I would mirror its shape closely:

    • a protected GitHub environment (windows-signing) holding the credential, rather than a repository secret;
    • OIDC (id-token: write) to Azure Key Vault, so no long-lived certificate sits in secrets at all;
    • opt-in only — workflow_dispatch with an explicit signing-mode, or a windows-signing label on a PR;
    • a separate checks job that runs signing regressions with no credential access;
    • signing gated on github.event.pull_request.head.repo.full_name == github.repository, so a fork can never reach the certificate.

    One place I am not sure the pattern transfers: the Windows side gets its credential-free property from OIDC federation to Key Vault. It is worth checking early whether Apple's notarization offers anything comparable. If it does not, a long-lived App Store Connect key in a protected environment is probably the closest equivalent — and it would be the one point where the macOS workflow cannot simply copy the Windows one, which is worth stating in the PR rather than leaving a reviewer to discover.

    The release trigger — also answered. publish-release.yml runs on push to main, classifies from the merged PR rather than the commit message, and says outright that "Nothing here is dispatched by hand" — the tag is created by the workflow. Today it attaches only container-images.json (:430-434, via gh release upload … --clobber), which is why you see container assets and nothing else.

    The wrinkle: the DMG and the release are built by two different workflows. The DMG comes out of desktop.yml as an upload-artifact; the release is published by publish-release.yml, a separate workflow on a separate run. An artifact from one run is not simply there for another, so "upload the DMG the desktop workflow produced" needs a decision:

    1. a macOS build-sign-notarize job inside publish-release.yml, so the release builds its own DMG from the release commit; or
    2. fetch the artifact across workflow runs, which ties the release to some other run having built that exact commit.

    I would lean toward the first — publish-release.yml is built on the release being "always a reviewed commit on main", and building the installer from that same commit keeps the property; the second makes it depend on whichever desktop run happened to go first. But it is the maintainers' call, and it is probably the question to ask before writing anything.

    Your remaining question, asset naming, I could not find a precedent for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions