Skip to content

Swiftpkgr, a friendly UI for swiftpkg - #5

Merged
jordancalhoun merged 14 commits into
mainfrom
feature/swiftpkgr
Jul 18, 2026
Merged

jordancalhoun merged 14 commits into
mainfrom
feature/swiftpkgr

Conversation

@jordancalhoun

@jordancalhoun jordancalhoun commented Jul 17, 2026 •

Copy link
Copy Markdown
Collaborator

Adds Swiftpkgr, a native SwiftUI frontend for swiftpkg, while preserving the existing CLI and its macOS 13+ compatibility.
Swiftpkgr targets macOS 15+ and supports creating, importing, editing, building, and maintaining the same package projects as the command-line tool.

Closes #4
Closes #2

Summary by CodeRabbit

  • New Features
    • Added the Swiftpkgr macOS desktop app for creating, opening, importing, editing, and building installer projects.
    • Added project settings screens for package behavior, distribution, signing, notarization, contents, and build options.
    • Added support for shared project settings in plist, JSON, YAML, and YML formats.
    • Expanded the CLI with build options for BOM export, signing, notarization, and stapling.
    • Added cancellable asynchronous builds with progress and activity reporting.
  • Documentation
    • Updated installation, verification, desktop app, and release workflow guidance.
  • Release
    • Updated the version to 0.3.0.

@jordancalhoun jordancalhoun added the enhancement New feature or request label Jul 17, 2026
@jordancalhoun jordancalhoun added this to the Major Release: 1.0.0 milestone Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 96a95e3d-9cf1-4cea-8eda-586cc264ca59

📥 Commits

Reviewing files that changed from the base of the PR and between 58f56eb and a6cf869.

⛔ Files ignored due to path filters (4)
  • dist/.gitignore is excluded by !**/dist/**
  • swiftpkg/AppIcon.icon/Assets/box.svg is excluded by !**/*.svg
  • swiftpkg/AppIcon.icon/Assets/page-1.svg is excluded by !**/*.svg
  • swiftpkg/AppIcon.icon/Assets/page-2.svg is excluded by !**/*.svg
📒 Files selected for processing (62)
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .gitignore
  • AGENTS.md
  • Package.swift
  • README.md
  • Swiftpkgr/Components/SwiftpkgrCommands.swift
  • Swiftpkgr/Extensions/BuildInfoFormat+Ext.swift
  • Swiftpkgr/Extensions/NotarizationAuthenticationMode+Ext.swift
  • Swiftpkgr/Extensions/PackageCompression+Ext.swift
  • Swiftpkgr/Extensions/PackageOwnership+Ext.swift
  • Swiftpkgr/Extensions/PostInstallAction+Ext.swift
  • Swiftpkgr/Extensions/SigningTimestampMode+Ext.swift
  • Swiftpkgr/Models/AppAlert.swift
  • Swiftpkgr/Models/PendingProjectAction.swift
  • Swiftpkgr/Models/ProjectSection.swift
  • Swiftpkgr/Screens/BuildView.swift
  • Swiftpkgr/Screens/DistributionSettingsView.swift
  • Swiftpkgr/Screens/GeneralSettingsView.swift
  • Swiftpkgr/Screens/NotarizationSettingsView.swift
  • Swiftpkgr/Screens/PackageBehaviorView.swift
  • Swiftpkgr/Screens/ProjectContentsView.swift
  • Swiftpkgr/Screens/ProjectEditorView.swift
  • Swiftpkgr/Screens/ProjectSectionView.swift
  • Swiftpkgr/Screens/SigningSettingsView.swift
  • Swiftpkgr/Screens/WelcomeView.swift
  • Swiftpkgr/Services/ProjectPanelService.swift
  • Swiftpkgr/State/ProjectEditorModel.swift
  • Swiftpkgr/SwiftpkgrApp.swift
  • VERIFICATION.md
  • VERSION
  • release/SwiftpkgInstaller/.gitignore
  • release/SwiftpkgInstaller/README.md
  • release/SwiftpkgInstaller/build-info.plist
  • release/SwiftpkgInstaller/payload/.gitkeep
  • scripts/publish-xcode-release.sh
  • site/index.html
  • swiftpkg.xcodeproj/project.pbxproj
  • swiftpkg.xcodeproj/xcshareddata/xcschemes/SwiftPkgCore.xcscheme
  • swiftpkg.xcodeproj/xcshareddata/xcschemes/Swiftpkgr.xcscheme
  • swiftpkg/AppIcon.icon/icon.json
  • swiftpkg/BuildInfo.swift
  • swiftpkg/BuildInfoDocument.swift
  • swiftpkg/ConsoleEvent.swift
  • swiftpkg/NotarizationAuthenticationMode.swift
  • swiftpkg/PackageBuildOptions.swift
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageImporter.swift
  • swiftpkg/PackageOperationService.swift
  • swiftpkg/PackageSettingsDraft.swift
  • swiftpkg/ProjectOperations.swift
  • swiftpkg/SigningTimestampMode.swift
  • swiftpkg/Support.swift
  • swiftpkg/Version.swift
  • swiftpkg/main.swift
  • swiftpkgCLI/CLI.swift
  • swiftpkgCLI/SwiftPkg.swift
  • swiftpkgCLI/main.swift
  • swiftpkgTests/BuildInfoTests.swift
  • swiftpkgTests/CLITests.swift
  • swiftpkgTests/ProjectOperationsTests.swift
  • swiftpkgTests/TestSupport.swift

