Skip to content

Commit e48ead9

Browse files
authored
Merge pull request #140 from cashfree/feature/swift-package-support
Feature/swift package support
2 parents bff06fd + cdff29e commit e48ead9

File tree

5 files changed

+760
-2
lines changed

5 files changed

+760
-2
lines changed
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
name: Swift Package Manager
2+
3+
on:
4+
# Validate on PRs
5+
pull_request:
6+
branches: [ main, master, develop ]
7+
paths:
8+
- 'Package.swift'
9+
- '*.xcframework/**'
10+
- '*.podspec'
11+
12+
# Handle pushes to master and tag pushes (validate only)
13+
push:
14+
branches: [ main, master ]
15+
tags: [ '[0-9]+.[0-9]+.[0-9]+', 'v[0-9]+.[0-9]+.[0-9]+' ]
16+
17+
# Manual validation and release options
18+
workflow_dispatch:
19+
inputs:
20+
action:
21+
description: 'Action to perform'
22+
required: true
23+
type: choice
24+
options:
25+
- 'validate'
26+
- 'release'
27+
default: 'validate'
28+
version:
29+
description: 'Version for manual release (e.g., 2.4.7)'
30+
required: false
31+
type: string
32+
33+
jobs:
34+
validate:
35+
name: Validate Swift Package
36+
runs-on: macos-latest
37+
38+
outputs:
39+
version: ${{ steps.get_version.outputs.version }}
40+
tag: ${{ steps.get_version.outputs.tag }}
41+
should_release: ${{ steps.get_version.outputs.should_release }}
42+
43+
steps:
44+
- name: Checkout Code
45+
uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0
48+
token: ${{ secrets.GITHUB_TOKEN }}
49+
50+
- name: Setup Xcode
51+
uses: maxim-lobanov/setup-xcode@v1
52+
with:
53+
xcode-version: latest-stable
54+
55+
- name: Get Version Info
56+
id: get_version
57+
run: |
58+
if [[ $GITHUB_REF == refs/tags/* ]]; then
59+
# Tag push - validation mode (no automated releases)
60+
tag_name=${GITHUB_REF#refs/tags/}
61+
# Remove 'v' prefix if present for version consistency
62+
version=$(echo "$tag_name" | sed 's/^v//')
63+
echo "tag=$tag_name" >> $GITHUB_OUTPUT
64+
echo "version=$version" >> $GITHUB_OUTPUT
65+
echo "should_release=false" >> $GITHUB_OUTPUT
66+
echo "🏷️ Tag push detected - validation mode for $tag_name (version: $version)"
67+
elif [[ $GITHUB_REF == refs/heads/main ]] || [[ $GITHUB_REF == refs/heads/master ]]; then
68+
# Push to master - validate only
69+
echo "tag=" >> $GITHUB_OUTPUT
70+
echo "version=" >> $GITHUB_OUTPUT
71+
echo "should_release=false" >> $GITHUB_OUTPUT
72+
echo "✅ Push to main/master - validation only mode"
73+
elif [[ "${{ github.event.inputs.action }}" == "release" ]]; then
74+
# Manual release - validation mode (no automated releases)
75+
version="${{ github.event.inputs.version }}"
76+
if [ -z "$version" ]; then
77+
current_version=$(git describe --tags --abbrev=0 2>/dev/null || echo "2.2.5")
78+
IFS='.' read -ra VERSION_PARTS <<< "$current_version"
79+
major=${VERSION_PARTS[0]:-2}
80+
minor=${VERSION_PARTS[1]:-5}
81+
patch=${VERSION_PARTS[2]:-5}
82+
patch=$((patch + 1))
83+
version="$major.$minor.$patch"
84+
fi
85+
echo "tag=$version" >> $GITHUB_OUTPUT
86+
echo "version=$version" >> $GITHUB_OUTPUT
87+
echo "should_release=false" >> $GITHUB_OUTPUT
88+
echo "🔧 Manual release validation mode - version: $version"
89+
else
90+
# PR or validation only
91+
echo "tag=" >> $GITHUB_OUTPUT
92+
echo "version=" >> $GITHUB_OUTPUT
93+
echo "should_release=false" >> $GITHUB_OUTPUT
94+
echo "✅ Validation only mode"
95+
fi
96+
97+
- name: Validate Swift Package Requirements
98+
run: |
99+
echo "🔍 Validating Swift Package Registry Requirements..."
100+
echo "=================================================="
101+
102+
# 1. Package.swift validation
103+
if [ ! -f "Package.swift" ]; then
104+
echo "❌ Package.swift not found in root folder"
105+
exit 1
106+
fi
107+
echo "✅ Package.swift exists in root folder"
108+
109+
# 2. Valid JSON output
110+
swift package dump-package > package-dump.json
111+
if [ $? -ne 0 ]; then
112+
echo "❌ Package.swift does not output valid JSON"
113+
exit 1
114+
fi
115+
echo "✅ Package.swift outputs valid JSON"
116+
117+
# 3. Swift version check
118+
swift_version=$(grep -o "swift-tools-version:[0-9]\+\.[0-9]\+" Package.swift | cut -d':' -f2 || echo "unknown")
119+
echo "📌 Swift tools version: $swift_version"
120+
121+
if [[ "$swift_version" == "unknown" ]]; then
122+
echo "❌ Could not determine Swift tools version"
123+
exit 1
124+
fi
125+
126+
major=$(echo $swift_version | cut -d'.' -f1)
127+
minor=$(echo $swift_version | cut -d'.' -f2)
128+
129+
if [ "$major" -lt 5 ] || ([ "$major" -eq 5 ] && [ "$minor" -lt 0 ]); then
130+
echo "❌ Swift version $swift_version is less than required 5.0"
131+
exit 1
132+
fi
133+
echo "✅ Swift version $swift_version meets requirement (≥5.0)"
134+
135+
# 4. Products validation
136+
products=$(python3 -c "
137+
import sys, json
138+
with open('package-dump.json') as f:
139+
data = json.load(f)
140+
products = data.get('products', [])
141+
if not products:
142+
print('NONE')
143+
else:
144+
for product in products:
145+
print(f'{product[\"name\"]}:{product[\"type\"]}')
146+
")
147+
148+
if [ "$products" = "NONE" ]; then
149+
echo "❌ No products found in Package.swift"
150+
exit 1
151+
fi
152+
153+
library_count=$(echo "$products" | grep -c ":library" || echo "0")
154+
if [ "$library_count" -eq 0 ]; then
155+
echo "❌ No library products found"
156+
exit 1
157+
fi
158+
echo "✅ Found $library_count library product(s)"
159+
160+
# 5. URL format validation
161+
repo_url="https://github.com/${{ github.repository }}.git"
162+
if [[ ! "$repo_url" =~ ^https://.*\.git$ ]]; then
163+
echo "❌ Repository URL must include protocol and .git extension"
164+
exit 1
165+
fi
166+
echo "✅ Repository URL format is correct"
167+
168+
# 6. Platform support validation (CRITICAL for SPM compliance)
169+
echo "📋 Validating platform support..."
170+
platforms=$(python3 -c "
171+
import sys, json
172+
with open('package-dump.json') as f:
173+
data = json.load(f)
174+
platforms = data.get('platforms', [])
175+
if not platforms:
176+
print('NONE')
177+
else:
178+
for platform in platforms:
179+
name = platform.get('platformName', 'unknown')
180+
version = platform.get('version', 'unknown')
181+
print(f'{name}:{version}')
182+
")
183+
184+
if [ "$platforms" = "NONE" ]; then
185+
echo "❌ No platforms declared in Package.swift - SPM requires explicit platform support"
186+
echo "💡 Add platforms array to Package.swift, e.g.:"
187+
echo " platforms: [.iOS(.v12), .macOS(.v10_15)]"
188+
exit 1
189+
fi
190+
191+
echo "📱 Declared platforms:"
192+
echo "$platforms" | while read -r platform; do
193+
name=$(echo "$platform" | cut -d':' -f1)
194+
version=$(echo "$platform" | cut -d':' -f2)
195+
echo " - $name (minimum: $version)"
196+
done
197+
198+
# Check if iOS is supported (most common requirement)
199+
ios_support=$(echo "$platforms" | grep -i "ios" || echo "")
200+
if [ -n "$ios_support" ]; then
201+
echo "✅ iOS platform support declared"
202+
else
203+
echo "⚠️ iOS platform not explicitly declared"
204+
fi
205+
206+
echo "✅ Platform declarations validated"
207+
echo "🎉 Swift Package Registry requirements validated!"
208+
209+
- name: Resolve Dependencies and Build
210+
run: |
211+
echo "📦 Resolving dependencies..."
212+
swift package resolve
213+
echo "✅ Dependencies resolved"
214+
215+
echo "🔨 Building package..."
216+
217+
# Check if package contains buildable targets
218+
has_buildable=$(swift package dump-package | python3 -c "
219+
import sys, json
220+
data = json.load(sys.stdin)
221+
buildable_targets = [t for t in data.get('targets', []) if t.get('type') != 'binary']
222+
print('true' if buildable_targets else 'false')
223+
")
224+
225+
if [ "$has_buildable" = "true" ]; then
226+
swift build
227+
echo "✅ Package built successfully"
228+
else
229+
echo "📦 Package contains only binary targets (XCFrameworks)"
230+
echo "✅ Binary package validation - no build required"
231+
fi
232+
233+
- name: Validate XCFrameworks
234+
run: |
235+
echo "🔍 Validating XCFrameworks..."
236+
for framework in *.xcframework; do
237+
if [ -d "$framework" ]; then
238+
echo "📱 Validating $framework..."
239+
if [ -f "$framework/Info.plist" ]; then
240+
echo "✅ $framework has valid Info.plist"
241+
else
242+
echo "❌ $framework missing Info.plist"
243+
exit 1
244+
fi
245+
fi
246+
done
247+
echo "✅ All XCFrameworks validated"
248+
249+
- name: Run Tests (if available)
250+
run: |
251+
# Check if package has test targets
252+
has_tests=$(swift package dump-package | python3 -c "
253+
import sys, json
254+
data = json.load(sys.stdin)
255+
test_targets = [t for t in data.get('targets', []) if t.get('type') == 'test']
256+
print('true' if test_targets else 'false')
257+
")
258+
259+
if [ "$has_tests" = "true" ]; then
260+
echo "🧪 Running tests..."
261+
swift test
262+
echo "✅ All tests passed"
263+
else
264+
echo "ℹ️ No test targets found - binary package"
265+
echo "✅ Tests not applicable for binary package"
266+
fi
267+
268+
validation_summary:
269+
name: Validation Summary
270+
runs-on: ubuntu-latest
271+
needs: validate
272+
if: always() && needs.validate.result == 'success'
273+
274+
steps:
275+
- name: Generate Validation Summary
276+
run: |
277+
echo "## 📋 Swift Package Validation Report" >> $GITHUB_STEP_SUMMARY
278+
echo "" >> $GITHUB_STEP_SUMMARY
279+
echo "### ✅ Swift Package Registry Requirements" >> $GITHUB_STEP_SUMMARY
280+
echo "- ✅ Repository is publicly accessible" >> $GITHUB_STEP_SUMMARY
281+
echo "- ✅ Package.swift exists in root folder" >> $GITHUB_STEP_SUMMARY
282+
echo "- ✅ Swift version ≥5.0 requirement met" >> $GITHUB_STEP_SUMMARY
283+
echo "- ✅ Package contains usable library products" >> $GITHUB_STEP_SUMMARY
284+
echo "- ✅ Platform support properly declared" >> $GITHUB_STEP_SUMMARY
285+
echo "- ✅ Valid JSON output from swift package dump-package" >> $GITHUB_STEP_SUMMARY
286+
echo "- ✅ Package URL includes protocol and .git extension" >> $GITHUB_STEP_SUMMARY
287+
echo "- ✅ Package compiles without errors" >> $GITHUB_STEP_SUMMARY
288+
echo "" >> $GITHUB_STEP_SUMMARY
289+
echo "### ✅ Additional Validation Results" >> $GITHUB_STEP_SUMMARY
290+
echo "- ✅ Dependencies resolved successfully" >> $GITHUB_STEP_SUMMARY
291+
echo "- ✅ Binary package validation completed" >> $GITHUB_STEP_SUMMARY
292+
echo "- ✅ XCFrameworks are properly structured" >> $GITHUB_STEP_SUMMARY
293+
echo "" >> $GITHUB_STEP_SUMMARY
294+
echo "### 📦 Package Type" >> $GITHUB_STEP_SUMMARY
295+
echo "This is a **binary package** containing XCFrameworks only." >> $GITHUB_STEP_SUMMARY
296+
echo "No source code compilation required." >> $GITHUB_STEP_SUMMARY
297+
echo "" >> $GITHUB_STEP_SUMMARY
298+
299+
# Show validation results based on trigger type
300+
if [[ "${{ startsWith(github.ref, 'refs/tags/') }}" == "true" ]]; then
301+
echo "### 🏷️ Tag Validation Complete" >> $GITHUB_STEP_SUMMARY
302+
echo "Tag **${{ github.ref_name }}** validation successful." >> $GITHUB_STEP_SUMMARY
303+
elif [[ "${{ github.event.inputs.action }}" == "release" ]]; then
304+
echo "### 🔧 Manual Release Validation Complete" >> $GITHUB_STEP_SUMMARY
305+
echo "Release validation successful for version **${{ needs.validate.outputs.version }}**." >> $GITHUB_STEP_SUMMARY
306+
else
307+
echo "### ✅ Validation Complete" >> $GITHUB_STEP_SUMMARY
308+
echo "Package validation successful." >> $GITHUB_STEP_SUMMARY
309+
fi
310+
echo "" >> $GITHUB_STEP_SUMMARY
311+
echo "**Note**: Validation ensures your package meets Swift Package Manager standards." >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22
./*/.DS_Store
33
*/*/.DS_Store
44
*/*/*/.DS_Store
5-
Swift+Sample+Application/.DS_Store
5+
Swift+Sample+Application/.DS_Store
6+
7+
# Swift Package Manager
8+
.build/
9+
.swiftpm/
10+
Package.resolved

Package.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// swift-tools-version:5.7
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "CashfreePG",
8+
platforms: [
9+
.iOS(.v12)
10+
],
11+
products: [
12+
// Products define the executables and libraries a package produces, and make them visible to other packages.
13+
.library(
14+
name: "CashfreePG",
15+
targets: ["CashfreePG"]
16+
),
17+
.library(
18+
name: "CashfreePGCoreSDK",
19+
targets: ["CashfreePGCoreSDK"]
20+
),
21+
.library(
22+
name: "CashfreePGUISDK",
23+
targets: ["CashfreePGUISDK"]
24+
),
25+
.library(
26+
name: "CashfreeAnalyticsSDK",
27+
targets: ["CashfreeAnalyticsSDK"]
28+
),
29+
.library(
30+
name: "CFNetworkSDK",
31+
targets: ["CFNetworkSDK"]
32+
)
33+
],
34+
dependencies: [
35+
// Dependencies declare other packages that this package depends on.
36+
],
37+
targets: [
38+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
39+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
40+
41+
// CFNetworkSDK - Base networking framework
42+
.binaryTarget(
43+
name: "CFNetworkSDK",
44+
path: "CFNetworkSDK.xcframework"
45+
),
46+
47+
// CashfreeAnalyticsSDK - Depends on CFNetworkSDK
48+
.binaryTarget(
49+
name: "CashfreeAnalyticsSDK",
50+
path: "CashfreeAnalyticsSDK.xcframework"
51+
),
52+
53+
// CashfreePGCoreSDK - Depends on CashfreeAnalyticsSDK
54+
.binaryTarget(
55+
name: "CashfreePGCoreSDK",
56+
path: "CashfreePGCoreSDK.xcframework"
57+
),
58+
59+
// CashfreePGUISDK - Depends on CashfreePGCoreSDK
60+
.binaryTarget(
61+
name: "CashfreePGUISDK",
62+
path: "CashfreePGUISDK.xcframework"
63+
),
64+
65+
// CashfreePG - Main target that depends on CashfreePGUISDK
66+
.binaryTarget(
67+
name: "CashfreePG",
68+
path: "CashfreePG.xcframework"
69+
)
70+
]
71+
)

0 commit comments

Comments
 (0)