Skip to content

Commit d410d04

Browse files
authored
Merge pull request #228 from line/feature/cov-badge
Add test coverage badge and HTML report generation
2 parents 12a96cb + 54e4eb1 commit d410d04

File tree

7 files changed

+165
-0
lines changed

7 files changed

+165
-0
lines changed

.github/workflows/coverage.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Coverage Badge
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
coverage:
11+
name: Update Coverage Badge
12+
runs-on: macos-15
13+
environment: "Coverage Badge Env" # Use specified GitHub environment
14+
15+
steps:
16+
- name: Checkout Code
17+
uses: actions/checkout@v4
18+
19+
- name: Cache Gems
20+
uses: actions/cache@v4
21+
with:
22+
path: vendor/bundle
23+
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
24+
restore-keys: |
25+
${{ runner.os }}-gems-
26+
27+
- name: Bundle Install
28+
run: |
29+
bundle config path vendor/bundle
30+
bundle install --jobs 4 --retry 3
31+
32+
- name: Run Tests with Coverage
33+
env:
34+
SWIFT_VERSION: "6.0"
35+
run: bundle exec fastlane sdk_tests_with_coverage
36+
37+
- name: Extract Coverage
38+
id: coverage
39+
run: |
40+
ruby script/extract_coverage.rb
41+
42+
- name: Update Coverage Badge
43+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
44+
uses: schneegans/[email protected]
45+
with:
46+
auth: ${{ secrets.GIST_SECRET }}
47+
gistID: ${{ secrets.GIST_ID }}
48+
filename: line-sdk-ios-coverage.json
49+
label: Coverage
50+
message: ${{ steps.coverage.outputs.coverage }}
51+
color: ${{ steps.coverage.outputs.color }}
52+
53+
- name: Deploy Coverage Report to GitHub Pages
54+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
55+
uses: peaceiris/actions-gh-pages@v3
56+
with:
57+
github_token: ${{ secrets.GITHUB_TOKEN }}
58+
publish_dir: ./coverage_output
59+
publish_branch: gh-pages
60+
enable_jekyll: false
61+
allow_empty_commit: false
62+
force_orphan: true
63+
user_name: 'github-actions[bot]'
64+
user_email: 'github-actions[bot]@users.noreply.github.com'
65+
commit_message: 'Deploy coverage report for ${{ github.sha }}'
66+
67+
- name: Upload Coverage Artifacts
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: coverage-reports
71+
path: |
72+
./coverage_output/
73+
./test_output/
74+
retention-days: 30

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ gem "fastlane"
44
gem "jazzy"
55
gem "xcode-install"
66
gem "cocoapods"
7+
gem "xcov"
78

89
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
910
eval_gemfile(plugins_path) if File.exist?(plugins_path)

Gemfile.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ GEM
281281
simctl (1.6.10)
282282
CFPropertyList
283283
naturally
284+
slack-notifier (2.4.0)
284285
sqlite3 (1.7.3-arm64-darwin)
285286
sysrandom (1.0.5)
286287
terminal-notifier (2.0.0)
@@ -310,10 +311,18 @@ GEM
310311
colored2 (~> 3.1)
311312
nanaimo (~> 0.4.0)
312313
rexml (>= 3.3.6, < 4.0)
314+
xcov (1.8.1)
315+
fastlane (>= 2.141.0, < 3.0.0)
316+
multipart-post
317+
slack-notifier
318+
terminal-table
319+
xcodeproj
320+
xcresult (~> 0.2.0)
313321
xcpretty (0.4.1)
314322
rouge (~> 3.28.0)
315323
xcpretty-travis-formatter (1.0.1)
316324
xcpretty (~> 0.2, >= 0.0.7)
325+
xcresult (0.2.2)
317326

318327
PLATFORMS
319328
arm64-darwin-22
@@ -326,6 +335,7 @@ DEPENDENCIES
326335
fastlane-plugin-create_xcframework
327336
jazzy
328337
xcode-install
338+
xcov
329339

