Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0a14250
Initial plan
Copilot Mar 26, 2026
6741832
Stage 2: Convert NetworkAuthManager from actor to class
Copilot Mar 26, 2026
9256bd0
Stage 3a: Remove DispatchQueue.main.async wrappers
Copilot Mar 26, 2026
7b77113
Stage 3b: Convert UploadManager to async throws
Copilot Mar 26, 2026
a64ed56
Stage 3c: Convert Model.loadExecutable to direct return
Copilot Mar 26, 2026
542a287
Stage 3d: Convert TCCProfileImporter to direct return
Copilot Mar 26, 2026
f38e4fc
Stage 4: Add @concurrent for background I/O
Copilot Mar 26, 2026
23583a4
Stage 5: Enable Swift 6 language mode
Copilot Mar 26, 2026
c24c1e9
create-separate story/JPCFM-5564 Fix failing build and tests
jjpritzl Mar 31, 2026
24d36a5
create-separate story/JPCFM-5564 Fix code signing mistake
jjpritzl Mar 31, 2026
cf78ace
create-separate story/JPCFM-5564 Fix bad syntax in build settings
jjpritzl Mar 31, 2026
60390d5
create-separate story/JPCFM-5564 Fix bad syntax in project settings f…
jjpritzl Mar 31, 2026
ebbd218
Add swift-format GitHub Action, config, and pre-commit hook (#142)
Copilot Mar 31, 2026
2f85f1b
create-separate story/JPCFM-5564 Try to fix failing tests on GH PR
jjpritzl Apr 1, 2026
2ed25d9
create-separate story/JPCFM-5564 Try to fix unit test check issue
jjpritzl Apr 1, 2026
83f107d
create-separate story/JPCFM-5564 Make actual change with the plan to …
jjpritzl Apr 1, 2026
b28109d
create-separate story/JPCFM-5564 merge main and fix merge conflicts
jjpritzl Apr 1, 2026
e0862fe
Big sur compatibility removal (#135)
jjpritzl Apr 1, 2026
f800969
Swift testing conversion (#145)
pmoprhy Apr 2, 2026
b165a85
Merge branch 'master' of github.com:jamf/PPPC-Utility into copilot/cr…
watkyn Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/swift-format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: swift-format

on:
pull_request:
paths:
- '.github/workflows/swift-format.yml'
- '.swift-format'
- '**/*.swift'

permissions:
contents: read

jobs:
swift-format:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Lint with swift-format
run: xcrun swift-format lint --strict -r -p .
21 changes: 0 additions & 21 deletions .github/workflows/swiftlint.yml

This file was deleted.

12 changes: 12 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"lineLength": 200,
"indentation": {
"spaces": 4
},
"multiElementCollectionTrailingCommas": false,
"rules": {
"AlwaysUseLowerCamelCase": false,
"ReplaceForEachWithForLoop": false
}
}
12 changes: 0 additions & 12 deletions .swiftlint.yml

This file was deleted.

18 changes: 18 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# PPPC Utility

## Swift Concurrency

- `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` is set on both app and test targets — don't add explicit `@MainActor` to production code or test structs/functions, it's already the default

## Swift Testing Conventions

- Place `@Test` and `@Suite` annotations on the line **above** the declaration, not inline
- Use `// when` and `// then` comment blocks; skip `// given` (assumed from context)
- When XCTest assertions have message strings, preserve them as `#expect` messages, not code comments (e.g. `#expect(x == false, "reason")`)
- Avoid `#require` on `Bool?` — it's ambiguous; use `#expect(x == true)` instead
- Capture a baseline of compiler warnings before each phase, then verify no new warnings after. Use this command and compare the output before/after:
```
xcodebuild clean build-for-testing -project "PPPC Utility.xcodeproj" -scheme "PPPC Utility" -destination "platform=macOS" 2>&1 | grep -i "warning:" | grep -v "xcodebuild: WARNING"
```
- Use parameterized tests with Traits where it reduces duplication; 1–2 args is ideal, max 3
- Beyond 3 params: create separate tests with some values hard-coded
47 changes: 14 additions & 33 deletions PPPC Utility.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@
isa = PBXNativeTarget;
buildConfigurationList = 6EC409EA214D65BD00BE4F17 /* Build configuration list for PBXNativeTarget "PPPC Utility" */;
buildPhases = (
49DB95D624991AA800F433CA /* SwiftLint */,
6EC409D6214D65BC00BE4F17 /* Sources */,
6EC409D7214D65BC00BE4F17 /* Frameworks */,
6EC409D8214D65BC00BE4F17 /* Resources */,
Expand Down Expand Up @@ -463,28 +462,6 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
49DB95D624991AA800F433CA /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = SwiftLint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
5F95AE172315A6AD002E0A22 /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down Expand Up @@ -570,9 +547,10 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = XPLDEEDNHE;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "PPPC UtilityTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -597,9 +575,10 @@
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = XPLDEEDNHE;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "PPPC UtilityTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -740,9 +719,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Resources/PPPC Utility.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = XPLDEEDNHE;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = NO;
INFOPLIST_FILE = Resources/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -756,7 +736,7 @@
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
};
name = Debug;
};
Expand All @@ -766,9 +746,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "Resources/PPPC Utility.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = XPLDEEDNHE;
DEVELOPMENT_TEAM = "";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Resources/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -782,7 +763,7 @@
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
};
name = Release;
};
Expand Down
1 change: 1 addition & 0 deletions PPPC UtilityTests/Helpers/ModelBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Cocoa

