Skip to content

Add macOS artifacts to desktop release pipeline and unify publish flow#6

Merged
Derpedyea merged 3 commits into
mainfrom
feature/main
May 5, 2026
Merged

Add macOS artifacts to desktop release pipeline and unify publish flow#6
Derpedyea merged 3 commits into
mainfrom
feature/main

Conversation

@Derpedyea
Copy link
Copy Markdown
Member

@Derpedyea Derpedyea commented May 5, 2026

Summary

  • Added a prepare job in .github/workflows/desktop-release.yml to validate release config, enforce semver input, and generate a shared two-word release name.
  • Refactored windows release job to consume shared prepare outputs and upload installer artifacts for fan-in.
  • Added a new macos release job (dist:mac) that builds dmg + zip, validates mac release artifacts, checks latest-mac.yml, verifies code signature/zip/dmg integrity, and confirms ARM64 architecture.
  • Added a publish job to combine Windows/macOS artifacts, verify expected files and feed contents, create a multi-file GitHub release, push update feeds/assets to R2, and verify public feed propagation.
  • Updated desktop packaging config to support mac distribution (dist:mac) and include uiohook-napi/node-gyp-build in asarUnpack.
  • Updated dashboard copy in apps/dashboard/src/App.tsx and README.md to reflect cross-platform desktop delivery and hosted latest installers.
  • Extended worker update-feed parsing to support macOS artifact lookup and added tests in apps/worker/src/billing.test.ts.

Testing

  • Not run (not executed in this environment).
  • Workflow validation checks now include:
    • Semver and required env var/secret validation in prepare.
    • Windows/macos artifact presence and latest*.yml version/path assertions.
    • macOS integrity checks (codesign, hdiutil verify, unzip -t, and ARM64 lipo check).
    • Combined publish verification for .exe, .dmg, .zip, .blockmap, latest.yml, and latest-mac.yml.
    • Public feed reachability checks for both Windows and macOS update feeds via polling.

Summary by CodeRabbit

  • New Features

    • Added macOS desktop app support and a macOS download option.
    • Download button and marketing copy updated to offer both Windows and macOS choices.
  • Documentation

    • Desktop release docs updated to describe multi-platform publishing and hosted update feeds.
  • Tests

    • Added test coverage for parsing macOS update feed artifacts.

- Move release version/name/config validation into a shared prepare job
- Add macOS build, verification, artifact uploads, and publish flow alongside Windows
- Extend dashboard/workflow update feed handling for macOS .dmg/.zip artifacts
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Warning

Rate limit exceeded

@Derpedyea has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 59 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2f030654-87ca-4696-8305-5e19015dcf11

📥 Commits

Reviewing files that changed from the base of the PR and between 3b2fa36 and 9fa976f.

📒 Files selected for processing (1)
  • .github/workflows/desktop-release.yml
📝 Walkthrough

Walkthrough

Refactors the desktop release workflow into prepare/build/publish jobs, adds macOS packaging and release artifacts, generalizes update-feed parsing and download endpoints for macOS, updates marketing/UI copy and CSS, adds build scripts, tests, and README documentation for multi-platform releases.

Changes

Desktop release + macOS support