📝 Walkthrough

Walkthrough

This PR extracts shared package logic into a new SwiftPkgCore library, introduces a SwiftUI macOS app (Swiftpkgr) for editing and building package projects, migrates the CLI to use async build APIs, updates the Xcode project/CI accordingly, and adds a signing/notarization release automation script with supporting installer template and documentation updates.

Changes

Swiftpkgr Frontend and Shared Core

Layer / File(s) Summary
Shared core contracts and configuration
Package.swift, swiftpkg/BuildInfo.swift, swiftpkg/BuildInfoDocument.swift, swiftpkg/PackageBuildOptions.swift, swiftpkg/PackageSettingsDraft.swift, swiftpkg/ProjectOperations.swift, swiftpkg/SigningTimestampMode.swift, swiftpkg/NotarizationAuthenticationMode.swift, swiftpkg/ConsoleEvent.swift, swiftpkg/Support.swift, swiftpkg/Version.swift, swiftpkg/PackageImporter.swift, swiftpkg/PackageBuilder.swift, swiftpkg/PackageOperationService.swift
Package.swift adds a new SwiftPkgCore library/target; build-info models, PackageSettingsDraft, process/console abstractions, and PackageOperationService become public with async build/notarize support.
CLI migration to SwiftPkgCore
swiftpkgCLI/CLI.swift, swiftpkgCLI/SwiftPkg.swift, swiftpkgCLI/main.swift
CLI types resolve into PackageBuildOptions, expose parsing/resolution publicly, and the entrypoint becomes async, importing SwiftPkgCore.
Project editor model and workflows
Swiftpkgr/State/ProjectEditorModel.swift
Manages project lifecycle, settings drafts, build/import/export operations, cancellation, and error/alert reporting via PackageOperationService.
Swiftpkgr navigation and settings UI
Swiftpkgr/SwiftpkgrApp.swift, Swiftpkgr/Components/*, Swiftpkgr/Models/*, Swiftpkgr/Screens/*, Swiftpkgr/Services/ProjectPanelService.swift, Swiftpkgr/Extensions/*
New SwiftUI app scaffold, commands, screens for general/behavior/contents/distribution/signing/notarization/build settings, and panel/reveal services.
Xcode targets, CI, and verification
swiftpkg.xcodeproj/*, .github/workflows/ci.yml, AGENTS.md, VERIFICATION.md, swiftpkg/AppIcon.icon/icon.json, swiftpkgTests/*
Adds SwiftPkgCore/Swiftpkgr Xcode targets and schemes, updates deployment/Swift settings, CI build step, docs, and test module imports.

Signed and Notarized Release Automation

Layer / File(s) Summary
Publish/build/sign/notarize script
scripts/publish-xcode-release.sh
New script validates prerequisites, builds both frontends, signs, notarizes, staples, and assembles a signed universal installer package, then publishes via git/GitHub CLI.
Installer template and release fallback workflow
release/SwiftpkgInstaller/*, .gitignore, VERSION, .github/workflows/release.yml
Adds the reusable installer template with placeholder signing metadata, bumps VERSION to 0.3.0, tracks dist/, and replaces the unconditional unsigned release job with a conditional fallback.
README and site documentation for signed releases
README.md, site/index.html
Updates install/verification/uninstall docs, describes the Swiftpkgr desktop app, rewrites maintainer release instructions around publish-xcode-release.sh, and updates site marketing copy.

Estimated code review effort: 4 (Complex) | ~75 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ProjectEditorView
  participant ProjectEditorModel
  participant PackageOperationService
  participant PackageBuildCoordinator
  User->>ProjectEditorView: choose project or trigger build
  ProjectEditorView->>ProjectEditorModel: invoke action
  ProjectEditorModel->>PackageOperationService: buildPackage(options, reporter)
  PackageOperationService->>PackageBuildCoordinator: buildPackage(project, options)
  PackageBuildCoordinator-->>PackageOperationService: ConsoleEvent updates / result
  PackageOperationService-->>ProjectEditorModel: completion or error
  ProjectEditorModel-->>ProjectEditorView: update status, logs, or alert
Loading
sequenceDiagram
  participant Maintainer
  participant PublishScript as publish-xcode-release.sh
  participant Xcodebuild
  participant Notarytool
  participant GitHubCLI
  Maintainer->>PublishScript: run --check/--build/--publish
  PublishScript->>Xcodebuild: build swiftpkg and Swiftpkgr
  PublishScript->>Notarytool: notarize and staple artifacts
  PublishScript->>PublishScript: assemble signed .pkg into dist/
  PublishScript->>GitHubCLI: create/update release with pkg and SHA256SUMS
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR delivers the UI frontend, but the new app is documented as macOS 15+, missing the linked requirement to support macOS 13+. Set the Swiftpkgr target to macOS 13+ or update the issue scope if the higher minimum OS is intentional.
Docstring Coverage ⚠️ Warning Docstring coverage is 4.60% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed Changes are aligned with the UI frontend, shared-core, docs, and test goals; no clearly unrelated code was added.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding the Swiftpkgr UI for swiftpkg.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/swiftpkgr

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

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
swiftpkg/Support.swift (1)

56-92: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Make process launch atomic with cancellation registration.

Line 70 exposes activeProcess before Line 77 starts it. A concurrent cancel() sees isRunning == false, returns, and the process then launches despite cancellation.

Proposed fix
-        lock.withLock { activeProcess = process }
         defer {
             lock.withLock {
                 if activeProcess === process { activeProcess = nil }
             }
         }
         do {
-            try process.run()
+            try lock.withLock {
+                try process.run()
+                activeProcess = process
+            }
         } catch {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@swiftpkg/Support.swift` around lines 56 - 92, Update SystemProcessRunner.run
so process registration and launch are atomic with respect to cancel(),
preventing cancellation from observing an unstarted activeProcess and returning
before launch. Coordinate the lock around activeProcess assignment and
process.run(), while preserving cleanup in the existing defer and ensuring
launch errors still clear registration and propagate as MunkiPkgError.
🧹 Nitpick comments (1)
swiftpkg/PackageSettingsDraft.swift (1)

82-153: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the newly exposed public API surface.

  • swiftpkg/PackageSettingsDraft.swift#L82-L153: document the defaults and validation conversion contracts.
  • swiftpkg/ProjectOperations.swift#L5-L19: document ProjectCreator and createProject.
  • swiftpkg/ProjectOperations.swift#L49-L66: document the public BOM export and synchronization operations.
  • swiftpkg/PackageImporter.swift#L17-L29: add a concise type-level comment for PackageImporter.
  • swiftpkgCLI/SwiftPkg.swift#L4-L9: document SwiftPkg.run, including its exit-status contract.

As per coding guidelines, “Use fluent, role-based Swift names, concise documentation comments for new nontrivial types and entry points.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@swiftpkg/PackageSettingsDraft.swift` around lines 82 - 153, Document the
newly exposed public APIs with concise role-based Swift documentation comments:
in swiftpkg/PackageSettingsDraft.swift lines 82-153, document
validatedConfiguration() and its defaults and validation-to-PackageConfiguration
contract; in swiftpkg/ProjectOperations.swift lines 5-19, document
ProjectCreator and createProject; in swiftpkg/ProjectOperations.swift lines
49-66, document the public BOM export and synchronization operations; in
swiftpkg/PackageImporter.swift lines 17-29, add a type-level comment for
PackageImporter; and in swiftpkgCLI/SwiftPkg.swift lines 4-9, document
SwiftPkg.run and its exit-status contract.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 121: Update the documented Swiftpkgr build command in README.md lines
121-121 and docs/SWIFTPKGR_IMPLEMENTATION_PLAN.md lines 379-380 to append
CODE_SIGNING_ALLOWED=NO, matching the unsigned build configuration used by CI
and VERIFICATION.md.

In `@swiftpkg/PackageBuilder.swift`:
- Around line 212-217: Update the timeout handling in
waitForAcceptance(_:configuration:) to replace the direct stderr write with
console.warning(...). Preserve the existing timeout message and ensure it is
emitted through Console so the event reporter and UI receive the
stapling-skipped warning.

In `@Swiftpkgr/NotarizationSettingsView.swift`:
- Around line 25-26: Prevent notarizationPassword from being persisted in
build-info: update the PackageSettingsDraft, validatedConfiguration(), and
BuildInfoStore flow used by NotarizationSettingsView so the Apple ID password
remains ephemeral and is excluded from serialized configuration. Prefer reusing
the existing keychain-profile flow if available, while preserving the
SecureField input behavior.

In `@Swiftpkgr/ProjectEditorModel.swift`:
- Around line 250-256: The project action flow must reject transitions while an
operation is running. In Swiftpkgr/ProjectEditorModel.swift lines 250-256,
update requestProjectAction to return when isRunning before queuing or
performing the action; in Swiftpkgr/SwiftpkgrCommands.swift lines 7-13, disable
the new/open/import commands when model.isRunning.
- Around line 132-140: Enable YAML format parity across settings workflows: in
Swiftpkgr/ProjectEditorModel.swift lines 132-140, allow importSettings to load
YAML settings; in Swiftpkgr/ProjectEditorModel.swift lines 152-159, accept the
YAML BuildInfoFormat during export; and in Swiftpkgr/ProjectPanelService.swift
lines 36-52, include .yaml and .yml content types in both file panels.
- Around line 167-188: Separate ProjectEditorModel.build() into a request method
that checks whether configured signing or notarization credentials require user
confirmation and a confirmed execution method containing the existing build
logic. Update Swiftpkgr/ProjectEditorModel.swift lines 167-188 accordingly, and
change the build triggers in Swiftpkgr/ProjectEditorView.swift lines 41-43,
Swiftpkgr/SwiftpkgrCommands.swift lines 26-29, and Swiftpkgr/BuildView.swift
lines 15-17 to call the shared gated request method so every entry point follows
the confirmation flow.

---

Outside diff comments:
In `@swiftpkg/Support.swift`:
- Around line 56-92: Update SystemProcessRunner.run so process registration and
launch are atomic with respect to cancel(), preventing cancellation from
observing an unstarted activeProcess and returning before launch. Coordinate the
lock around activeProcess assignment and process.run(), while preserving cleanup
in the existing defer and ensuring launch errors still clear registration and
propagate as MunkiPkgError.

---

Nitpick comments:
In `@swiftpkg/PackageSettingsDraft.swift`:
- Around line 82-153: Document the newly exposed public APIs with concise
role-based Swift documentation comments: in swiftpkg/PackageSettingsDraft.swift
lines 82-153, document validatedConfiguration() and its defaults and
validation-to-PackageConfiguration contract; in swiftpkg/ProjectOperations.swift
lines 5-19, document ProjectCreator and createProject; in
swiftpkg/ProjectOperations.swift lines 49-66, document the public BOM export and
synchronization operations; in swiftpkg/PackageImporter.swift lines 17-29, add a
type-level comment for PackageImporter; and in swiftpkgCLI/SwiftPkg.swift lines
4-9, document SwiftPkg.run and its exit-status contract.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e54e5f28-fb44-4201-b944-33c2b9df6194

📥 Commits

Reviewing files that changed from the base of the PR and between 0cae24f and 58f56eb.

📒 Files selected for processing (48)
  • .github/workflows/ci.yml
  • AGENTS.md
  • Package.swift
  • README.md
  • Swiftpkgr/AppAlert.swift
  • Swiftpkgr/BuildView.swift
  • Swiftpkgr/DistributionSettingsView.swift
  • Swiftpkgr/GeneralSettingsView.swift
  • Swiftpkgr/NotarizationSettingsView.swift
  • Swiftpkgr/OptionLabels.swift
  • Swiftpkgr/PackageBehaviorView.swift
  • Swiftpkgr/PendingProjectAction.swift
  • Swiftpkgr/ProjectContentsView.swift
  • Swiftpkgr/ProjectEditorModel.swift
  • Swiftpkgr/ProjectEditorView.swift
  • Swiftpkgr/ProjectPanelService.swift
  • Swiftpkgr/ProjectSection.swift
  • Swiftpkgr/ProjectSectionView.swift
  • Swiftpkgr/SigningSettingsView.swift
  • Swiftpkgr/SwiftpkgrApp.swift
  • Swiftpkgr/SwiftpkgrCommands.swift
  • Swiftpkgr/WelcomeView.swift
  • VERIFICATION.md
  • docs/SWIFTPKGR_IMPLEMENTATION_PLAN.md
  • swiftpkg.xcodeproj/project.pbxproj
  • swiftpkg.xcodeproj/xcshareddata/xcschemes/SwiftPkgCore.xcscheme
  • swiftpkg.xcodeproj/xcshareddata/xcschemes/Swiftpkgr.xcscheme
  • swiftpkg/BuildInfo.swift
  • swiftpkg/BuildInfoDocument.swift
  • swiftpkg/ConsoleEvent.swift
  • swiftpkg/NotarizationAuthenticationMode.swift
  • swiftpkg/PackageBuildOptions.swift
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageImporter.swift
  • swiftpkg/PackageOperationService.swift
  • swiftpkg/PackageSettingsDraft.swift
  • swiftpkg/ProjectOperations.swift
  • swiftpkg/SigningTimestampMode.swift
  • swiftpkg/Support.swift
  • swiftpkg/Version.swift
  • swiftpkg/main.swift
  • swiftpkgCLI/CLI.swift
  • swiftpkgCLI/SwiftPkg.swift
  • swiftpkgCLI/main.swift
  • swiftpkgTests/BuildInfoTests.swift
  • swiftpkgTests/CLITests.swift
  • swiftpkgTests/ProjectOperationsTests.swift
  • swiftpkgTests/TestSupport.swift
💤 Files with no reviewable changes (1)
  • swiftpkg/main.swift

Comment thread README.md
Comment thread swiftpkg/PackageBuilder.swift
Comment on lines +25 to +26
SecureField("App-specific password", text: $model.draft.notarizationPassword)
Text("CLI-compatible exports store this password in plaintext. Prefer a keychain profile.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map relevant files first
git ls-files 'Swiftpkgr/**/*.swift' | rg 'NotarizationSettingsView|ProjectEditorModel|build-info|Notarization|notarization' || true

