Skip to content

Commit 49829f9

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

File tree

12 files changed

+215
-392
lines changed

12 files changed

+215
-392
lines changed

.github/workflows/continuous_integration.yml

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

.github/workflows/test.yml

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
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: Extract Code Coverage
59+
run: |
60+
# Display coverage report for logs
61+
xcrun xccov view --report TestResults.xcresult
62+
63+
# Extract target-specific coverage percentage
64+
coverage_percentage=$(xcrun xccov view --report TestResults.xcresult | grep "${{ env.COVERAGE_TARGET_FILTER }}" | head -1 | grep -o '[0-9]\+\.[0-9]\+%' | head -1)
65+
66+
if [ -n "$coverage_percentage" ]; then
67+
echo "✅ Code coverage (${{ env.COVERAGE_TARGET_FILTER }}): $coverage_percentage"
68+
else
69+
coverage_percentage="N/A"
70+
echo "⚠️ Could not extract coverage percentage for ${{ env.COVERAGE_TARGET_FILTER }}"
71+
fi
72+
73+
# Save coverage to environment for later use
74+
echo "COVERAGE_PERCENTAGE=$coverage_percentage" >> $GITHUB_ENV
75+
76+
- name: Generate Code Coverage Report for SonarQube
77+
run: |
78+
# Create sonar-reports directory
79+
mkdir -p sonar-reports
80+
81+
# Use Slather to convert coverage to SonarQube format
82+
if slather coverage \
83+
--sonarqube-xml \
84+
--output-directory sonar-reports \
85+
--scheme ${{ env.SCHEME_NAME }} \
86+
${{ env.XCODEPROJ_PATH }}; then
87+
88+
# Verify coverage file was generated
89+
if [ -f "sonar-reports/sonarqube-generic-coverage.xml" ]; then
90+
echo "✅ Coverage converted successfully with Slather"
91+
echo "📄 Generated: sonar-reports/sonarqube-generic-coverage.xml"
92+
else
93+
echo "⚠️ Slather succeeded but output file not found in expected location"
94+
echo "📁 Files in sonar-reports:"
95+
ls -la sonar-reports/ || echo "Directory doesn't exist"
96+
fi
97+
else
98+
echo "❌ Slather failed to generate coverage report"
99+
echo "ℹ️ SonarCloud will run without coverage data"
100+
echo "🔍 This is usually due to no test coverage or build issues"
101+
fi
102+
103+
- name: Run SwiftLint for SonarQube
104+
run: |
105+
swiftlint --reporter checkstyle > sonar-reports/${{ env.PROJECT_NAME }}-swiftlint.xml || true
106+
107+
- name: Setup SonarQube Scanner
108+
uses: warchant/setup-sonar-scanner@v8
109+
110+
- name: Send to SonarCloud
111+
id: sonarcloud
112+
continue-on-error: true
113+
run: |
114+
if [ -f "sonar-project.properties" ]; then
115+
SONAR_PROJECT_KEY=$(grep "^sonar.projectKey=" sonar-project.properties | cut -d'=' -f2)
116+
echo "🔍 Attempting to send results to SonarCloud..."
117+
echo "📋 Project Key: $SONAR_PROJECT_KEY"
118+
echo "🌿 Branch: ${{ github.ref_name }}"
119+
120+
sonar-scanner \
121+
-Dsonar.projectKey="$SONAR_PROJECT_KEY" \
122+
-Dsonar.branch.name=${{ github.ref_name }} \
123+
-Dsonar.projectVersion=${{ github.sha }}
124+
else
125+
echo "⚠️ sonar-project.properties not found, skipping SonarCloud upload"
126+
exit 0
127+
fi
128+
env:
129+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
131+
132+
- name: Upload Test Results
133+
uses: actions/upload-artifact@v4
134+
if: always()
135+
with:
136+
name: test-results
137+
path: |
138+
TestResults.xcresult
139+
sonar-reports/
140+
build/reports/
141+
142+
# Slack notification - Uncomment when ready to use
143+
# - name: Slack Notification
144+
# if: always()
145+
# uses: 8398a7/action-slack@v3
146+
# with:
147+
# status: ${{ job.status }}
148+
# fields: repo,message,commit,author,action,eventName,ref,workflow
149+
# webhook_url: ${{ secrets.SLACK_WEBHOOK }}
150+
# env:
151+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
152+
153+
- name: Comment Test Results
154+
if: github.event_name == 'pull_request' && always()
155+
uses: actions/github-script@v7
156+
with:
157+
script: |
158+
const { execSync } = require('child_process');
159+
160+
// Get Xcode version dynamically
161+
const xcodeVersion = execSync('xcodebuild -version | head -1', { encoding: 'utf8' }).trim();
162+
163+
// Get coverage percentage from environment
164+
const coveragePercentage = process.env.COVERAGE_PERCENTAGE || 'N/A';
165+
166+
// Check if SonarCloud step succeeded by checking job status
167+
const sonarStepSucceeded = '${{ steps.sonarcloud.outcome }}' === 'success';
168+
169+
// Dynamic message based on SonarCloud success/failure
170+
const sonarMessage = sonarStepSucceeded
171+
? '☁️ **SonarCloud**: Analysis completed - [View detailed report →](https://sonarcloud.io)'
172+
: '⚠️ **SonarCloud**: Upload failed - check workflow logs for details';
173+
174+
const nextStepsMessage = sonarStepSucceeded
175+
? '📋 **Next Steps**: Review the SonarCloud analysis for code quality insights and coverage details.'
176+
: '📋 **Next Steps**: Coverage data is available in test artifacts. SonarCloud integration needs attention.';
177+
178+
await github.rest.issues.createComment({
179+
issue_number: context.issue.number,
180+
owner: context.repo.owner,
181+
repo: context.repo.repo,
182+
body: `## 🧪 Test Results
183+
184+
✅ **Tests**: All tests passed successfully!
185+
📊 **Code Coverage**: ${coveragePercentage}
186+
${sonarMessage}
187+
188+
**Environment:**
189+
- ${xcodeVersion}
190+
- iOS Simulator (${{ env.IOS_SIMULATOR_DEVICE }})
191+
- macOS runner: ${{ runner.os }}
192+
193+
${nextStepsMessage}`
194+
});

.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)