Layer / File(s) Summary
Workflow orchestration / CI metadata
.github/workflows/desktop-release.yml
Introduces prepare job that validates env/secrets and semver, emits version and release_name outputs, adds concurrency: group: desktop-release with cancel-in-progress: true, and restructures pipeline into prepare → platform builds → publish.
Build steps (Windows & macOS)
.github/workflows/desktop-release.yml
windows and macos jobs now depend on prepare, stamp apps/desktop/package.json with outputs, run build/typecheck, verify expected artifact filenames and update-feed YAML contents, and upload platform-specific artifact bundles.
Publish / Distribution
.github/workflows/desktop-release.yml
publish job downloads both platform artifacts, verifies latest.yml and latest-mac.yml advertise the expected version, uploads assets to the GitHub Release tag v<version>, publishes files to R2 with per-extension content-type/cache-control via aws s3 cp, and validates public feeds with retrying curl checks.
Packaging config & scripts
apps/desktop/package.json, package.json
Adds dist:mac script to build/package macOS (dmg/zip) via electron-builder and configures asarUnpack entries for native modules. Adds root script desktop:dist:mac.
Update-feed parsing & download endpoints
apps/worker/src/index.ts
Adds latestArtifactUrlFromYml(...) and extractLatestArtifactPath(...), generalizes latestUpdateArtifactUrl(...), adds latestMacDmgUrl(...), replaces prior single-purpose parsing with extension-normalized, validated extraction, and adds /downloads/laryn-mac-latest.dmg route that redirects to resolved URL or returns 503 if unavailable.
Marketing / UI / CSS
apps/worker/src/index.ts, apps/dashboard/src/App.tsx
Updates download page and dashboard copy to be platform-inclusive, introduces download-options grid/cards for Windows .exe and macOS .dmg, adjusts spec/hotkey copy (default modifier → “Super”), and adds responsive CSS (.download-meta, .download-options, .download-card, etc.).
Tests
apps/worker/src/billing.test.ts
Adds test that validates extraction of the latest macOS .dmg artifact path and full download URL construction from an update-feed YAML payload using the new helpers.
Documentation
README.md
Updates “Desktop releases” section to document manual workflow behavior for Windows + macOS, artifacts published to R2, and hosted download redirect paths.

Sequence Diagram

sequenceDiagram
    actor Developer as Developer
    participant GH as "GitHub Actions"
    participant Prep as "prepare job"
    participant Win as "windows job"
    participant Mac as "macos job"
    participant Pub as "publish job"
    participant Releases as "GitHub Releases API"
    participant R2 as "R2 Storage"
    participant Feed as "Public update feeds"

    Developer->>GH: Trigger desktop-release workflow
    GH->>Prep: start prepare
    Prep->>Prep: validate env & semver, emit version/release_name
    Prep-->>GH: outputs ready

    par Platform builds
      GH->>Win: start windows job (uses outputs)
      Win->>Win: stamp package.json, build, verify .exe/.yml, upload artifacts
    and
      GH->>Mac: start macos job (uses outputs)
      Mac->>Mac: stamp package.json, build, verify .dmg/.zip/.yml, upload artifacts
    end

    GH->>Pub: start publish job (depends on artifacts)
    Pub->>Pub: download artifacts, validate latest.yml and latest-mac.yml
    Pub->>Releases: upload assets (exe, dmg, zip, blockmap, yml)
    Pub->>R2: publish files with content-type/cache-control
    Pub->>Feed: validate public feeds (curl retry loop)
    Pub-->>Developer: release completed
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I stitched two builds into one release,
Windows and mac in tidy peace.
Jobs prepare, then build, then share,
Feeds float files through cloud-held air.
A rabbit cheers—artifacts take flight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the primary objective: adding macOS artifacts to the desktop release pipeline and consolidating the publish workflow into a unified multi-platform process.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/main

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Derpedyea
Copy link
Copy Markdown
Member Author

bugbot run verbose=true

@cursor
Copy link
Copy Markdown

cursor Bot commented May 5, 2026

Bugbot request id: serverGenReqId_53940c63-c4ba-4366-9d0e-4419e66ad1a0

@Derpedyea
Copy link
Copy Markdown
Member Author

bugbot run

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 5, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
laryn-transcribe 9fa976f May 05 2026, 03:43 PM

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/desktop-release.yml:
- Around line 14-16: The concurrency group currently uses desktop-release-${{
inputs.version }} so different versions can run concurrently and race on shared
keys (latest.yml / latest-mac.yml); change the concurrency group to a constant
value like desktop-release (remove ${{ inputs.version }}) and enable
cancel-in-progress: true so only one desktop release workflow runs at a time and
newer runs cancel older ones, preventing out-of-order uploads.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 322c8881-34ed-4f48-9b80-3e23cc3487bc

📥 Commits

Reviewing files that changed from the base of the PR and between 3a08cff and 6c6fec9.

⛔ Files ignored due to path filters (1)
  • apps/desktop/assets/logo.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • .github/workflows/desktop-release.yml
  • README.md
  • apps/dashboard/src/App.tsx
  • apps/desktop/package.json
  • apps/worker/src/billing.test.ts
  • apps/worker/src/dashboard-assets.ts
  • apps/worker/src/index.ts
  • package.json