@testable import PPPC_Utility

@MainActor
class ModelBuilder {

var model: Model
Expand Down
39 changes: 22 additions & 17 deletions PPPC UtilityTests/Helpers/TCCProfileBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ class TCCProfileBuilder: NSObject {
// MARK: - build testing objects

func buildTCCPolicy(allowed: Bool?, authorization: TCCPolicyAuthorizationValue?) -> TCCPolicy {
var policy = TCCPolicy(identifier: "policy id", codeRequirement: "policy code req",
receiverIdentifier: "policy receiver id", receiverCodeRequirement: "policy receiver code req")
var policy = TCCPolicy(
identifier: "policy id", codeRequirement: "policy code req",
receiverIdentifier: "policy receiver id", receiverCodeRequirement: "policy receiver code req")
policy.comment = "policy comment"
policy.identifierType = "policy id type"
policy.receiverIdentifierType = "policy receiver id type"
Expand All @@ -44,27 +45,31 @@ class TCCProfileBuilder: NSObject {
}

func buildTCCPolicies(allowed: Bool?, authorization: TCCPolicyAuthorizationValue?) -> [String: [TCCPolicy]] {
return ["SystemPolicyAllFiles": [buildTCCPolicy(allowed: allowed, authorization: authorization)],
"AppleEvents": [buildTCCPolicy(allowed: allowed, authorization: authorization)]]
return [
"SystemPolicyAllFiles": [buildTCCPolicy(allowed: allowed, authorization: authorization)],
"AppleEvents": [buildTCCPolicy(allowed: allowed, authorization: authorization)]
]
}

func buildTCCContent(_ contentIndex: Int, allowed: Bool?, authorization: TCCPolicyAuthorizationValue?) -> TCCProfile.Content {
return TCCProfile.Content(payloadDescription: "Content Desc \(contentIndex)",
displayName: "Content Name \(contentIndex)",
identifier: "Content ID \(contentIndex)",
organization: "Content Org \(contentIndex)",
type: "Content type \(contentIndex)",
uuid: "Content UUID \(contentIndex)",
version: contentIndex,
services: buildTCCPolicies(allowed: allowed, authorization: authorization))
return TCCProfile.Content(
payloadDescription: "Content Desc \(contentIndex)",
displayName: "Content Name \(contentIndex)",
identifier: "Content ID \(contentIndex)",
organization: "Content Org \(contentIndex)",
type: "Content type \(contentIndex)",
uuid: "Content UUID \(contentIndex)",
version: contentIndex,
services: buildTCCPolicies(allowed: allowed, authorization: authorization))
}

func buildProfile(allowed: Bool? = nil, authorization: TCCPolicyAuthorizationValue? = nil) -> TCCProfile {
var profile = TCCProfile(organization: "Test Org",
identifier: "Test ID",
displayName: "Test Name",
payloadDescription: "Test Desc",
services: [:])
var profile = TCCProfile(
organization: "Test Org",
identifier: "Test ID",
displayName: "Test Name",
payloadDescription: "Test Desc",
services: [:])
profile.content = [buildTCCContent(1, allowed: allowed, authorization: authorization)]
profile.version = 100
profile.uuid = "the uuid"
Expand Down
Loading
Loading