Skip to content

Implement a public auto-updating Nightly channel - #245

Draft
xcv58 wants to merge 4 commits into
ggbond268:mainfrom
xcv58:codex/issue-243-nightly-builds
Draft

Implement a public auto-updating Nightly channel#245
xcv58 wants to merge 4 commits into
ggbond268:mainfrom
xcv58:codex/issue-243-nightly-builds

Conversation

@xcv58

@xcv58 xcv58 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Tracks #243.

Important

This draft targets one deliverable only: the public, signed/notarized, auto-updating MacTools Nightly channel. The earlier scheduled Debug-snapshot proposal has been removed from the final diff. The existing manual MacTools-Debug Actions artifact remains an ordinary CI debugging tool outside this PR's Nightly scope.

Current state

The branch currently documents the intended architecture and maintainer handoff. It does not yet implement or publish Nightly, so this PR must remain draft until the contributor checklist below is complete.

There is one publication gate: ENABLE_NIGHTLY_RELEASES. It must remain unset until a maintainer completes the credential-backed N-to-N+1 acceptance after merge.

Target user experience

  1. GitHub publicly lists MacTools Nightly — Unstable as a prerelease with a warning first in the notes.
  2. A user downloads and installs the Developer ID-signed and notarized Nightly DMG once.
  3. Nightly coexists with stable MacTools through isolated app/extension identities, URL scheme, preferences, Application Support directory, and plugins.
  4. Check for Updates discovers and installs later Nightly builds from a dedicated Sparkle feed.
  5. Matching same-commit plugins synchronize automatically before loading.
  6. Stable app data, appcast, plugin catalogs, Homebrew metadata, website stable-download metadata, GitHub Latest, and release behavior remain untouched.

No access control, account, invitation, private download service, separate Debug Nightly, or separate marketing website is required.

Implementation required before this PR is ready

The following work can be completed and reviewed without upstream release credentials:

  • Nightly isolation: add a dedicated build configuration for the app and Finder extension with separate product names, bundle IDs, URL scheme, defaults scope, Application Support/plugin paths, and visible Nightly channel metadata.
  • Update configuration: make the Sparkle feed/public key and plugin source/public key build-configurable; assign every successful Nightly a monotonically increasing numeric build version.
  • Publication workflow: add a dedicated workflow gated by ENABLE_NIGHTLY_RELEASES that references maintainer Secrets, runs tests, builds with Release settings, signs/notarizes, creates an immutable public GitHub prerelease, puts the instability warning first, and advances the dedicated appcast only after every app/plugin asset is available.
  • Atomic plugins: build the app and plugins from the same commit and PluginKit version, then synchronize the matching Nightly plugin set before plugin loading even when production plugin versions did not change.
  • Stable protection: keep publication fail-closed and prove that stable storage, docs/appcast.xml, docs/app-release.json, Homebrew, GitHub Latest, and production plugin catalogs cannot be modified by the Nightly path.
  • Tests and documentation: cover configuration isolation, build numbering/appcast generation, package/catalog integrity, plugin synchronization, publication ordering, and stable-channel protection; finish the public warning, retention, rollback, troubleshooting, and changelog documentation.

A new Xcode target is not required if a Nightly configuration provides complete isolation. A separate Nightly Sparkle key is recommended but may reuse the stable key if the maintainer explicitly accepts that tradeoff. A remote Nightly plugin catalog is optional if the app ships and synchronizes a complete matching plugin baseline.

Maintainer activation after merge

Credential-backed acceptance cannot run in the contributor fork. Merge must leave scheduled publication disabled until a maintainer completes:

  • Confirm the Developer ID, notarization, bundle-prefix, Sparkle-key, and any plugin-catalog-key configuration.
  • Manually publish Nightly N and N+1.
  • Install N and use Check for Updates to install N+1; verify signatures, notarization, relaunch, warning copy, matching plugins, and stable-app isolation.
  • Confirm retention and rollback by publishing known-good source as a new higher build rather than replacing immutable signed bytes.
  • Set ENABLE_NIGHTLY_RELEASES=true, verify the next scheduled prerelease/feed update, and confirm the pause/resume and troubleshooting instructions.

Deleting or changing ENABLE_NIGHTLY_RELEASES pauses scheduled publication. Manual validation remains available while paused.

Publication invariants

  • GitHub Releases is the public discovery and initial-download surface.
  • Every Nightly is a prerelease, never GitHub Latest.
  • The release title and first note clearly say Nightly — Unstable.
  • App and plugin assets are immutable and tied to one source commit.
  • The dedicated Nightly appcast is published last.
  • Any generation, test, build, signing, notarization, plugin, checksum, upload, or feed failure prevents the feed from advancing.
  • A missed Nightly is acceptable; a partial or untested Nightly is not.
  • Normal Sparkle prompts and Check for Updates are sufficient; silent background installation is out of scope.

