Skip to content

Commit cd29fa3

Browse files
committed
Migrate from Fastlane to GitHub Actions
1 parent f619d31 commit cd29fa3

File tree

12 files changed

+229
-392
lines changed

12 files changed

+229
-392
lines changed

.github/workflows/continuous_integration.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

.github/workflows/test.yml

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: Test Suite
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- misc/RMET-4346/ci-cd # Temporary for testing
8+
pull_request:
9+
types: [opened, synchronize, reopened]
10+
11+
jobs:
12+
test:
13+
name: Run Tests
14+
runs-on: macos-latest
15+
16+
env:
17+
IOS_SIMULATOR_DEVICE: "iPhone 16"
18+
PROJECT_NAME: "OSInAppBrowserLib" # Name used for output files
19+
SCHEME_NAME: "OSInAppBrowserLib" # Xcode scheme to build/test
20+
XCODEPROJ_PATH: "OSInAppBrowserLib.xcodeproj" # Path to .xcodeproj file
21+
COVERAGE_TARGET_FILTER: "OSInAppBrowserLib" # Target name for coverage filtering
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Install Dependencies
28+
run: |
29+
# Install SwiftLint
30+
if ! command -v swiftlint &> /dev/null; then
31+
brew install swiftlint
32+
fi
33+
34+
# Install xcbeautify for better output formatting
35+
if ! command -v xcbeautify &> /dev/null; then
36+
brew install xcbeautify
37+
fi
38+
39+
# Install slather for coverage conversion
40+
if ! gem list slather -i &> /dev/null; then
41+
gem install slather
42+
fi
43+
44+
- name: Run Unit Tests
45+
run: |
46+
mkdir -p build/reports
47+
set -o pipefail
48+
xcodebuild test \
49+
-project ${{ env.XCODEPROJ_PATH }} \
50+
-scheme ${{ env.SCHEME_NAME }} \
51+
-destination "platform=iOS Simulator,name=${{ env.IOS_SIMULATOR_DEVICE }}" \
52+
-configuration Debug \
53+
-enableCodeCoverage YES \
54+
-resultBundlePath TestResults.xcresult \
55+
SKIP_SCRIPT_PHASES=YES \
56+
CODE_SIGNING_ALLOWED=NO | xcbeautify --report junit --report-path build/reports/junit.xml
57+
58+
- name: Generate Code Coverage Report for SonarQube
59+
run: |
60+
# Display coverage report for logs
61+
echo "📊 Full Coverage Report:"
62+
xcrun xccov view --report TestResults.xcresult
63+
64+
echo ""
65+
echo "🔍 Extracting coverage percentage..."
66+
67+
# Try to get overall coverage first (the number that appears at the top)
68+
overall_coverage=$(xcrun xccov view --report TestResults.xcresult | head -20 | grep -E "^\s*[0-9]+\.[0-9]+%" | head -1 | grep -o '[0-9]\+\.[0-9]\+%')
69+
70+
# Also try to get target-specific coverage for comparison
71+
target_coverage=$(xcrun xccov view --report TestResults.xcresult | grep "${{ env.COVERAGE_TARGET_FILTER }}" | head -1 | grep -o '[0-9]\+\.[0-9]\+%' | head -1)
72+
73+
# Prefer overall coverage, fallback to target-specific
74+
if [ -n "$overall_coverage" ]; then
75+
coverage_percentage="$overall_coverage"
76+
echo "✅ Overall code coverage: $coverage_percentage"
77+
if [ -n "$target_coverage" ] && [ "$target_coverage" != "$overall_coverage" ]; then
78+
echo "📋 Target-specific coverage (${{ env.COVERAGE_TARGET_FILTER }}): $target_coverage"
79+
fi
80+
elif [ -n "$target_coverage" ]; then
81+
coverage_percentage="$target_coverage"
82+
echo "✅ Target code coverage (${{ env.COVERAGE_TARGET_FILTER }}): $coverage_percentage"
83+
else
84+
coverage_percentage="N/A"
85+
echo "⚠️ Could not extract coverage percentage"
86+
fi
87+
88+
# Save coverage to environment for later use
89+
echo "COVERAGE_PERCENTAGE=$coverage_percentage" >> $GITHUB_ENV
90+
91+
# Create sonar-reports directory
92+
mkdir -p sonar-reports
93+
94+
# Use Slather to convert coverage to SonarQube format
95+
if slather coverage \
96+
--sonarqube-xml \
97+
--output-directory sonar-reports \
98+
--scheme ${{ env.SCHEME_NAME }} \
99+
${{ env.XCODEPROJ_PATH }}; then
100+
101+
# Verify coverage file was generated
102+
if [ -f "sonar-reports/sonarqube-generic-coverage.xml" ]; then
103+
echo "✅ Coverage converted successfully with Slather"
104+
echo "📄 Generated: sonar-reports/sonarqube-generic-coverage.xml"
105+
else
106+
echo "⚠️ Slather succeeded but output file not found in expected location"
107+
echo "📁 Files in sonar-reports:"
108+
ls -la sonar-reports/ || echo "Directory doesn't exist"
109+
fi
110+
else
111+
echo "❌ Slather failed to generate coverage report"
112+
echo "ℹ️ SonarCloud will run without coverage data"
113+
echo "🔍 This is usually due to no test coverage or build issues"
114+
fi
115+
116+
- name: Run SwiftLint for SonarQube
117+
run: |
118+
mkdir -p sonar-reports
119+
swiftlint --reporter checkstyle > sonar-reports/${{ env.PROJECT_NAME }}-swiftlint.xml || true
120+
121+
- name: Setup SonarQube Scanner
122+
uses: warchant/setup-sonar-scanner@v8
123+
124+
- name: Send to SonarCloud
125+
id: sonarcloud
126+
continue-on-error: true
127+
run: |
128+
if [ -f "sonar-project.properties" ]; then
129+
SONAR_PROJECT_KEY=$(grep "^sonar.projectKey=" sonar-project.properties | cut -d'=' -f2)
130+
echo "🔍 Attempting to send results to SonarCloud..."
131+
echo "📋 Project Key: $SONAR_PROJECT_KEY"
132+
echo "🌿 Branch: ${{ github.ref_name }}"
133+
134+
sonar-scanner \
135+
-Dsonar.projectKey="$SONAR_PROJECT_KEY" \
136+
-Dsonar.branch.name=${{ github.ref_name }} \
137+
-Dsonar.projectVersion=${{ github.sha }}
138+
else
139+
echo "⚠️ sonar-project.properties not found, skipping SonarCloud upload"
140+
exit 0
141+
fi
142+
env:
143+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
144+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
145+
146+
- name: Upload Test Results
147+
uses: actions/upload-artifact@v4
148+
if: always()
149+
with:
150+
name: test-results
151+
path: |
152+
TestResults.xcresult
153+
sonar-reports/
154+
build/reports/
155+
156+
# Slack notification - Uncomment when ready to use
157+
# - name: Slack Notification
158+
# if: always()
159+
# uses: 8398a7/action-slack@v3
160+
# with:
161+
# status: ${{ job.status }}
162+
# fields: repo,message,commit,author,action,eventName,ref,workflow
163+
# webhook_url: ${{ secrets.SLACK_WEBHOOK }}
164+
# env:
165+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
166+
167+
- name: Comment Test Results
168+
if: github.event_name == 'pull_request' && always()
169+
uses: actions/github-script@v7
170+
with:
171+
script: |
172+
const { execSync } = require('child_process');
173+
174+
// Get Xcode version dynamically
175+
const xcodeVersion = execSync('xcodebuild -version | head -1', { encoding: 'utf8' }).trim();
176+
177+
// Get coverage percentage from environment
178+
const coveragePercentage = process.env.COVERAGE_PERCENTAGE || 'N/A';
179+
180+
// Check if SonarCloud step succeeded by checking job status
181+
const sonarStepSucceeded = '${{ steps.sonarcloud.outcome }}' === 'success';
182+
183+
// Dynamic message based on SonarCloud success/failure
184+
const sonarMessage = sonarStepSucceeded
185+
? '☁️ **SonarCloud**: Analysis completed - [View detailed report →](https://sonarcloud.io)'
186+
: '⚠️ **SonarCloud**: Upload failed - check workflow logs for details';
187+
188+
const nextStepsMessage = sonarStepSucceeded
189+
? '📋 **Next Steps**: Review the SonarCloud analysis for code quality insights and coverage details.'
190+
: '📋 **Next Steps**: Coverage data is available in test artifacts. SonarCloud integration needs attention.';
191+
192+
await github.rest.issues.createComment({
193+
issue_number: context.issue.number,
194+
owner: context.repo.owner,
195+
repo: context.repo.repo,
196+
body: `## 🧪 Test Results
197+
198+
✅ **Tests**: All tests passed successfully!
199+
📊 **Code Coverage**: ${coveragePercentage}
200+
${sonarMessage}
201+
202+
**Environment:**
203+
- ${xcodeVersion}
204+
- iOS Simulator (${{ env.IOS_SIMULATOR_DEVICE }})
205+
- macOS runner: ${{ runner.os }}
206+
207+
${nextStepsMessage}`
208+
});

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,9 @@ iOSInjectionProject/
9191

9292
# macOS
9393
.DS_Store
94+
95+
# GitHub Actions CI/CD artifacts
96+
# Generated by test workflow
97+
TestResults.xcresult/
98+
build/reports/
99+
sonar-reports/

Gemfile

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)