You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a MAS-signed macOS TestFlight workflow for scheduled internal nightlies and reviewer-gated external beta candidates.
Use a unique CI build number and emit a promotion manifest so the exact processed TestFlight build can be promoted later.
Add a reviewer-gated production workflow that submits an already-processed build to Mac App Store review.
Support manual, automatic-after-review, and seven-day phased release modes.
Pin Ruby setup and Fastlane, use separate MAS signing/provisioning credentials from direct-distribution notarization credentials, and keep production submission separate from the nightly lane.
Prevent build:mas from implicitly publishing through electron-builder.
This PR is intentionally stacked on feat/microsoft-store-publishing and should be merged after PR #260, or retargeted to main once that PR lands.
Required setup
macos-testflight-nightly Environment: MAS signing/API secrets, no approval for scheduled nightlies.
macos-testflight-beta Environment: same secrets, required maintainer approval for manual beta runs.
production-release Environment: App Store Connect API secrets and required maintainers.
App Store Connect bundle ID com.flo.desktop, Mac App Distribution certificate, MAS provisioning profile, TestFlight groups, and prepared version metadata.
See the workflow comments and fastlane/Fastfile for the lane behavior. The first production mode should be manual; switch to automatic or phased only after a successful review cycle.
Verification
npm run test:release-config
YAML parsing for all release workflows
git diff --check
Apple signing, TestFlight processing, and App Store review require the maintainer's Apple/GitHub credentials and cannot be validated locally.
This PR is stacked on PR #260. Please merge #260 first, then retarget #261 to main if GitHub does not do that automatically.
Apple Developer / App Store Connect setup
Confirm the existing App Store Connect app:
Mac App Store listing: https://apps.apple.com/in/app/flo-cafe/id6763136018
Bundle ID: com.flo.desktop
Team ID: BKDY677XJA
In Apple Developer Certificates, Identifiers & Profiles:
Create/export a Mac App Distribution certificate as a .p12.
Create a Mac App Store distribution provisioning profile for com.flo.desktop.
Do not reuse the direct-distribution MAC_CERTS; that is the Developer ID certificate used for DMG/ZIP notarization.
The profile must be supplied to CI at build/flo.provisionprofile; it must never be committed.
In App Store Connect, create a dedicated API key with App Manager-level access for the first implementation. The key must be allowed to upload builds, manage TestFlight information, and submit builds for review. Keep the .p8 private key; Apple only allows downloading it once.
Create/confirm TestFlight groups:
Internal group for maintainers/staff.
External beta group for release candidates.
Complete the beta app description, feedback email, and external review information. Apple may review the first external build before distribution.
Ensure the App Store Connect agreement/tax/banking status and the current app metadata are complete. For production, the target version must have release notes and review information prepared in App Store Connect. This PR deliberately does not overwrite production metadata from the repository.
GitHub Environments and values
Create these environments:
macos-testflight-nightly
Used only by the scheduled nightly workflow from main. Add:
Secrets
MAS_MAC_CERTS — base64 .p12 Mac App Distribution certificate
TESTFLIGHT_GROUP — internal group name, if required
TESTFLIGHT_CHANGELOG — optional nightly “what to test” text
Do not add required reviewers here, otherwise every scheduled nightly will pause.
macos-testflight-beta
Use the same secrets and variables as above, but add required maintainer reviewers. All manual TestFlight runs use this environment, including internal manual runs and external beta runs.
production-release
Add the App Store Connect API secrets above. This is the same protected environment used by PR #260 for Microsoft Store publishing. Keep required maintainer reviewers and self-approval disabled.
Add the optional environment variable:
MACOS_STORE_RELEASE_MODE=manual
Allowed values are:
manual — submit to Apple review, then release manually after approval; safest first mode.
automatic — Apple releases automatically after approval.
phased — Apple releases automatically using the seven-day phased rollout.
How the workflows work
Nightly/internal TestFlight
The scheduled macos-testflight.yml workflow:
Checks out main.
Builds the mas target, not the direct DMG/ZIP target.
Sets a unique numeric CFBundleVersion from the GitHub run number.
Verifies the MAS package signature, bundle ID, marketing version, and build number.
Uploads the .pkg to TestFlight using Fastlane.
Publishes a promotion manifest containing the exact version, build number, source ref, and commit SHA.
External beta
Run macos-testflight.yml manually from the workflow UI while selecting the workflow definition from main:
channel=external
source_ref=release/... or a strict X.Y.Z-rc.N tag
The workflow rejects arbitrary branch refs and waits for the protected macos-testflight-beta approval. The exact build number from the promotion manifest is the candidate to promote later.
Production App Store submission
Run macos-app-store-submit.yml manually from the workflow definition on main with:
version: X.Y.Z
build_number: exact processed TestFlight build number
release_mode: manual # first release
The workflow does not rebuild or checkout arbitrary release code. It uses Fastlane to select the already-processed App Store Connect build and submit that exact build for Mac App Store review. The production-release approval is required.
After Apple approves a manual release, release it from App Store Connect. Once the process is proven, use automatic or phased for later releases.
The Mac App Store is the production channel; it has no GitHub-style latest channel. TestFlight is separate, and direct GitHub DMG/ZIP users remain on the existing electron-updater channel.
First validation sequence
Create the certificates, profile, API key, environments, groups, and metadata.
Run an internal TestFlight build from main.
Install it through TestFlight and test SQLite, printers, KDS, backups, and MAS sandbox behavior.
Run an external RC build from a protected release branch/tag and complete Apple beta review if requested.
Use the manifest’s exact build number in the production submission workflow with release_mode=manual.
After approval, manually release the version and verify the public listing.
Only then consider automatic or phased mode.
Fastlane is pinned to 2.237.0; Ruby setup is pinned in the workflow. Apple’s official references:
Anyone with repository Write access may be able to enqueue a manual workflow, but manual beta and production jobs cannot use their protected credentials or submit until a maintainer approves the environment. Release tag rulesets should separately restrict production tags to maintainers/owners.
@itsbkm Governance prerequisite: issue #204 now contains the complete main/tag ruleset checklist and the remaining follow-up release-gating work. Please apply those repository settings before treating these publishing PRs as production-ready: #204 (comment)
@itsbkm This PR is intentionally stacked: #261 targets feat/microsoft-store-publishing, while #260 targets main. Please merge #260 first. After #260 is merged, change #261 base to main using the PR Edit UI (or gh pr edit 261 --base main), then re-run checks and review/merge the Apple-only diff. Do not retarget it before #260 merges, or the Microsoft commits will appear duplicated in #261.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
build:masfrom implicitly publishing through electron-builder.This PR is intentionally stacked on
feat/microsoft-store-publishingand should be merged after PR #260, or retargeted tomainonce that PR lands.Required setup
macos-testflight-nightlyEnvironment: MAS signing/API secrets, no approval for scheduled nightlies.macos-testflight-betaEnvironment: same secrets, required maintainer approval for manual beta runs.production-releaseEnvironment: App Store Connect API secrets and required maintainers.com.flo.desktop, Mac App Distribution certificate, MAS provisioning profile, TestFlight groups, and prepared version metadata.See the workflow comments and
fastlane/Fastfilefor the lane behavior. The first production mode should bemanual; switch toautomaticorphasedonly after a successful review cycle.Verification
npm run test:release-configgit diff --checkApple signing, TestFlight processing, and App Store review require the maintainer's Apple/GitHub credentials and cannot be validated locally.