Skip to content

ci(mac-release): release-contract asserts scheme + bundle-id + SUPublicEDKey#807

Merged
buremba merged 2 commits into
mainfrom
ci/release-contract-stricter
May 17, 2026
Merged

ci(mac-release): release-contract asserts scheme + bundle-id + SUPublicEDKey#807
buremba merged 2 commits into
mainfrom
ci/release-contract-stricter

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented May 17, 2026

Closes #794.

Context

PR #784 added a "Verify release contract" step in mac-release.yml that only checked path existence. A rename inside the lobu-ai/owletto submodule (Xcode scheme LobuOwletto, bundle id ai.lobu.macai.owletto.mac, or accidental removal of SUPublicEDKey) would pass those checks and fail late in xcodebuild -scheme Lobu — or worse, silently break Sparkle auto-update for installed users.

What's now verified

The same Verify release contract shell block (no new step) now also asserts, at the pinned submodule SHA, before any build runs:

  1. xcodebuild -project Lobu.xcodeproj -list exposes a scheme named exactly Lobu (regex-anchored so e.g. LobuTests doesn't match).
  2. Info.plist CFBundleName and CFBundleDisplayName are both Owletto (what users see in Finder, the menu bar, "About").
  3. project.pbxproj still sets PRODUCT_BUNDLE_IDENTIFIER = ai.lobu.macCFBundleIdentifier in Info.plist resolves to $(PRODUCT_BUNDLE_IDENTIFIER) at build time, so the real id lives in the pbxproj build settings. This is the value the URL scheme, Keychain service name, and Sparkle update path all key off.
  4. Info.plist contains <key>SUPublicEDKey</key> so installed apps can still verify Sparkle update signatures.

Compatibility

Additive only — every existing path-existence check is preserved unchanged. Verified locally against the currently-pinned packages/web SHA: all four new assertions pass; flipping any of the four expected values to a renamed variant (Owletto scheme, ai.owletto.mac bundle id) fails with a clear ::error:: and aborts before xcodebuild runs.

Summary by CodeRabbit

  • Chores
    • Added validation checks to the macOS release workflow to enforce consistency across build configurations: verifies the expected build scheme is present, app display/name values match, the app bundle identifier is exact, and the update-signing key remains present to ensure signed updates validate correctly.

Review Change Stack

…icEDKey

The "Verify release contract" step previously only checked that the
Xcode project + Info.plist + Sparkle script paths exist. A rename
inside the owletto submodule (scheme Lobu->Owletto, bundle id
ai.lobu.mac->ai.owletto.mac, Sparkle key removal) would pass those
checks and fail late in xcodebuild, or worse, silently break
auto-update for installed users.

Add four assertions in the same shell block:
- xcodebuild -list must expose a scheme named exactly 'Lobu' (the
  workflow uses `-scheme Lobu` everywhere).
- Info.plist CFBundleName and CFBundleDisplayName must be 'Owletto'.
- project.pbxproj must still set PRODUCT_BUNDLE_IDENTIFIER = ai.lobu.mac
  (CFBundleIdentifier in Info.plist resolves to that var at build time,
  so the real id lives in the pbxproj build settings).
- Info.plist must contain <key>SUPublicEDKey</key> so installed apps
  can verify Sparkle update signatures.

Backward-compatible: only adds checks. Closes #794.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5486a450-b741-456f-9146-5fb069f3645b

📥 Commits

Reviewing files that changed from the base of the PR and between 29fba82 and 393f31a.

📒 Files selected for processing (1)
  • .github/workflows/mac-release.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/mac-release.yml

📝 Walkthrough

Walkthrough

The PR tightens the macOS release workflow by adding explicit, fail-fast checks that the Xcode scheme Lobu, Info.plist CFBundleName/CFBundleDisplayName (Owletto), PRODUCT_BUNDLE_IDENTIFIER (ai.lobu.mac) across configurations, and SUPublicEDKey are present and unchanged before building.

Changes

macOS Release Contract Validation

Layer / File(s) Summary
Release contract documentation
.github/workflows/mac-release.yml
Adds comments enumerating the required release contract values: Xcode scheme, display names, bundle identifier, and Sparkle public key.
Verify release contract checks
.github/workflows/mac-release.yml
Implements checks in the workflow step: uses xcodebuild -list -json to assert the Lobu scheme exists; uses PlistBuddy to assert CFBundleName and CFBundleDisplayName are Owletto; extracts distinct PRODUCT_BUNDLE_IDENTIFIER values from Lobu.xcodeproj/project.pbxproj and requires ai.lobu.mac for all configurations; verifies SUPublicEDKey is present in Info.plist. Each mismatch emits ::error:: and exits.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #793: Related — shares focus on guarding the Xcode scheme and mac CI flow for the Lobu project.
  • #788: Related — adds validation of SUPublicEDKey in Info.plist, which aligns with Sparkle key rotation and update validation concerns.
  • #794: Directly addressed — requested asserting Xcode scheme, bundle ID, and Sparkle pubkey in the mac-release step.

Poem

🐰 I hopped through YAML to guard the release,
I checked each scheme and bundle with ease,
I peeked in Info.plist for the Sparkle key,
Now Lobu’s updates stay trusted and free,
A rabbit's nod keeps the pipeline at peace.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding release-contract assertions for scheme, bundle ID, and Sparkle public key in the mac-release workflow.
Description check ✅ Passed The PR description is comprehensive and well-structured, providing context, detailed explanation of the four new assertions, compatibility notes, and verification status. However, it does not include test plan or validation steps as specified in the repository's description template.
Linked Issues check ✅ Passed The PR implementation fully addresses all requirements from issue #794: scheme verification via -list -json, bundle identifier check in project.pbxproj, Sparkle SUPublicEDKey presence verification, and clear error messaging before any build runs.
Out of Scope Changes check ✅ Passed All changes are strictly within scope: the PR only modifies the existing 'Verify release contract' shell block in mac-release.yml with additive assertions; no path-existence checks are removed and no other files are modified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 ci/release-contract-stricter

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

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29fba826ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/mac-release.yml Outdated
Comment on lines +139 to +140
if ! grep -q "PRODUCT_BUNDLE_IDENTIFIER = ${EXPECTED_BUNDLE_ID};" \
packages/web/apps/mac/Lobu.xcodeproj/project.pbxproj; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify the Release bundle identifier specifically

This grep passes as soon as any build setting in project.pbxproj still contains ai.lobu.mac, but Xcode projects commonly have separate Debug/Release settings (and possibly test targets). If the app's Release configuration drifts to ai.owletto.mac while another configuration still has the old value, this check succeeds and the later Archive steps still build -configuration Release, so the release can ship with the wrong bundle id despite the contract check.

Useful? React with 👍 / 👎.

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Pi review on PR #807 flagged three checks that could pass while the
release contract was actually broken:

1. Scheme check matched against `xcodebuild -list` plain output, which
   contains both a `Targets:` and a `Schemes:` section. A target named
   'Lobu' would satisfy the grep even if the scheme had been renamed
   to 'Owletto'. Switch to `-list -json` and parse the schemes array,
   so only an actual scheme named 'Lobu' counts.

2. PRODUCT_BUNDLE_IDENTIFIER grep proved "some occurrence equals
   ai.lobu.mac". If one build config drifted while another stale
   occurrence stayed correct, the grep would still pass. Assert the
   distinct set of values across project.pbxproj equals exactly
   {ai.lobu.mac}.

3. SUPublicEDKey grep could match the literal string inside an XML
   comment. Replace with PlistBuddy `Print :SUPublicEDKey`, which only
   succeeds when it's an actual plist key.

Sanity-checked all three against the currently pinned submodule SHA
(b01682708) locally: scheme list = "Lobu", distinct bundle ids =
"ai.lobu.mac", PlistBuddy returns the key. No behavior change beyond
catching cases the old checks would silently miss.
@buremba buremba merged commit fdbfc27 into main May 17, 2026
20 of 21 checks passed
@buremba buremba deleted the ci/release-contract-stricter branch May 17, 2026 04:11
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.

Strengthen mac-release release-contract: assert Xcode scheme + bundle ID

2 participants