Skip to content

Commit 3a898be

Browse files
author
Alexey Alter-Pesotskiy
authored
[CIS-1766] SonarCloud implementation (#55)
1 parent 136d7ae commit 3a898be

14 files changed

+178
-30
lines changed

.github/workflows/smoke-checks.yml

+15-9
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ on:
1111
types:
1212
- created
1313

14-
concurrency:
14+
concurrency:
1515
group: ${{ github.workflow }}-${{ github.ref }}
1616
cancel-in-progress: true
17-
17+
1818
env:
19-
HOMEBREW_NO_INSTALL_CLEANUP=1: 1 # Disable cleanup for homebrew, we don't need it on CI
19+
HOMEBREW_NO_INSTALL_CLEANUP: 1 # Disable cleanup for homebrew, we don't need it on CI
2020

2121
jobs:
2222
automated-code-review:
@@ -54,6 +54,10 @@ jobs:
5454
- uses: actions/checkout@v1
5555
- name: Set build image var
5656
run: echo "ImageVersion=$ImageVersion" >> $GITHUB_ENV
57+
- uses: actions/[email protected]
58+
with:
59+
python-version: 3.8
60+
cache: 'pip'
5761
- name: Cache RubyGems
5862
uses: actions/cache@v2
5963
id: rubygem-cache
@@ -69,6 +73,8 @@ jobs:
6973
key: ${{ runner.os }}-mint-${{ hashFiles('./Mintfile') }}
7074
restore-keys: ${{ runner.os }}-mint-
7175
- uses: ./.github/actions/bootstrap
76+
env:
77+
INSTALL_SONAR: true
7278
- name: Prepare iPhone 12 with iOS 15.4
7379
uses: ./.github/actions/prepare-ios-simulator
7480
with:
@@ -77,12 +83,12 @@ jobs:
7783
xcode: "13.3.1"
7884
- name: Run Tests (Debug)
7985
run: bundle exec fastlane test_ui device:"iPhone 12 (15.4)"
80-
- uses: codecov/codecov-action@v1
81-
with:
82-
token: ${{ secrets.CODECOV_TOKEN }}
83-
flags: unit-tests
84-
fail_ci_if_error: true # if codecov upload fails, should fail ci
85-
verbose: true
86+
- name: Run Sonar analysis
87+
run: bundle exec fastlane sonar_upload
88+
env:
89+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
90+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
91+
PR_NUMBER: ${{ github.event.number }}
8692
- uses: 8398a7/action-slack@v3
8793
with:
8894
status: ${{ job.status }}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,5 @@ Example/Carthage/.env
7474
Example/Carthage/fastlane/report.xml
7575
Sample/Cocoapods/Podfile.lock
7676
docusaurus/.env
77+
reports/
78+
.scannerwork/

.slather.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
coverage_service: sonarqube_xml
2+
xcodeproj: StreamChatSwiftUI.xcodeproj
3+
scheme: StreamChatSwiftUI
4+
source_directory: Sources/
5+
output_directory: reports
6+
ignore:
7+
- "StreamChatSwiftUITests/**/*"
8+
- "**/*_Tests.swift"
9+
- "**/*_Mock.swift"
10+
- "**/*_Vendor.swift"
11+
- "**/Generated/*.swift"

Gemfile

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ gem "danger-commit_lint"
1111
gem "jazzy"
1212
gem "xcode-install"
1313
gem "json"
14+
gem "fastlane-plugin-lizard"
15+
gem "slather"
1416

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

Gemfile.lock

+25
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ GEM
3838
cork
3939
nap
4040
open4 (~> 1.3)
41+
clamp (1.3.2)
4142
cocoapods (1.11.3)
4243
addressable (~> 2.8)
4344
claide (>= 1.0.2, < 2.0)
@@ -75,6 +76,7 @@ GEM
7576
nap (>= 0.8, < 2.0)
7677
netrc (~> 0.11)
7778
cocoapods-try (1.2.0)
79+
coderay (1.1.3)
7880
colored (1.2)
7981
colored2 (3.1.2)
8082
commander (4.6.0)
@@ -183,6 +185,11 @@ GEM
183185
fastlane-plugin-emerge (0.5.1)
184186
faraday (~> 1.1)
185187
fastlane-plugin-firebase_app_distribution (0.3.4)
188+
fastlane-plugin-lizard (1.3.3)
189+
bundler
190+
fastlane
191+
pry
192+
fastlane-plugin-sonarcloud_metric_kit (0.2.0)
186193
fastlane-plugin-versioning (0.5.0)
187194
ffi (1.15.5)
188195
fourflusher (2.3.1)
@@ -253,6 +260,7 @@ GEM
253260
kramdown (~> 2.0)
254261
liferaft (0.0.6)
255262
memoist (0.16.2)
263+
method_source (1.0.0)
256264
mini_magick (4.11.0)
257265
mini_mime (1.1.2)
258266
minitest (5.15.0)
@@ -265,14 +273,22 @@ GEM
265273
naturally (2.2.1)
266274
netrc (0.11.0)
267275
no_proxy_fix (0.1.2)
276+
nokogiri (1.13.4-arm64-darwin)
277+
racc (~> 1.4)
278+
nokogiri (1.13.4-x86_64-darwin)
279+
racc (~> 1.4)
268280
octokit (4.22.0)
269281
faraday (>= 0.9)
270282
sawyer (~> 0.8.0, >= 0.5.3)
271283
open4 (1.3.4)
272284
optparse (0.1.1)
273285
os (1.1.4)
274286
plist (3.6.0)
287+
pry (0.14.1)
288+
coderay (~> 1.1)
289+
method_source (~> 1.0)
275290
public_suffix (4.0.7)
291+
racc (1.6.0)
276292
rake (13.0.6)
277293
rchardet (1.8.0)
278294
redcarpet (3.5.1)
@@ -300,6 +316,12 @@ GEM
300316
simctl (1.6.8)
301317
CFPropertyList
302318
naturally
319+
slather (2.7.2)
320+
CFPropertyList (>= 2.2, < 4)
321+
activesupport
322+
clamp (~> 1.3)
323+
nokogiri (~> 1.12)
324+
xcodeproj (~> 1.21)
303325
sqlite3 (1.4.2)
304326
terminal-notifier (2.0.0)
305327
terminal-table (1.8.0)
@@ -348,9 +370,12 @@ DEPENDENCIES
348370
fastlane
349371
fastlane-plugin-emerge
350372
fastlane-plugin-firebase_app_distribution
373+
fastlane-plugin-lizard
374+
fastlane-plugin-sonarcloud_metric_kit
351375
fastlane-plugin-versioning
352376
jazzy
353377
json
378+
slather
354379
xcode-install
355380

356381
BUNDLED WITH

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
<img src="ReadmeAssets/iOS_Chat_Messaging.png"/>
33
</p>
44

5+
<p align="center">
6+
<a href="https://sonarcloud.io/summary/new_code?id=GetStream_stream-chat-swiftui"><img src="https://sonarcloud.io/api/project_badges/measure?project=GetStream_stream-chat-swiftui&metric=coverage" /></a>
7+
</p>
8+
59
## SwiftUI StreamChat SDK
610

711
The SwiftUI SDK is built on top of the [StreamChat](https://getstream.io/chat/docs/ios-swift/?language=swift) framework and it's a SwiftUI alternative to the [StreamChatUI](https://getstream.io/chat/docs/sdk/ios/) SDK. It's built completely in SwiftUI, using declarative patterns, that will be familiar to developers working with SwiftUI. The SDK includes an extensive set of performant and customizable UI components which allow you to get started quickly with little to no plumbing required.
@@ -13,7 +17,7 @@ The complete documentation and capabilities of the SwiftUI SDK can be found [her
1317
- **Channel list:** Browse channels and perform actions on them.
1418
- **Message list:** Fast message list that renders many different types of messages.
1519
- **Message Composer:** Powerful and customizable message composer, extendable with your own custom attachments.
16-
- **Message reactions:** Ready made reactions support, easily configurable depending on your use-cases.
20+
- **Message reactions:** Ready made reactions support, easily configurable depending on your use-cases.
1721
- **Offline support:** Browse channels and send messages while offline.
1822
- **Highly customizable components:** The components are designed in a way that you can easily customize or completely swap existing views with your own implementation.
1923

@@ -31,7 +35,7 @@ The SwiftUI SDK offers three types of components:
3135

3236
- Screens - Easiest to integrate, but offer small customizations, like branding and text changes.
3337
- Stateful components - Offer more customization options and possibility to inject custom views. Also fairly simple to integrate, if the extension points are suitable for your chat use-case. These components come with view models.
34-
- Stateless components - These are the building blocks for the other two types of components. In order to use them, you would have to provide the state and data. Using these components only make sense if you want to implement completely custom chat experience.
38+
- Stateless components - These are the building blocks for the other two types of components. In order to use them, you would have to provide the state and data. Using these components only make sense if you want to implement completely custom chat experience.
3539

3640
## Free for Makers
3741

bootstrap.sh

+16-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
# You should have homebrew installed.
55
# If you get `zsh: permission denied: ./bootstrap.sh` error, please run `chmod +x bootstrap.sh` first
66

7+
function puts {
8+
echo
9+
echo -e "👉 ${1}"
10+
}
11+
712
# Check if Homebrew is installed
813
if [[ $(command -v brew) == "" ]]; then
914
echo "Homebrew not installed. Please install."
@@ -14,31 +19,32 @@ set -Eeuo pipefail
1419

1520
trap "echo ; echo ❌ The Bootstrap script failed to finish without error. See the log above to debug. ; echo" ERR
1621

17-
echo
18-
echo -e "👉 Install Mint if needed"
22+
puts "Install Mint if needed"
1923
# List installed Mint versions, if fails, install Mint
2024
brew list mint || brew install mint
2125

2226
# Set bash to Strict Mode (http://redsymbol.net/articles/unofficial-bash-strict-mode/)
2327
set -euo pipefail
2428

25-
echo
26-
echo -e "👉 Bootstrap Mint dependencies"
29+
puts "Bootstrap Mint dependencies"
2730
mint bootstrap
2831

29-
echo
30-
echo -e "👉 Create git/hooks folder if needed"
32+
puts "Create git/hooks folder if needed"
3133
mkdir -p .git/hooks
3234

3335
# Symlink hooks folder to .git/hooks folder
34-
echo
35-
echo -e "👉 Create symlink for pre-commit hooks"
36+
puts "Create symlink for pre-commit hooks"
3637
# Symlink needs to be ../../hooks and not ./hooks because git evaluates them in .git/hooks
3738
ln -sf ../../hooks/pre-commit.sh .git/hooks/pre-commit
3839
chmod +x .git/hooks/pre-commit
3940
chmod +x ./hooks/git-format-staged
4041

4142
# Install gems
42-
echo
43-
echo -e "👉 Install bundle dependencies"
43+
puts "Install bundle dependencies"
4444
bundle install
45+
46+
if [[ ${INSTALL_SONAR-default} == true ]]; then
47+
puts "Install sonar dependencies"
48+
pip install lizard
49+
brew install sonar-scanner
50+
fi

codecov.yml

-8
This file was deleted.

fastlane/Fastfile

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
default_platform :ios
22

33
require 'json'
4+
import 'Sonarfile'
45

56
# The number of times the stress test suite is ran
67
stress_tests_cycles = 50

fastlane/Pluginfile

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
gem 'fastlane-plugin-firebase_app_distribution'
66
gem 'fastlane-plugin-versioning'
77
gem 'fastlane-plugin-emerge'
8+
gem 'fastlane-plugin-sonarcloud_metric_kit'

fastlane/Scanfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
devices(["iPhone 12"])
88

9-
# Needed for codecov
9+
# Needed for Sonar
1010
code_coverage(true)
1111

1212
# Our integration tests need to run in parallel

fastlane/Sonarfile

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env ruby
2+
3+
desc 'Get code coverage report and run complexity analysis for Sonar'
4+
lane :sonar_upload do
5+
version_number = get_version_number(
6+
xcodeproj: 'StreamChatSwiftUI.xcodeproj',
7+
target: 'StreamChatSwiftUI'
8+
)[/\d+\.\d+\.\d/]
9+
10+
slather
11+
12+
lizard(
13+
source_folder: './Sources/',
14+
language: 'swift',
15+
export_type: 'xml',
16+
report_file: 'reports/lizard.xml'
17+
)
18+
19+
if ENV['GITHUB_EVENT_NAME'] == 'pull_request'
20+
sonar(
21+
sonar_login: ENV['SONAR_TOKEN'],
22+
pull_request_branch: ENV['GITHUB_HEAD_REF'],
23+
pull_request_base: ENV['GITHUB_BASE_REF'],
24+
pull_request_key: ENV['PR_NUMBER'],
25+
project_version: version_number
26+
)
27+
else
28+
branch = git_branch
29+
30+
sonar(
31+
sonar_login: ENV['SONAR_TOKEN'],
32+
branch_name: branch,
33+
project_version: version_number
34+
)
35+
36+
case branch.to_sym
37+
when :main
38+
slack_sonarcloud_metrics(new_period: version_number, branch: branch)
39+
when :develop
40+
slack_sonarcloud_metrics(branch: branch)
41+
end
42+
end
43+
end
44+
45+
desc 'Creates a report in Slack with SonarCloud analysis details'
46+
private_lane :slack_sonarcloud_metrics do |options|
47+
project_key = 'GetStream_stream-chat-swiftui'
48+
metrics = sonarcloud_metric_kit(
49+
project_key: project_key,
50+
quality_gate: true,
51+
branch: options[:branch]
52+
)
53+
new_period = options[:new_period] || options[:branch]
54+
new_coverage = metrics[:new_coverage].to_f.round(2)
55+
new_duplication_density = metrics[:new_duplicated_lines_density].to_f.round(2)
56+
vulnerabilities = metrics[:security_hotspots].to_i + metrics[:vulnerabilities].to_i
57+
new_vulnerabilities = metrics[:new_security_hotspots].to_i + metrics[:new_vulnerabilities].to_i
58+
59+
release_status = "From *#{metrics[:period_value]}* to *#{new_period}*\n _#{metrics[:new_lines_to_cover]}_ new lines of code 🚀"
60+
coverage_status = "Total: _#{metrics[:coverage]}%_\nOn new code: _#{new_coverage}%_ #{new_coverage < 80 ? '⚠️' : '✅'}"
61+
duplication_status = "Total: _#{metrics[:duplicated_lines_density]}%_\nOn new code: _#{new_duplication_density}%_ #{new_duplication_density < 3 ? '✅' : '⚠️'}"
62+
code_smells_status = "Total: _#{metrics[:code_smells]}_\nNew: _#{metrics[:new_code_smells]}_ #{metrics[:new_code_smells].to_i.positive? ? '🙊' : '✅'}"
63+
bugs_status = "Total: _#{metrics[:bugs]}_\nNew: _#{metrics[:new_bugs]}_ #{metrics[:new_bugs].to_i.positive? ? '⚠️' : '✅'}"
64+
security_status = "Total: _#{vulnerabilities}_\nNew: _#{new_vulnerabilities}_ #{new_vulnerabilities.positive? ? '⚠️' : '✅'}"
65+
66+
slack(
67+
message: "[StreamChatSwiftUI](https://sonarcloud.io/summary/new_code?id=#{project_key}&branch=#{options[:branch]})",
68+
attachment_properties: {
69+
thumb_url: 'https://pbs.twimg.com/profile_images/955394530806829056/LC7DAYM3_400x400.jpg',
70+
fields: [
71+
{ title: 'Update', value: release_status, short: true },
72+
{ title: 'Code coverage', value: coverage_status, short: true },
73+
{ title: 'Duplicated lines density', value: duplication_status, short: true },
74+
{ title: 'Code smells', value: code_smells_status, short: true },
75+
{ title: 'Bugs', value: bugs_status, short: true },
76+
{ title: 'Vulnerabilities & Security hotspots', value: security_status, short: true }
77+
]
78+
},
79+
default_payloads: [],
80+
slack_url: ENV['SLACK_WEBHOOK_URL']
81+
)
82+
end

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lizard

sonar-project.properties

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
sonar.projectKey=GetStream_stream-chat-swiftui
2+
sonar.projectName=stream-chat-swiftui
3+
sonar.host.url=https://sonarcloud.io
4+
sonar.organization=getstream
5+
sonar.sourceEncoding=UTF-8
6+
sonar.language=swift
7+
sonar.coverageReportPaths=reports/sonarqube-generic-coverage.xml
8+
sonar.swift.lizard.report=reports/lizard.xml
9+
sonar.inclusions=Sources/**/*.swift
10+
sonar.exclusions=Sources/**/*_Vendor.swift, Sources/**/Generated/*.swift
11+
12+
# Prevent C/C++/Objective-C files from being analyzed
13+
sonar.c.file.suffixes=-
14+
sonar.cpp.file.suffixes=-
15+
sonar.objc.file.suffixes=-

0 commit comments

Comments
 (0)