Skip to content

Commit 95ca116

Browse files
d-dateclaude
andauthored
Clean up docs and update build workflow for all 17 modules (#89)
- Remove obsolete one-time documents (BUILD_PLAN.md, VERIFICATION_REPORT.md, IMPLEMENTATION_SUMMARY.md) - Update README.md requirements to match Package.swift (iOS 15, Xcode 15) and list all supported module variants - Rewrite AGENTS.md to reflect actual project (build system, not SwiftUI app) - Remove completed "Multi-Module Support" from AUTOMATION.md future items - Simplify TESTING.md by removing redundant batch build strategies - Update build-mlkit.yml: use `make run`, dynamic asset deletion, full module list in release notes, include bundle.zip in uploads Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4fc8bcd commit 95ca116

8 files changed

Lines changed: 65 additions & 972 deletions

File tree

.github/workflows/build-mlkit.yml

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,8 @@ jobs:
4040
- name: Update version in Podfile
4141
run: ruby scripts/update_version.rb ${{ inputs.version }}
4242

43-
- name: Build XCFramework maker
44-
run: make bootstrap-builder
45-
46-
- name: Install CocoaPods
47-
run: make bootstrap-cocoapods
48-
49-
- name: Build XCFrameworks
50-
run: make create-xcframework
51-
52-
- name: Archive XCFrameworks
53-
run: make archive
43+
- name: Build and archive XCFrameworks
44+
run: make run
5445

5546
- name: Calculate checksums and update Package.swift
5647
run: ruby scripts/update_checksums.rb ${{ inputs.version }}
@@ -106,8 +97,8 @@ jobs:
10697
if: inputs.create_release && steps.check_release.outputs.exists == 'true'
10798
run: |
10899
echo "Deleting old assets from existing release..."
109-
for asset in GoogleToolboxForMac.xcframework.zip MLImage.xcframework.zip MLKitBarcodeScanning.xcframework.zip MLKitCommon.xcframework.zip MLKitFaceDetection.xcframework.zip MLKitVision.xcframework.zip; do
110-
if gh release view ${{ inputs.version }} --json assets --jq ".assets[].name" | grep -q "^${asset}$"; then
100+
gh release view ${{ inputs.version }} --json assets --jq ".assets[].name" | while read -r asset; do
101+
if [[ "$asset" == *.xcframework.zip ]] || [[ "$asset" == *.bundle.zip ]]; then
111102
echo " Deleting: $asset"
112103
gh release delete-asset ${{ inputs.version }} "$asset" --yes || true
113104
fi
@@ -142,22 +133,34 @@ jobs:
142133
143134
## Available Libraries
144135
136+
### Vision APIs
145137
- MLKitBarcodeScanning
146138
- MLKitFaceDetection
139+
- MLKitTextRecognition (+ Chinese, Devanagari, Japanese, Korean)
140+
- MLKitImageLabeling (+ Custom)
141+
- MLKitObjectDetection (+ Custom)
142+
- MLKitPoseDetection (+ Accurate)
143+
- MLKitSegmentationSelfie
144+
145+
### Language APIs
146+
- MLKitLanguageID
147+
- MLKitTranslate
148+
- MLKitSmartReply
147149
148150
🤖 This release was automatically generated
149151
draft: false
150152
prerelease: false
151153
files: |
152154
GoogleMLKit/*.xcframework.zip
155+
GoogleMLKit/*.bundle.zip
153156
env:
154157
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
155158

156159
- name: Upload assets to existing release
157160
if: inputs.create_release && steps.check_release.outputs.exists == 'true'
158161
run: |
159162
echo "Uploading new assets to existing release..."
160-
gh release upload ${{ inputs.version }} GoogleMLKit/*.xcframework.zip --clobber
163+
gh release upload ${{ inputs.version }} GoogleMLKit/*.xcframework.zip GoogleMLKit/*.bundle.zip --clobber
161164
env:
162165
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
163166

@@ -166,7 +169,9 @@ jobs:
166169
uses: actions/upload-artifact@v6
167170
with:
168171
name: xcframeworks-${{ inputs.version }}
169-
path: GoogleMLKit/*.xcframework.zip
172+
path: |
173+
GoogleMLKit/*.xcframework.zip
174+
GoogleMLKit/*.bundle.zip
170175
retention-days: 30
171176

172177
- name: Comment on related issue

AGENTS.md

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,43 @@
1-
# Agent guide for Swift and SwiftUI
1+
# Agent guide for Google MLKit SwiftPM
22

3-
This repository contains an Xcode project written with Swift and SwiftUI. Please follow the guidelines below so that the development experience is built on modern, safe API usage.
3+
This repository wraps Google ML Kit frameworks for Swift Package Manager compatibility. It converts CocoaPods-distributed ML Kit frameworks to XCFrameworks.
44

55
## Role
66

7-
You are a **Senior iOS Engineer**, specializing in SwiftUI, SwiftData, and related frameworks. Your code must always adhere to Apple's Human Interface Guidelines and App Review guidelines.
7+
You are a **Senior iOS Engineer** maintaining a SwiftPM binary distribution package. Your work involves Ruby automation scripts, Makefile build orchestration, and GitHub Actions CI/CD.
88

99
## Core instructions
1010

11-
- Target iOS 26.0 or later. (Yes, it definitely exists.)
12-
- Swift 6.2 or later, using modern Swift concurrency.
13-
- SwiftUI backed up by `@Observable` classes for shared data.
11+
- Target iOS 15.0 or later (matches Package.swift platform requirement).
12+
- Swift tools version 5.9 (matches Package.swift).
1413
- Do not introduce third-party frameworks without asking first.
15-
- Avoid UIKit unless requested.
14+
- This is NOT a typical app project. It is a build/packaging system that produces XCFrameworks from CocoaPods.
1615

17-
## Swift instructions
18-
19-
- Always mark `@Observable` classes with `@MainActor`.
20-
- Assume strict Swift concurrency rules are being applied.
21-
- Prefer Swift-native alternatives to Foundation methods where they exist, such as using `replacing("hello", with: "world")` with strings rather than `replacingOccurrences(of: "hello", with: "world")`.
22-
- Prefer modern Foundation API, for example `URL.documentsDirectory` to find the app’s documents directory, and `appending(path:)` to append strings to a URL.
23-
- Never use C-style number formatting such as `Text(String(format: "%.2f", abs(myNumber)))`; always use `Text(abs(change), format: .number.precision(.fractionLength(2)))` instead.
24-
- Prefer static member lookup to struct instances where possible, such as `.circle` rather than `Circle()`, and `.borderedProminent` rather than `BorderedProminentButtonStyle()`.
25-
- Never use old-style Grand Central Dispatch concurrency such as `DispatchQueue.main.async()`. If behavior like this is needed, always use modern Swift concurrency.
26-
- Filtering text based on user-input must be done using `localizedStandardContains()` as opposed to `contains()`.
27-
- Avoid force unwraps and force `try` unless it is unrecoverable.
28-
29-
## SwiftUI instructions
30-
31-
- Always use `foregroundStyle()` instead of `foregroundColor()`.
32-
- Always use `clipShape(.rect(cornerRadius:))` instead of `cornerRadius()`.
33-
- Always use the `Tab` API instead of `tabItem()`.
34-
- Never use `ObservableObject`; always prefer `@Observable` classes instead.
35-
- Never use the `onChange()` modifier in its 1-parameter variant; either use the variant that accepts two parameters or accepts none.
36-
- Never use `onTapGesture()` unless you specifically need to know a tap’s location or the number of taps. All other usages should use `Button`.
37-
- Never use `Task.sleep(nanoseconds:)`; always use `Task.sleep(for:)` instead.
38-
- Never use `UIScreen.main.bounds` to read the size of the available space.
39-
- Do not break views up using computed properties; place them into new `View` structs instead.
40-
- Do not force specific font sizes; prefer using Dynamic Type instead.
41-
- Use the `navigationDestination(for:)` modifier to specify navigation, and always use `NavigationStack` instead of the old `NavigationView`.
42-
- If using an image for a button label, always specify text alongside like this: `Button("Tap me", systemImage: "plus", action: myButtonAction)`.
43-
- When rendering SwiftUI views, always prefer using `ImageRenderer` to `UIGraphicsImageRenderer`.
44-
- Don’t apply the `fontWeight()` modifier unless there is good reason. If you want to make some text bold, always use `bold()` instead of `fontWeight(.bold)`.
45-
- Do not use `GeometryReader` if a newer alternative would work as well, such as `containerRelativeFrame()` or `visualEffect()`.
46-
- When making a `ForEach` out of an `enumerated` sequence, do not convert it to an array first. So, prefer `ForEach(x.enumerated(), id: \.element.id)` instead of `ForEach(Array(x.enumerated()), id: \.element.id)`.
47-
- When hiding scroll view indicators, use the `.scrollIndicators(.hidden)` modifier rather than using `showsIndicators: false` in the scroll view initializer.
48-
- Place view logic into view models or similar, so it can be tested.
49-
- Avoid `AnyView` unless it is absolutely required.
50-
- Avoid specifying hard-coded values for padding and stack spacing unless requested.
51-
- Avoid using UIKit colors in SwiftUI code.
16+
## Project structure
5217

53-
## SwiftData instructions
18+
- `Package.swift` - Swift package definition with 17 library products and 30+ binary targets
19+
- `Podfile` - CocoaPods dependencies for downloading ML Kit frameworks
20+
- `Makefile` - Build orchestration (bootstrap, build, create-xcframework, archive)
21+
- `scripts/` - Ruby and shell automation scripts
22+
- `Resources/` - Info.plist templates for frameworks that lack them
23+
- `xcframework-maker/` - Submodule for XCFramework conversion tool
24+
- `Example/` - Reference iOS app demonstrating ML Kit modules
25+
- `.github/workflows/` - CI/CD for version checking and building
5426

55-
If SwiftData is configured to use CloudKit:
27+
## Key workflows
5628

57-
- Never use `@Attribute(.unique)`.
58-
- Model properties must always either have default values or be marked as optional.
59-
- All relationships must be marked optional.
29+
1. **Version check**: `check-mlkit-updates.yml` runs daily, creates GitHub issues for new ML Kit versions
30+
2. **Build**: `build-mlkit.yml` is triggered manually, builds XCFrameworks and creates releases
31+
3. **Local build**: `./scripts/build_all.sh <version>` for local development
6032

61-
## Project structure
33+
## Script conventions
6234

63-
- Use a consistent project structure, with folder layout determined by app features.
64-
- Follow strict naming conventions for types, properties, methods, and SwiftData models.
65-
- Break different types up into different Swift files rather than placing multiple structs, classes, or enums into a single file.
66-
- Write unit tests for core application logic.
67-
- Only write UI tests if unit tests are not possible.
68-
- Add code comments and documentation comments as needed.
69-
- If the project requires secrets such as API keys, never include them in the repository.
35+
- Ruby scripts use standard library only (no gems beyond CocoaPods)
36+
- Shell scripts are POSIX-compatible where possible
37+
- All scripts should handle errors gracefully and provide clear output
7038

7139
## PR instructions
7240

73-
- If installed, make sure SwiftLint returns no warnings or errors before committing.
41+
- Test automation scripts locally before committing
42+
- Verify Package.swift syntax: `swift package dump-package`
43+
- Update documentation if adding new modules or changing build process

AUTOMATION.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,7 @@ Possible enhancements:
259259
- Add automated tests to verify the built frameworks work correctly
260260
- Test integration with sample projects
261261

262-
3. **Multi-Module Support**
263-
- Extend to support more MLKit modules beyond BarcodeScanning and FaceDetection
264-
265-
4. **Changelog Generation**
262+
3. **Changelog Generation**
266263
- Automatically generate changelogs based on MLKit release notes
267264

268265
## Contributing

0 commit comments

Comments
 (0)