Skip to content

Commit 677d88c

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

File tree

11 files changed

+205
-392
lines changed

11 files changed

+205
-392
lines changed

.github/workflows/continuous_integration.yml

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

.github/workflows/test.yml

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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+
xcrun xccov view --report TestResults.xcresult
62+
63+
# Extract coverage percentage and save to environment variable
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+
if [ -z "$coverage_percentage" ]; then
66+
# Fallback: try to get overall coverage
67+
coverage_percentage=$(xcrun xccov view --report TestResults.xcresult | grep -E "^\s*[0-9]+\.[0-9]+%" | head -1 | grep -o '[0-9]\+\.[0-9]\+%')
68+
fi
69+
70+
if [ -n "$coverage_percentage" ]; then
71+
echo "COVERAGE_PERCENTAGE=$coverage_percentage" >> $GITHUB_ENV
72+
echo "✅ Code coverage: $coverage_percentage"
73+
else
74+
echo "COVERAGE_PERCENTAGE=N/A" >> $GITHUB_ENV
75+
echo "⚠️ Could not extract coverage percentage"
76+
fi
77+
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+
mkdir -p sonar-reports
106+
swiftlint --reporter checkstyle > sonar-reports/${{ env.PROJECT_NAME }}-swiftlint.xml || true
107+
108+
- name: Setup SonarQube Scanner
109+
uses: warchant/setup-sonar-scanner@v8
110+
111+
- name: Send to SonarCloud
112+
id: sonarcloud
113+
continue-on-error: true
114+
run: |
115+
echo "🔍 Attempting to send results to SonarCloud..."
116+
echo "📋 Project Key: OutSystems_OSInAppBrowserLib-iOS"
117+
echo "🌿 Branch: ${{ github.ref_name }}"
118+
119+
sonar-scanner \
120+
-Dsonar.branch.name=${{ github.ref_name }} \
121+
-Dsonar.projectVersion=${{ github.sha }}
122+
env:
123+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
124+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
125+
126+
- name: Upload Test Results
127+
uses: actions/upload-artifact@v4
128+
if: always()
129+
with:
130+
name: test-results
131+
path: |
132+
TestResults.xcresult
133+
sonar-reports/
134+
build/reports/
135+
136+
# Slack notification - Uncomment when ready to use
137+
# - name: Slack Notification
138+
# if: always()
139+
# uses: 8398a7/action-slack@v3
140+
# with:
141+
# status: ${{ job.status }}
142+
# fields: repo,message,commit,author,action,eventName,ref,workflow
143+
# webhook_url: ${{ secrets.SLACK_WEBHOOK }}
144+
# env:
145+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
146+
147+
- name: Comment Test Results
148+
if: github.event_name == 'pull_request' && always()
149+
uses: actions/github-script@v7
150+
with:
151+
script: |
152+
const { execSync } = require('child_process');
153+
154+
// Get Xcode version dynamically
155+
const xcodeVersion = execSync('xcodebuild -version | head -1', { encoding: 'utf8' }).trim();
156+
157+
// Get coverage percentage from environment
158+
const coveragePercentage = process.env.COVERAGE_PERCENTAGE || 'N/A';
159+
160+
// Check if SonarCloud step succeeded by checking job status
161+
const sonarStepSucceeded = '${{ steps.sonarcloud.outcome }}' === 'success';
162+
163+
// Dynamic message based on SonarCloud success/failure
164+
const sonarMessage = sonarStepSucceeded
165+
? '☁️ **SonarCloud**: Analysis completed - [View detailed report →](https://sonarcloud.io)'
166+
: '⚠️ **SonarCloud**: Upload failed - check workflow logs for details';
167+
168+
const nextStepsMessage = sonarStepSucceeded
169+
? '📋 **Next Steps**: Review the SonarCloud analysis for code quality insights and coverage details.'
170+
: '📋 **Next Steps**: Coverage data is available in test artifacts. SonarCloud integration needs attention.';
171+
172+
await github.rest.issues.createComment({
173+
issue_number: context.issue.number,
174+
owner: context.repo.owner,
175+
repo: context.repo.repo,
176+
body: `## 🧪 Test Results
177+
178+
✅ **Tests**: All tests passed successfully!
179+
📊 **Code Coverage**: ${coveragePercentage}
180+
${sonarMessage}
181+
182+
**Environment:**
183+
- ${xcodeVersion}
184+
- iOS Simulator (${{ env.IOS_SIMULATOR_DEVICE }})
185+
- macOS runner: ${{ runner.os }}
186+
187+
${nextStepsMessage}`
188+
});

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