# Show outline for the target file if present
for f in $(git ls-files 'Swiftpkgr/**/*.swift' | rg 'NotarizationSettingsView\.swift$'); do
  echo "=== OUTLINE: $f ==="
  ast-grep outline "$f" --view expanded || true
done

Repository: codecarton/swiftpkg

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Swiftpkgr swift files ==="
git ls-files 'Swiftpkgr/**/*.swift' | sed -n '1,200p'

echo "=== Search for notarization/build-info references ==="
rg -n --hidden --glob 'Swiftpkgr/**/*.swift' \
  'notarizationPassword|notarization|build-info|keychain|SecureField|staplingTimeout|ProjectEditorModel|draft\.' \
  Swiftpkgr || true

Repository: codecarton/swiftpkg

Length of output: 6478


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect likely files once located.
for f in \
  "$(git ls-files 'Swiftpkgr/**/*.swift' | rg 'NotarizationSettingsView\.swift$' | head -n 1)" \
  "$(git ls-files 'Swiftpkgr/**/*.swift' | rg 'ProjectEditorModel\.swift$' | head -n 1)" \
  "$(git ls-files 'Swiftpkgr/**/*.swift' | rg 'build-info|BuildInfo|PackageOperationService|Export' | head -n 5)"
do
  [ -n "${f:-}" ] || continue
  echo "=== FILE: $f ==="
  wc -l "$f"
  ast-grep outline "$f" --view expanded || true