Comment thread .github/workflows/desktop-release.yml Outdated
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 9 files

Confidence score: 2/5

  • There is a concrete merge risk in .github/workflows/desktop-release.yml: pip install is likely to fail on Ubuntu 24.04 due to PEP 668, which can break the release pipeline outright.
  • A high-impact race condition is present in the version-scoped concurrency setup; parallel runs for different versions can overwrite shared latest.yml/latest-mac.yml artifacts with older metadata.
  • Security risk is elevated because workflow inputs are injected directly into shell commands, creating a command-injection path; passing inputs via environment variables is the safer pattern.
  • Pay close attention to .github/workflows/desktop-release.yml - release reliability and workflow command safety need fixes before merging.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/desktop-release.yml">

<violation number="1" location=".github/workflows/desktop-release.yml:15">
P1: Use a single desktop-release concurrency group instead of a version-scoped group. Different versions can currently publish in parallel and the slower run may overwrite shared `latest.yml`/`latest-mac.yml` feeds with older metadata.</violation>

<violation number="2" location=".github/workflows/desktop-release.yml:36">
P1: Direct injection of GitHub Action inputs into shell scripts exposes the workflow to command injection. Pass the input via an environment variable instead.</violation>

<violation number="3" location=".github/workflows/desktop-release.yml:327">
P0: The pipeline will fail here because `pip install` on Ubuntu 24.04 enforces PEP 668. Remove this step as `awscli` is already pre-installed on GitHub-hosted runners.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant User as Manual Trigger
    participant GHWorkflow as GitHub Actions Workflow
    participant Prepare as prepare job
    participant WinJob as windows job
    participant MacJob as macos job
    participant PublishJob as publish job
    participant Repo as Code Repository
    participant Deps as pnpm Dependencies
    participant Builder as electron-builder
    participant R2 as Cloudflare R2
    participant Worker as Cloudflare Worker
    participant Browser as User Browser

    Note over User,Worker: Desktop Release Pipeline - macOS & Windows

    User->>GHWorkflow: Trigger workflow with semver version
    GHWorkflow->>Prepare: Start prepare job (ubuntu-latest)
    Prepare->>Prepare: Validate env vars & secrets
    Prepare->>Prepare: Validate semver input
    Prepare->>Prepare: Generate two-word release name
    Prepare-->>GHWorkflow: Output version + release_name

    par Windows Build
        GHWorkflow->>WinJob: Start (needs prepare)
        WinJob->>Repo: Checkout code
        WinJob->>Deps: pnpm install --frozen-lockfile
        WinJob->>WinJob: Stamp version & release_name in package.json
        WinJob->>WinJob: pnpm typecheck
        WinJob->>Builder: pnpm desktop:dist:win
        Builder->>WinJob: Build NSIS installer + latest.yml + .exe.blockmap
        WinJob->>WinJob: Verify release files exist & latest.yml references correct version
        WinJob-->>GHWorkflow: Upload desktop-windows-release artifact
    and macOS Build
        GHWorkflow->>MacJob: Start (needs prepare)
        MacJob->>Repo: Checkout code
        MacJob->>Deps: pnpm install --frozen-lockfile
        MacJob->>MacJob: Stamp version & release_name in package.json
        MacJob->>MacJob: pnpm typecheck
        MacJob->>Builder: pnpm desktop:dist:mac
        Builder->>MacJob: Build DMG + ZIP + latest-mac.yml + .blockmap
        MacJob->>MacJob: Verify macOS release files exist
        MacJob->>MacJob: Check latest-mac.yml for correct version & paths
        MacJob->>MacJob: codesign verification
        MacJob->>MacJob: hdiutil verify DMG integrity
        MacJob->>MacJob: unzip -t ZIP integrity
        MacJob->>MacJob: lipo confirm ARM64 architecture
        MacJob-->>GHWorkflow: Upload desktop-macos-release artifact
    end

    GHWorkflow->>PublishJob: Start (needs windows + macos)
    PublishJob->>WinJob: Download desktop-windows-release artifact
    PublishJob->>MacJob: Download desktop-macos-release artifact
    PublishJob->>PublishJob: Verify all expected files present (.exe, .dmg, .zip, .blockmap, latest.yml, latest-mac.yml)
    PublishJob->>PublishJob: Create GitHub Release with all artifacts
    PublishJob->>R2: Push latest.yml + .exe + .blockmap to Windows update feed
    PublishJob->>R2: Push latest-mac.yml + .dmg + .zip + .blockmap to macOS update feed
    PublishJob->>PublishJob: Poll public URLs to verify feed propagation

    Note over Worker,Browser: User Download Flow (runtime)

    User->>Browser: Visit /download page
    Browser->>Worker: GET /downloads/laryn-windows-latest.exe
    Worker->>R2: Fetch latest.yml from update feed
    R2-->>Worker: latest.yml content
    Worker->>Worker: Parse latest.yml for Windows installer path
    Worker-->>Browser: 302 Redirect to latest .exe in R2

    alt macOS download
        Browser->>Worker: GET /downloads/laryn-mac-latest.dmg
        Worker->>R2: Fetch latest-mac.yml from update feed
        R2-->>Worker: latest-mac.yml content
        Worker->>Worker: NEW: Parse latest-mac.yml for macOS DMG path (extractLatestArtifactPath)
        alt Feed available
            Worker-->>Browser: 302 Redirect to latest .dmg in R2
        else Feed not available
            Worker-->>Browser: 503 "Not available yet"
        end
    end

    Note over WinJob,MacJob: Desktop app includes uiohook-napi & node-gyp-build in asarUnpack for native modules
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/desktop-release.yml Outdated
Comment thread .github/workflows/desktop-release.yml
Comment thread .github/workflows/desktop-release.yml Outdated
- Use a stable concurrency group and enable cancel-in-progress for desktop releases
- Pass workflow version input through an environment variable before script parsing
- Remove redundant AWS CLI install step from the publish phase
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/desktop-release.yml:
- Around line 68-70: The guard that tests the shell variable "version" (the if
[[ ! "$version" =~ ... ]] check) is too lax and accepts invalid prereleases;
replace this inline regex with a full SemVer 2.0.0 validator or otherwise
perform canonical SemVer validation (e.g., call the official semver validator
via the semver npm package or use the full SemVer 2.0.0 regex from semver.org)
so that malformed prereleases like "1.2.3-01" or "1.2.3-.." are rejected before
proceeding; update the if condition to use that stricter validation against
"$version".
- Around line 338-367: The release script currently uploads feed files
(latest.yml and latest-mac.yml) inside the same for-loop as the binary
artifacts, which can let clients fetch updated feeds that reference artifacts
not yet uploaded; change the logic so feed files are excluded from this first
pass and are uploaded only after all binaries finish uploading — e.g. in the
loop around release-assets/* skip names matching latest.yml|latest-mac.yml (or
move their case branch out), run aws s3 cp for binaries as-is, then run a
separate upload step that uploads latest.yml and latest-mac.yml via the same aws
s3 cp command (with content_type "text/yaml" and cache_control "no-cache") once
the loop completes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 78231cab-5ee6-46fa-b12f-2edeeb02ee16

📥 Commits

Reviewing files that changed from the base of the PR and between 6c6fec9 and 3b2fa36.

📒 Files selected for processing (1)
  • .github/workflows/desktop-release.yml

Comment thread .github/workflows/desktop-release.yml Outdated
Comment thread .github/workflows/desktop-release.yml
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

@Derpedyea
Copy link
Copy Markdown
Member Author

bugbot run

@Derpedyea
Copy link
Copy Markdown
Member Author

bugbot run verbose=true

@cursor
Copy link
Copy Markdown

cursor Bot commented May 5, 2026

Bugbot request id: serverGenReqId_997a9d81-f039-4a6f-9524-76cea0558d26

- Validate desktop version input with a stricter SemVer regex
- Handle `latest.yml` and `latest-mac.yml` uploads in a dedicated step with text/yaml content type and no-cache headers
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

@Derpedyea Derpedyea merged commit 787fdb4 into main May 5, 2026
4 checks passed
@Derpedyea Derpedyea deleted the feature/main branch May 5, 2026 15:36
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.

1 participant