Current branch changes

  • Documents the single public Nightly target and the contributor/maintainer responsibility boundary.
  • Removes the scheduled Debug-snapshot proposal, its repository variable, and its contributor-facing documentation from the final diff.
  • Leaves the existing manual Debug artifact behavior unchanged and outside the Nightly channel.

Validation

  • actionlint .github/workflows/build.yml
  • /usr/bin/python3 -m unittest discover -s scripts/tests -p 'test_*.py' — 10 tests
  • git diff --check

Non-goals

  • A second Debug or contributor Nightly channel.
  • Access control, accounts, invite codes, or private downloads.
  • A separate Nightly marketing website.
  • Homebrew Nightly distribution.
  • Reusing the stable appcast or production plugin catalog.
  • Marking Nightly as GitHub Latest.
  • Silent background installation.

@xcv58

xcv58 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

CI follow-up:

  • The initial upstream run failed only in DeviceBatteryCommandRunnerTests.testTimeoutReturnsFilteredPartialOutputWithoutWaitingForDescendantPipe(), an existing timing-sensitive test unrelated to these workflow/documentation changes.
  • GitHub does not allow a contributor without repository admin access to rerun that upstream job.
  • I ran the same workflow end to end at commit fcfeb7b on the contributor fork. It passed the full Xcode test suite (including the previously failing test), Debug app packaging/upload, and the unsigned Release build: https://github.com/xcv58/MacTools/actions/runs/30867004189
  • Maintainer action: please use Re-run failed jobs on the upstream check before merging.

@xcv58 xcv58 changed the title Add opt-in nightly build artifacts Add a public auto-updating Nightly channel Aug 4, 2026
@xcv58 xcv58 changed the title Add a public auto-updating Nightly channel Implement a public auto-updating Nightly channel Aug 4, 2026
@xcv58

xcv58 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@ggbond268 Could you please review the proposed Nightly direction and let me know whether it fits your expectations?

The proposal now targets one public channel: a signed, notarized MacTools Nightly prerelease that users install once and subsequently update through Sparkle. The existing manual Debug artifact remains unrelated CI output.

I don't have access to the repository settings, Developer ID/notarization credentials, Sparkle signing key, or other release secrets. Therefore, I cannot complete or validate the credential-backed publication and N-to-N+1 update flow.

Would you be willing to take ownership of the maintainer-only implementation and activation steps? I can continue helping with credential-free code, tests, and documentation if you confirm the direction and indicate which parts you would like me to handle.

I'll keep the PR in draft until we have your feedback and the credential-backed steps have an owner. Thank you!

@ggbond268

Copy link
Copy Markdown
Owner

@ggbond268 Could you please review the proposed Nightly direction and let me know whether it fits your expectations?

The proposal now targets one public channel: a signed, notarized MacTools Nightly prerelease that users install once and subsequently update through Sparkle. The existing manual Debug artifact remains unrelated CI output.

I don't have access to the repository settings, Developer ID/notarization credentials, Sparkle signing key, or other release secrets. Therefore, I cannot complete or validate the credential-backed publication and N-to-N+1 update flow.

Would you be willing to take ownership of the maintainer-only implementation and activation steps? I can continue helping with credential-free code, tests, and documentation if you confirm the direction and indicate which parts you would like me to handle.

I'll keep the PR in draft until we have your feedback and the credential-backed steps have an owner. Thank you!

Thanks, the Nightly direction looks good.

Happy to handle signing/notarization and N→N+1 testing on my side — may take a bit since I’m busy lately.

@xcv58

xcv58 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@ggbond268 Could you please review the proposed Nightly direction and let me know whether it fits your expectations?
The proposal now targets one public channel: a signed, notarized MacTools Nightly prerelease that users install once and subsequently update through Sparkle. The existing manual Debug artifact remains unrelated CI output.
I don't have access to the repository settings, Developer ID/notarization credentials, Sparkle signing key, or other release secrets. Therefore, I cannot complete or validate the credential-backed publication and N-to-N+1 update flow.
Would you be willing to take ownership of the maintainer-only implementation and activation steps? I can continue helping with credential-free code, tests, and documentation if you confirm the direction and indicate which parts you would like me to handle.
I'll keep the PR in draft until we have your feedback and the credential-backed steps have an owner. Thank you!

Thanks, the Nightly direction looks good.

Happy to handle signing/notarization and N→N+1 testing on my side — may take a bit since I’m busy lately.

Thank you so much!

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