done

Repository: codecarton/swiftpkg

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the exact files and inspect the relevant regions with line numbers.
for f in $(git ls-files 'Swiftpkgr/**/*.swift' | rg 'NotarizationSettingsView\.swift$|ProjectEditorModel\.swift$|PackageOperationService\.swift$|build-info|BuildInfo|Notarization'); do
  echo "=== $f ==="
  sed -n '1,260p' "$f" | cat -n
  echo
done

Repository: codecarton/swiftpkg

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the exact files referenced by the search.
for f in \
  Swiftpkgr/NotarizationSettingsView.swift \
  Swiftpkgr/ProjectEditorModel.swift \
  Swiftpkgr/ProjectEditorView.swift \
  Swiftpkgr/SwiftpkgrCommands.swift
do
  if [ -f "$f" ]; then
    echo "=== $f ==="
    wc -l "$f"
    sed -n '1,260p' "$f" | cat -n
    echo
  fi
done

# Also inspect any build-info or draft serialization code.
rg -n --hidden --glob 'Swiftpkgr/**/*.swift' \
  'notarizationPassword|notarizationAppleID|notarizationTeamID|notarizationMode|staplingTimeout|validatedConfiguration|build-info|encode|serialize|PropertyListEncoder|JSONEncoder|FileManager|write' \
  Swiftpkgr || true

