feat: migrate the fosmvvm-bootstrap scaffolder into FOSUtilities - #140
Merged
Conversation
Sources/tests move in from fosmvvm-bootstrap as FOSMVVMBootstrap(+CLI/Tests), mac-host-gated at the manifest. The release-stamped Release.version replaces the hand-maintained FOS pin, ReleaseConsistencyTests fail CI on stamp or platform-floor drift, and the walking skeletons gate behind FOSMVVM_BOOTSTRAP_SKELETONS=1 so bare swift test stays fast.
CreatingAProject.md (FOSMVVM DocC, linked from the FOSFoundation landing), the README one-minute block, docs/RELEASING.md, and the bootstrap_generation_matrix CI job: fast suite, gated skeletons, and the generated apps' own UI tests on iOS Simulator and macOS, every PR.
…onfig's platforms exactly new without --config runs a validated interview (name defaulted from the output directory; Mac/iPhone/iPad/TV/Vision/Watch each opt-in; the two Designed-for-iPad/iPhone compat modes asked with Apple's default; --verbose echoes the equivalent config; --verify opts into the doors, which pick their destination from the config; xcodegen runs as generation, never as skippable verification). Emission uses xcodegen supportedDestinations with target-level device-family/compat overrides, so every target's destination surface reads exactly the answers; the watch ships as its own target (a multiplatform app target cannot contain watchOS), embedding the same frameworks, which carry the watchOS destination.
CI simulators are always the cold case, which is the measured first-run tap-flake condition; pre-boot plus -retry-tests-on-failure keeps a settling flake visible without redding the PR. The durable fix is FOSTestingUI's first-interaction settle (follow-on).
foscomputerservices
force-pushed
the
feat/fosmvvm-bootstrap-migration
branch
from
August 22, 2026 16:31
a4decf7 to
3b2d0ef
Compare
The generated-app build is an inner xcodebuild spawned by the Verifier, so the job's -skipMacroValidation flag never reaches it. Set IDESkipMacroFingerprintValidation runner-wide so the generated project can build against FOSMacros on a fresh runner.
Each skeleton resolves and builds the full FOSUtilities dependency graph; in parallel they starve a hosted runner past the per-test time limits, and the resulting kill also discards the not-yet-run tests.
…onment When the scaffolder itself runs under xcodebuild test, the harness's XCTest session variables leak into the Verifier's child processes; the generated project's own test runner then tries to attach to the harness's IDE session and hangs on a handshake that never comes, or exits non-zero with every generated test green. Verifier.verify now strips XCTest*/DYLD_* from the inherited environment before spawning steps (caller overlay still wins), so verification behaves identically from a shell and inside a test runner. All three walking skeletons verified green locally under the CI-identical xcodebuild invocation (sharedLibrary 64s, localOnly 58s, clientServer 113s).
…stination Generation follows the config's platforms exactly, so the macOS-only demo configs produced projects with no iOS Simulator destination and the iOS UI-test leg could not match one. Both configs now request iOS 17.0 alongside macOS, and the SUPPORTED_PLATFORMS command-line override — which papered over the missing platform — is gone. All four legs (LocalDemo/ServerDemo x iPhone 17 simulator/macOS) verified green locally with the CI-identical invocations.
CI showed a freshly launched app can discard its first synthesized tap (the event synthesizes, the app idles, and the expected UI change never comes — a per-launch window, so simulator pre-boot and test retries don't close it). The generated test-support base gains tap(_:until:timeout:): tap, poll for the UI change the tap must cause, re-tap once at half timeout. All seven generated tap sites use it, ops reads follow the witness instead of racing the transporter repaint, and BoardViewTests' claim that no waiting is needed is corrected. The primitive lives in the generated support layer because generated projects pin released FOSUtilities; migrating it into FOSTestingUI is the durable follow-on. All four generated-app legs verified green locally (LocalDemo/ServerDemo x iPhone 17 simulator/macOS, CI-identical invocations).
…uns them full-screen Without the declaration iOS letterboxes the app (compatibility sizing: a 603pt window centered on an 874pt iPhone 17 screen), and the reported element frames disagree with the tap-dispatch coordinate space — every synthesized tap misses, deterministically. The 26.5 runtime letterboxes where 27.0 does not, which is why the generated UI tests failed on CI's simulator and passed locally. Reproduced and verified on the 26.5 runtime locally: the failing alert tests go green (and drop from 16-28s of futile polling to 5-7s). All four generated-app legs green locally.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What this is
The fosmvvm-bootstrap scaffolder migrates into FOSUtilities, per the approved design in
docs/superpowers/plans/2026-08-22-fosmvvm-bootstrap-migration-design.md(all ten ruling points ruled; the design and the workflow-session handoff ride in this PR).Distribution story
swift run fosmvvm-bootstrap new --output ~/MyAppfrom a bare clone runs a short validated interview — project name defaulted from the output directory, per-device platform questions (Mac / iPhone / iPad / TV / Vision / Watch), the two "Designed for iPad/iPhone" compatibility questions, floors as version defaults.--configis the automation path;--verboseechoes the equivalent config;--verifyopts into the build/test doors (CI verifies every release the same way).CreatingAProject.mdin FOSMVVM (linked from the FOSFoundation landing, SPI's default); README carries the one-minute block.doctoris design-declared as an SPM command plugin; implementation remains Plan 5.Structure
FOSMVVMBootstrap(library, templates as resources) +FOSMVVMBootstrapCLI→ executable productfosmvvm-bootstrap+FOSMVVMBootstrapTests, all gated to Mac hosts at the manifest (FOSMVVMVapor precedent). Adds swift-argument-parser.Release.versionreplaces the hand-maintained pin;docs/RELEASING.mdrecords the ritual;ReleaseConsistencyTestsfail CI on drift (version ↔ CHANGELOG stamp, floors ↔ this package's platforms).supportedDestinations, target-level device-family/compat overrides — target settings beat project settings, measured), macOS opt-in like every platform, watch as its own target (a multiplatform app target cannot contain watchOS), verify door derives its destination from the config.CI
Verified on the branch
-showBuildSettingsconfirmed target-level wins)..xcodeprojmissing under--skip-verify(→ xcodegen is generation, not verification), Mac-only destination editor (→supportedDestinations), framework targets showing undeclined destinations (→ overrides on every target), compat rows uninvited (→ questions, Apple-default yes), prompts misnaming the device family.Follow-ons (named, not in this PR)