Skip to content

FrameGenKit, the framegen CLI, workspaces, all platforms, signing and publishing - #4

Merged
Ramiz69 merged 1 commit into
mainfrom
backlog
Oct 19, 2026
Merged

Ramiz69 merged 1 commit into
mainfrom
backlog

Conversation

@Ramiz69

@Ramiz69 Ramiz69 commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Summary

This implements the development backlog. The build engine moves into a local Swift package, FrameGenKit, shared by the app and a new framegen command-line tool, so CI runs exactly the same pipeline as the app.

It also adds:

  • .xcworkspace and CocoaPods support;
  • every Apple platform, detected automatically;
  • XCFramework code signing;
  • publishing to GitHub or any other host;
  • notifications when a build finishes;
  • a Russian localization.

This PR is stacked on #3 (release pipeline), which is stacked on #2 and #1. GitHub retargets it to main as those merge.

Changes

Engine (Packages/FrameGenKit)

  • XCFrameworkPipeline.run(BuildRequest, onEvent:) reports PipelineEvents. The app adapts them to BuildState; the tool prints them.
  • Workspaces: ProjectLocator prefers a sibling .xcworkspace and rejects paths that don't exist. Workspace configurations come from its main, non-Pods project.
  • Platforms: iOS, Mac Catalyst, macOS, tvOS, watchOS, visionOS and the simulators. SchemeBuildInfo reads SUPPORTED_PLATFORMS, SUPPORTS_MACCATALYST, PRODUCT_NAME and MARKETING_VERSION from -showBuildSettings -json.
  • Signing: codesign --timestamp runs before the zip, and the checksum is computed after it. SigningIdentity parses security find-identity.
  • Publishing:
    • Publisher uploads to GitHub with gh: it creates the release, or replaces the asset if the release exists. A shell command template covers other hosts, with presets for the GitLab Package Registry, Bitbucket Downloads, S3 and Artifactory.
    • A Template fills {name}, {version}, {zip}, {path} and {checksum}: percent-encoded in URLs, shell-quoted in commands.
  • Failure highlights come only from the failing step's output.

Command-line tool

  • framegen build | list | identities | help, with JSON output and exit codes 0, 1, 2 and 130.
  • Built by the Xcode target FrameGenCLI into FrameGen.app/Contents/Helpers/framegen, with hardened runtime and signed on copy. The cask's binary stanza puts it on PATH.
  • BuildArguments parses the options and prints them back for Product › Copy Build Command (⌥⌘C). Round-trip tests keep the two in sync.

App

  • New options: version, signing identity and distribution (manual URL, GitHub release or custom command). Platform toggles show only what the scheme supports; the rest is listed in the footer.
  • A Publish button (⌘U) with progress, success and error states; the snippet switches to the real download URL.
  • Notifications when a build finishes while the app is in the background; on by default, with an option in Settings.
  • Russian localization with Localizable.xcstrings and InfoPlist.xcstrings, including plural rules.
  • ProjectSettings decodes leniently, so an unknown platform or field no longer wipes every project's settings. Settings saved under an .xcodeproj path migrate to the workspace key.

Tooling

  • CI runs swift test --package-path Packages/FrameGenKit.
  • release.sh checks that the embedded tool is arm64-only, uses the hardened runtime and reports the release version.
  • README and docs/RELEASING.md are updated.

Testing

  • swift test: 174 tests pass, 133 in FrameGenKit and 41 in FrameGenCLI.
  • xcodebuild test: 9 app tests pass, covering BuildState and saved settings.
  • scripts/release.sh 2.1 --dry-run passes, including the new tool checks.
  • CLI, real builds on a sample framework:
    • iOS + macOS with a download URL template: the snippet has the real URL;
    • iOS + Simulator, and iOS + Catalyst + macOS, signed with an Apple Development certificate: codesign -dv shows a timestamp, and the checksum matches the signed zip;
    • an ambiguous --sign name or missing arguments gives exit code 2.
  • App, scripted runs in English and Russian: option detection (4 supported platforms out of 10), a signed 4-platform build, and the result with a templated URL and the Publish button.

Not tested

  • Real publishing. It would create a public release or upload to someone's bucket. Only the remote parsing, templates and command construction are covered by tests.
  • A real CocoaPods workspace. Workspace handling is tested with fixtures.
  • Building tvOS, watchOS and visionOS. The sample project doesn't support them. The destinations are tested, but no real slice was built.
  • One signing failure in a scripted app run. It didn't reproduce in the next run, and I couldn't see the error because the failure screen buried it. That's fixed now: the failure screen shows the failing step's own output. If it comes back, the codesign message will be visible.

Engine (Packages/FrameGenKit, shared by the app and the tool):
- XCFrameworkPipeline runs a BuildRequest and reports PipelineEvents;
  failure highlights come from the failing step's output only.
- Projects and workspaces (CocoaPods): a sibling .xcworkspace is preferred,
  configurations come from the workspace's main project, missing paths are
  rejected up front.
- Ten platforms (iOS, Mac Catalyst, macOS, tvOS, watchOS, visionOS and their
  simulators), detected from the scheme's SUPPORTED_PLATFORMS.
- Optional XCFramework signing with a secure timestamp, before zipping.
- Publishing to GitHub releases through gh, or with a shell command
  template (presets for GitLab, Bitbucket, S3, Artifactory); download URL
  templates give the binaryTarget snippet its real URL.

Command-line tool:
- framegen build/list/identities, embedded in FrameGen.app/Contents/Helpers
  and linked by the Homebrew cask; JSON output and stable exit codes.
- "Copy Build Command" prints the same invocation from the app.

App:
- Version, signing, distribution and platform options; Publish (⌘U);
  notifications when a build finishes in the background.
- Russian localization through String Catalogs.
- Saved settings decode leniently and migrate to workspace keys.

Tooling: CI runs swift test for the package; release.sh checks the embedded
tool (arm64, hardened runtime, version). 174 package tests, 9 app tests.
@Ramiz69
Ramiz69 changed the base branch from release-pipeline to main October 19, 2026 13:27
@Ramiz69
Ramiz69 merged commit 745a1fd into main Oct 19, 2026
@Ramiz69
Ramiz69 deleted the backlog branch October 19, 2026 13:29
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