Repository: codecarton/swiftpkg

Length of output: 21447


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search the whole repo for the draft/configuration definitions and the notarization password field.
rg -n --hidden \
  'notarizationPassword|notarizationAppleID|notarizationTeamID|notarizationMode|staplingTimeout|PackageSettingsDraft|validatedConfiguration|BuildInfoStore|BuildInfoDocument|PackageConfiguration|appleID|keychainProfile' \
  .

# Locate likely source files outside Swiftpkgr if present.
git ls-files | rg 'SwiftPkgCore|BuildInfo|PackageSettingsDraft|PackageConfiguration|Store|Draft|Settings' || true

Repository: codecarton/swiftpkg

Length of output: 16605


Don't persist the Apple ID password in build-info. SecureField only masks the UI; PackageSettingsDraft.notarizationPassword is carried into validatedConfiguration() and written out by BuildInfoStore, so Apple ID exports still store the credential in plaintext. Keep it ephemeral or switch this flow to a keychain profile.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Swiftpkgr/NotarizationSettingsView.swift` around lines 25 - 26, Prevent
notarizationPassword from being persisted in build-info: update the
PackageSettingsDraft, validatedConfiguration(), and BuildInfoStore flow used by
NotarizationSettingsView so the Apple ID password remains ephemeral and is
excluded from serialized configuration. Prefer reusing the existing
keychain-profile flow if available, while preserving the SecureField input
behavior.

Comment on lines +132 to +140
func importSettings() {
guard let url = panels.chooseSettingsFile(), let projectURL else { return }
do {
let configuration = try BuildInfoStore.loadTemplate(from: url, defaultsFor: projectURL)
draft = PackageSettingsDraft(configuration: configuration)
statusMessage = "Imported settings"
activityLog.append("Imported settings from \(url.path)")
} catch {
present(error, title: "Could Not Import Settings")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep YAML available in settings import and export.

The app can create/open YAML build-info projects, but the settings panels filter YAML out and export explicitly rejects it. This breaks format parity with CLI-compatible projects.

  • Swiftpkgr/ProjectEditorModel.swift#L132-L140: allow imported YAML settings.
  • Swiftpkgr/ProjectEditorModel.swift#L152-L159: accept the YAML BuildInfoFormat.
  • Swiftpkgr/ProjectPanelService.swift#L36-L52: add .yaml/.yml content types to both panels.
📍 Affects 2 files
  • Swiftpkgr/ProjectEditorModel.swift#L132-L140 (this comment)
  • Swiftpkgr/ProjectEditorModel.swift#L152-L159
  • Swiftpkgr/ProjectPanelService.swift#L36-L52
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Swiftpkgr/ProjectEditorModel.swift` around lines 132 - 140, Enable YAML
format parity across settings workflows: in Swiftpkgr/ProjectEditorModel.swift
lines 132-140, allow importSettings to load YAML settings; in
Swiftpkgr/ProjectEditorModel.swift lines 152-159, accept the YAML
BuildInfoFormat during export; and in Swiftpkgr/ProjectPanelService.swift lines
36-52, include .yaml and .yml content types in both file panels.

Comment thread Swiftpkgr/ProjectEditorModel.swift Outdated
Comment on lines +167 to +188
func build() {
guard let projectURL, let format = buildInfoDocument?.format else { return }
do {
try saveDraft()
} catch {
present(error, title: "Could Not Build Package")
return
}
let options = PackageBuildOptions(
requestedFormat: format,
exportsBOM: exportsBOM,
isQuiet: false,
skipsSigning: skipsSigning,
skipsNotarization: skipsNotarization,
skipsStapling: skipsStapling
)
let reporter = makeReporter()
runOperation("Building package…") { [operations] in
try await operations.buildPackage(in: projectURL, options: options, reporter: reporter)
return projectURL
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Require confirmation before credential-based builds.

Every Build entry point invokes build() immediately, including when signing or notarization will use configured credentials. Add a model-level request/confirmation flow so all entry points satisfy the PR’s credential-action confirmation requirement.

  • Swiftpkgr/ProjectEditorModel.swift#L167-L188: separate build request/confirmation from confirmed execution.
  • Swiftpkgr/ProjectEditorView.swift#L41-L43: call the gated request method.
  • Swiftpkgr/SwiftpkgrCommands.swift#L26-L29: call the same gated request method.
  • Swiftpkgr/BuildView.swift#L15-L17: call the same gated request method.
📍 Affects 4 files
  • Swiftpkgr/ProjectEditorModel.swift#L167-L188 (this comment)
  • Swiftpkgr/ProjectEditorView.swift#L41-L43
  • Swiftpkgr/SwiftpkgrCommands.swift#L26-L29
  • Swiftpkgr/BuildView.swift#L15-L17
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Swiftpkgr/ProjectEditorModel.swift` around lines 167 - 188, Separate
ProjectEditorModel.build() into a request method that checks whether configured
signing or notarization credentials require user confirmation and a confirmed
execution method containing the existing build logic. Update
Swiftpkgr/ProjectEditorModel.swift lines 167-188 accordingly, and change the
build triggers in Swiftpkgr/ProjectEditorView.swift lines 41-43,
Swiftpkgr/SwiftpkgrCommands.swift lines 26-29, and Swiftpkgr/BuildView.swift
lines 15-17 to call the shared gated request method so every entry point follows
the confirmation flow.

Comment on lines +250 to +256
private func requestProjectAction(_ action: PendingProjectAction) {
if hasUnsavedChanges {
pendingProjectAction = action
showsDiscardConfirmation = true
} else {
perform(action)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Block project transitions while an operation is running.

New/open/import commands remain active during a build. Opening another project can replace model state, then the completed operation reopens its original project and may discard edits made meanwhile.

  • Swiftpkgr/ProjectEditorModel.swift#L250-L256: reject project actions while isRunning.
  • Swiftpkgr/SwiftpkgrCommands.swift#L7-L13: disable these commands while model.isRunning.
📍 Affects 2 files
  • Swiftpkgr/ProjectEditorModel.swift#L250-L256 (this comment)
  • Swiftpkgr/SwiftpkgrCommands.swift#L7-L13
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Swiftpkgr/ProjectEditorModel.swift` around lines 250 - 256, The project
action flow must reject transitions while an operation is running. In
Swiftpkgr/ProjectEditorModel.swift lines 250-256, update requestProjectAction to
return when isRunning before queuing or performing the action; in
Swiftpkgr/SwiftpkgrCommands.swift lines 7-13, disable the new/open/import
commands when model.isRunning.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 10 file(s) based on 6 unresolved review comments.

Files modified:

  • README.md
  • Swiftpkgr/BuildView.swift
  • Swiftpkgr/ProjectEditorModel.swift
  • Swiftpkgr/ProjectEditorView.swift
  • Swiftpkgr/ProjectPanelService.swift
  • Swiftpkgr/SwiftpkgrCommands.swift
  • docs/SWIFTPKGR_IMPLEMENTATION_PLAN.md
  • swiftpkg/BuildInfo.swift
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageSettingsDraft.swift

Commit: 1f34d76b6ea0a703ad395f05ba365ccc641d9827

The changes have been pushed to the feature/swiftpkgr branch.

Time taken: 6m 27s

@jordancalhoun
jordancalhoun marked this pull request as ready for review July 18, 2026 03:48
@jordancalhoun
jordancalhoun merged commit 4de4310 into main Jul 18, 2026
1 of 2 checks passed
@jordancalhoun
jordancalhoun deleted the feature/swiftpkgr branch July 18, 2026 03:58
@coderabbitai coderabbitai Bot mentioned this pull request Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Add a macOS UI frontend Feature: Sign and notarize release installers

1 participant