Implement Swift 6 Approachable Concurrency migration (Stages 2–5)#144
Closed
Copilot wants to merge 20 commits intomain-actor-isolationfrom
Closed
Implement Swift 6 Approachable Concurrency migration (Stages 2–5)#144Copilot wants to merge 20 commits intomain-actor-isolationfrom
Copilot wants to merge 20 commits intomain-actor-isolationfrom
Conversation
With SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor, all types are MainActor by default. The actor's synchronization purpose (single-flight token refresh) is now provided by MainActor serialization. Changes: - actor NetworkAuthManager → class NetworkAuthManager - bearerAuthSupported(): drop async (no longer needed without actor) - basicAuthString(): drop nonisolated (no longer an actor) - JamfProAPIClient: drop await from bearerAuthSupported() calls - NetworkAuthManagerTests: drop await from bearerAuthSupported() calls Side effect: Resolves Token.isValid cross-isolation warning because Token and NetworkAuthManager are now both on MainActor. Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
With MainActor default isolation, manual dispatch to the main thread is redundant. All three locations are already MainActor-isolated. Changes: - Alert.swift: Remove DispatchQueue.main.async wrapper in display() - OpenViewController.swift: Remove wrapper in tableView selectionIndexes - SaveViewController.swift: Remove wrapper in savePressed panel callback Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Replace Task/completion handler pattern with direct async throws methods.
Changes:
- UploadManager.verifyConnection: async throws -> VerificationInfo
- UploadManager.upload: async throws (no completion handler)
- UploadInfoView.verifyConnection: now async, uses try await
- UploadInfoView.performUpload: now async, uses try await
- Button action bridges to async with Task { await ... }
Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5
Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Replace completion handler pattern with throws -> Executable since the work is synchronous (reads bundle info and code requirements). Changes: - Model.loadExecutable(url:) now throws -> Executable (no completion) - Remove LoadExecutableCompletion typealias - findExecutableOnComputerUsing → findExecutable, returns directly - getExecutableFrom: uses do/catch instead of completion handler - getAppleEventChoices: uses do/catch for each loadExecutable call - TCCProfileViewController: promptForExecutables and acceptDrop updated - OpenViewController.prompt: updated to use try/catch Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Replace completion handler pattern with throws -> TCCProfile since the work is synchronous (decode data, read file). Changes: - TCCProfileImporter.decodeTCCProfile(data:) now throws -> TCCProfile - TCCProfileImporter.decodeTCCProfile(fileUrl:) now throws -> TCCProfile - Remove TCCProfileImportCompletion typealias - TCCProfileConfigurationPanel: uses try/catch in panel callback - TCCProfileImporterTests: updated to use try/catch pattern Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Mark SecurityWrapper and Model methods with @Concurrent to move disk I/O and security operations off MainActor onto the cooperative pool. Changes: - SecurityWrapper.copyDesignatedRequirement: @Concurrent async throws - SecurityWrapper.sign: @Concurrent async throws - SecurityWrapper.loadSigningIdentities: @Concurrent async throws - Model.loadExecutable: @Concurrent async throws -> Executable - Model.getAppleEventChoices: now async (calls loadExecutable) - Model.getExecutableFrom/findExecutable: now async - Model.getExecutablesFromAllPolicies: now async - Model.importProfile: now async - All callers updated to use Task/await where needed - ModelTests: updated to async test methods Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Flip SWIFT_VERSION from 5.0 to 6.0 so all concurrency warnings become hard errors. Fix override isolation mismatches. Changes: - SWIFT_VERSION = 6.0 in all 4 build configurations - SaveViewController.observeValue: add nonisolated + MainActor.assumeIsolated - ModelTests.setUp: add nonisolated + MainActor.assumeIsolated - Update plan document to reflect all stages complete Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/4235dbf5-feb0-4744-839d-543eee3b8ee5 Co-authored-by: watkyn <40115+watkyn@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add separate pull requests for each state in the plan
Implement Swift 6 Approachable Concurrency migration (Stages 2–5)
Mar 26, 2026
* Initial plan * Add swift-format config, GitHub Action workflow, and pre-commit hook Co-authored-by: jjpritzl <108085430+jjpritzl@users.noreply.github.com> Agent-Logs-Url: https://github.com/jamf/PPPC-Utility/sessions/1f5e71ff-f5b8-4e2c-8b0e-bc262951f2fd * add-swift Disable AlwaysUseLowerCamelCase and ReplaceForEachWithForLoop rules These rules conflict with existing codebase conventions (Logger constants, enum-style variable names, and forEach usage patterns). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * add-swift Apply swift-format to entire codebase One-time bulk format using xcrun swift-format --in-place -r -p . This commit contains only formatting changes — no logic or functional changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * add-swift Fix SwiftLint conflicts with swift-format - Disable opening_brace rule in .swiftlint.yml (conflicts with swift-format's multiline condition brace placement) - Set multiElementCollectionTrailingCommas to false in .swift-format to avoid trailing comma conflicts with SwiftLint - Remove trailing commas added by swift-format - Remove superfluous swiftlint:disable file_length comment - Fix function_body_length violations caused by array expansion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * add-swift Increase file_length limit to 500 in .swiftlint.yml TCCProfileViewController.swift exceeds the default 400-line limit after swift-format expanded multi-line arrays. Raising the threshold avoids needing inline swiftlint:disable comments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * add-swift Fix pre-commit hook to handle special characters in filenames Use NUL-delimited output (git diff -z) with xargs -0 to safely handle filenames containing spaces, tabs, or newlines. Pass -- before the file list to prevent paths beginning with - from being interpreted as options. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * add-swift Remove SwiftLint — swift-format now handles all formatting - Delete .swiftlint.yml config - Delete .github/workflows/swiftlint.yml GitHub Action - Remove SwiftLint build phase from Xcode project - Remove all inline swiftlint:disable/enable comments from Swift files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jjpritzl <108085430+jjpritzl@users.noreply.github.com> Co-authored-by: JJ Pritzl <jj.pritzl@jamf.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…fix Unit Test issues
* AI generated removal of the big sur compatibility logic. Needs vetted and tested * big-sur story/JPCFM-5531 Add minor changes to update minimum supported OS and remove remaining Big Sur things * big-sur story/JPCFM-5531 Remove swiftlint disable call due to reduced file length * big-sur story/JPCFM-5531 Add Copilot suggestion for generating test results * big-sur story/JPCFM-5531 Add Copilot refactor to loadExecutable function * big-sur story/JPCFM-5531 Remove code coverage addition --------- Co-authored-by: Tony Eichelberger <tony.eichelberger@jamf.com>
* started on a claude.md and converting a couple tests * added plan * phase 3 done * phase 4 * phase 5 * phase 6 * phase 7 * swift format --------- Co-authored-by: Tony Eichelberger <tony.eichelberger@jamf.com>
…eate-separate-pull-requests
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.
Implements all pending stages from the plan at
docs/plans/approachable-concurrency.md. Stage 1 (build settings) was already applied. Each stage is a separate commit.Stage 2:
NetworkAuthManageractor → classWith
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor, MainActor serialization replaces the actor.bearerAuthSupported()dropsasync,basicAuthString()dropsnonisolated. ResolvesToken.isValidcross-isolation warning.Stage 3a: Remove
DispatchQueue.main.asyncwrappersThree locations (
Alert.display,OpenViewControllerselection handler,SaveViewController.savePressedpanel callback) — redundant under MainActor default isolation.Stage 3b:
UploadManager→ async throwsButton action in
UploadInfoViewbridges withTask { await ... }— the one idiomatic place aTask{}remains.Stage 3c:
Model.loadExecutable→ direct returnCompletion handler removed since the work is synchronous.
findExecutableOnComputerUsing→findExecutable, callers acrossTCCProfileViewController,OpenViewControllerupdated.Stage 3d:
TCCProfileImporter→ direct returnBoth
decodeTCCProfileoverloads nowthrows -> TCCProfile.TCCProfileImportCompletiontypealias removed. Tests updated from callback assertions todo/catch.Stage 4:
@concurrentfor background I/OSecurityWrapper.copyDesignatedRequirement,.sign,.loadSigningIdentities→@concurrent static func ... async throwsModel.loadExecutable→@concurrent func ... async throws -> ExecutablegetAppleEventChoices,getExecutableFrom,importProfile,getExecutablesFromAllPoliciesand all callersStage 5: Swift 6 language mode
SWIFT_VERSION = 5.0→6.0(4 build configurations)SaveViewController.observeValue:nonisolated+MainActor.assumeIsolatedfor KVO override mismatchModelTests.setUp: same pattern for XCTestCase lifecycle mismatch💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.