Skip to content

ci(release): publish macOS desktop assets#150

Open
fettpl wants to merge 4 commits into
sybil-solutions:mainfrom
fettpl:fix/release-macos-assets-147
Open

ci(release): publish macOS desktop assets#150
fettpl wants to merge 4 commits into
sybil-solutions:mainfrom
fettpl:fix/release-macos-assets-147

Conversation

@fettpl

@fettpl fettpl commented Jun 20, 2026

Copy link
Copy Markdown

Summary

Addresses #147 by publishing signed and notarized Apple Silicon desktop assets without putting semantic-release or ordinary releases behind owner-managed signing secrets.

This PR remains stacked on #149. Merge #149 first; its version-alignment commit is the base for this asset workflow.

Changes

  • Keeps semantic-release on ubuntu-latest with Node 22.19.0.
  • Exposes the release version only from @semantic-release/exec's success lifecycle, so the desktop path runs only after an actual release publication.
  • Checks the five signing/notarization secrets without failing when they are absent.
  • Runs a separate macos-latest job only when a release exists and signing is configured.
  • Scopes Apple credentials to the Electron Builder step and GITHUB_TOKEN to the upload step.
  • Applies the semantic-release version before the explicit notarized desktop build.
  • Fails before upload unless the built app passes codesign, stapler, and Gatekeeper validation.
  • Reuses and tests main's scripts/stage-desktop-release.mjs instead of maintaining duplicate verification/staging scripts.
  • Stages hyphenated versioned DMG, ZIP, blockmap, and updater metadata names matching the published v2.0.0 latest-mac.yml contract.
  • Adds stable Local-Studio-arm64.dmg and Local-Studio-arm64-mac.zip aliases.
  • Updates README.md and AGENTS.md for the automated release path.

A separate release: published workflow is not used because releases created with the repository GITHUB_TOKEN do not trigger another workflow run. The conditional job in the existing workflow avoids that recursion guard.

v2.0.0 Audit

The published release confirms that version alignment is correct: the app bundle, tag, and updater metadata all report 2.0.0; the app is arm64 with bundle id org.local.studio.desktop; and the published updater metadata resolves to the attached hyphenated versioned assets.

The downloaded versioned DMG exactly matches GitHub's published SHA-256 64ca37a5e9085e0a8a5d8452f7a544a684c37d9bab874f417d0b87e8cab085a8, but the app inside does not pass release validation:

  • codesign --verify --deep --strict reports an invalid or modified signature.
  • spctl --assess --type execute rejects it as an unnotarized Developer ID app.
  • xcrun stapler validate reports no stapled ticket.
  • The stable DMG alias has the same digest, and the stable ZIP alias is absent.

The ZIP signature has not been independently inspected.

Owner-Pending Steps

@0xSero needs to:

  • Merge release: align desktop release versions #149 before this PR.
  • Configure CSC_LINK, CSC_KEY_PASSWORD, APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, and APPLE_TEAM_ID.
  • Confirm the certificate matches Electron Builder identity sherif cherfa (TZ447KHNZL), or update that configuration.
  • Replace the v2.0.0 DMG assets with a signed, notarized, stapled rebuild and inspect the ZIP from the same build.
  • Add Local-Studio-arm64-mac.zip to v2.0.0 if the stable ZIP alias remains part of the release contract.
  • Re-run codesign, spctl, stapler validation, and a clean first launch on the replacement artifact. That real-artifact check is the remaining Homebrew blocker.

Validation

  • npm run test:release-assets (6 tests)
  • npm run test:release-version (2 tests)
  • Release workflow YAML parse and semantic-release configuration assertion
  • npm run check
    • frontend quality/build and 202 unit tests
    • controller quality checks and 146 unit tests
  • npm --prefix frontend run test (202 tests)
  • npm run test:integration
    • 118 controller integration tests
    • 240 frontend regression tests
  • Mandatory pre-push frontend quality gate
  • git diff --check origin/main...HEAD

AI Disclosure

AI assistance was used to inspect and reconcile the current release workflow, verify the published v2.0.0 metadata and DMG, implement and test the conditional asset pipeline, run validation, and review the final diff. I reviewed the resulting code, artifact metadata, and command output before updating this PR.

@0xSero