330340
BUNDLED WITH
331341
2.3.26

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<img src="https://raw.githubusercontent.com/line/line-sdk-ios-swift/assets/assets/sdklogo.png" width="355" height="97">
22

33
[![LINE SDK CI](https://github.com/line/line-sdk-ios-swift/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/line/line-sdk-ios-swift/actions/workflows/ci.yaml)
4+
[![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/onevcat/49ddb455d585b4c0599186552cfb0249/raw/line-sdk-ios-coverage.json)](https://line.github.io/line-sdk-ios-swift/)
45
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/LineSDKSwift.svg)](https://cocoapods.org/pods/LineSDKSwift)
56
[![Swift Package Manager Compatible](https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat)](https://swift.org/package-manager/)
67
[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)

fastlane/Fastfile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,34 @@ platform :ios do
3737
)
3838
end
3939

40+
desc "Run tests with coverage reporting"
41+
lane :sdk_tests_with_coverage do
42+
swift_version = ENV["SWIFT_VERSION"] || "6.0"
43+
44+
# Run tests with code coverage enabled
45+
run_tests(
46+
workspace: "LineSDK.xcworkspace",
47+
devices: ["iPhone 16"],
48+
scheme: "LineSDK",
49+
xcargs: "SWIFT_VERSION=#{swift_version}",
50+
code_coverage: true,
51+
output_directory: "./test_output",
52+
result_bundle: true
53+
)
54+
55+
# Generate coverage reports using xcov
56+
xcov(
57+
workspace: "LineSDK.xcworkspace",
58+
scheme: "LineSDK",
59+
output_directory: "./coverage_output",
60+
html_report: true,
61+
json_report: true,
62+
minimum_coverage_percentage: 0.0,
63+
include_test_targets: false,
64+
skip_slack: true
65+
)
66+
end
67+
4068
lane :sample_tests do
4169
# Ensure required environment variables are set
4270
unless ENV["LINE_SDK_TEST_EMAIL"] && ENV["LINE_SDK_TEST_PASSWORD"]

fastlane/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ Run tests.
3939

4040

4141

42+
### ios sdk_tests_with_coverage
43+
44+
```sh
45+
[bundle exec] fastlane ios sdk_tests_with_coverage
46+
```
47+
48+
Run tests with coverage reporting
49+
4250
### ios sample_tests
4351

4452
```sh

script/extract_coverage.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env ruby
2+
require 'json'
3+
4+
# Read coverage report from xcov
5+
coverage_file = './coverage_output/report.json'
6+
7+
if File.exist?(coverage_file)
8+
begin
9+
data = JSON.parse(File.read(coverage_file))
10+
11+
# Extract overall coverage percentage
12+
coverage_percentage = data['coverage'] ? (data['coverage'] * 100).round(1) : 0.0
13+
14+
# Determine badge color based on coverage
15+
color = case coverage_percentage
16+
when 0...60 then 'red'
17+
when 60...80 then 'yellow'
18+
when 80..100 then 'green'
19+
else 'lightgrey'
20+
end
21+
22+
puts "Coverage: #{coverage_percentage}%"
23+
puts "Color: #{color}"
24+
25+
# Output for GitHub Actions
26+
puts "::set-output name=coverage::#{coverage_percentage}%"
27+
puts "::set-output name=color::#{color}"
28+
29+
# Save coverage for reference
30+
File.write('coverage.txt', "#{coverage_percentage}%")
31+
32+
rescue JSON::ParserError => e
33+
puts "Error parsing coverage report: #{e.message}"
34+
puts "::set-output name=coverage::unknown"
35+
puts "::set-output name=color::lightgrey"
36+
File.write('coverage.txt', "unknown")
37+
end
38+
else
39+
puts "Coverage report not found at: #{coverage_file}"
40+
puts "::set-output name=coverage::unknown"
41+
puts "::set-output name=color::lightgrey"
42+
File.write('coverage.txt', "unknown")
43+
end

0 commit comments

Comments
 (0)