0xSero commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks — the asset verification scripts and the TDD here are genuinely good. Two blockers before this can merge:

  1. It would break the release pipeline as-is. validate-desktop-release-env.mjs hard-fails semantic-release's prepare step whenever the signing secrets are missing — and they aren't configured yet (owner-only). With this repo's releaseRules nearly every push to main triggers a release, so merging now means no tags/releases at all until secrets exist. Please make missing secrets skip the desktop-asset build, or better: split asset building into a separate macOS job triggered on release: published. That also keeps semantic-release on ubuntu instead of paying 10x macos-runner billing on every one-line merge.
  2. Stable asset names. The marketing site downloads via releases/latest/download/Local-Studio-arm64.dmg (see docs/publish-desktop-release.md). Versioned-only, space-containing names (Local Studio-1.49.1-arm64.dmg) would 404 that link once releases/latest moves. Please also attach stable-named copies.

Also needs a rebase after #149 lands (main deleted CONTRIBUTING.md and renamed the product to "Local Studio" — labels/fixtures still say vLLM Studio). I'll get the signing secrets configured on my side; the graceful-degradation rework is the part I'd like from you.

@fettpl

fettpl commented Jul 13, 2026

Copy link
Copy Markdown
Author

@0xSero the graceful-degradation and stable-name rework is pushed in 77572922.

  • Semantic-release stays on Ubuntu.
  • Its success hook exposes a version only when a release was actually published.
  • Missing signing secrets emit configured=false and skip the macOS job without failing the tag or release notes.
  • The conditional macOS job builds only for a real release with all five secrets configured.
  • Versioned updater assets are retained, and stable Local-Studio-arm64.dmg / Local-Studio-arm64-mac.zip copies are uploaded for the site.
  • Signing credentials are scoped only to the build step; the GitHub token is scoped only to upload.

I kept this in the existing workflow because a release created with GITHUB_TOKEN cannot trigger a second release.published workflow under GitHub's recursion guard.

Validation is green: 7 release-asset tests, 2 version tests, contracts/structure, frontend quality and production build, controller checks, and 139 controller unit tests. The pre-push gate also passed while updating both branches.

Owner-pending after merging #149 and this PR: configure the five signing/notarization secrets, confirm the certificate identity, then validate the first attached DMG/ZIP with codesign, spctl, and a clean launch.

@fettpl
fettpl force-pushed the fix/release-macos-assets-147 branch from 7757292 to 10c2aab Compare July 16, 2026 18:45
@fettpl

fettpl commented Jul 16, 2026

Copy link
Copy Markdown
Author

@0xSero conflicts are resolved and the asset workflow is rebased onto #149 at 10c2aab2. It now uses main’s staging implementation, preserves exact updater filenames, adds both stable aliases, runs the explicit notarized build, and keeps missing secrets as a non-failing skip. npm run check, 118 controller integration tests, 240 frontend regression tests, and the pre-push gate are green. GitHub reports the PR as mergeable. The CI and Security runs are action_required with no jobs created and need maintainer approval; your requested review and the owner-managed signing setup/first real-artifact validation also remain.

@fettpl

fettpl commented Jul 17, 2026

Copy link
Copy Markdown
Author

@0xSero v2.0.0 follow-up is pushed in e4364a39. The staging test now matches the release’s hyphenated latest-mac.yml URLs while retaining both stable aliases, and the macOS job now blocks upload unless the app passes codesign, stapler, and Gatekeeper checks. Release audit: the versioned DMG matches GitHub SHA-256 64ca37a5e9085e0a8a5d8452f7a544a684c37d9bab874f417d0b87e8cab085a8, contains arm64 Local Studio 2.0.0 with bundle id org.local.studio.desktop, but fails codesign --verify --deep --strict, is rejected by spctl as unnotarized, and has no stapled ticket. The stable DMG is the same digest; the stable ZIP alias is absent. Please replace the v2.0.0 DMGs with a signed/notarized/stapled rebuild, inspect the ZIP from that build, and add the stable ZIP alias if retained. Full repository, unit, integration/regression, and pre-push validation is green.

@fettpl
fettpl force-pushed the fix/release-macos-assets-147 branch from e4364a3 to b62e3ac Compare July 19, 2026 19:07
@fettpl

fettpl commented Jul 19, 2026

Copy link
Copy Markdown
Author

@0xSero PR #150 is restacked on the resolved #149 head and is now mergeable at b62e3ac0; it remains blocked only on review/workflow approval.

The rebase preserves the v2 updater-compatible asset names and stable aliases. It also pins the desktop job checkout to github.event.workflow_run.head_sha, ensuring the macOS build uses the same CI-tested revision as semantic-release after the upstream trigger change.

Clean-worktree verification passed: all 8 release tests, npm run check, both pre-push gates, and desktop:dist. The rebuilt app was reinstalled and /api/desktop-health returned HTTP 200. Local distribution signing was skipped because the maintainer signing identity is unavailable; the release job still requires the configured signing/notarization secrets.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants