From cd21e826d1e95db2cea64367c9d4e420e96a0570 Mon Sep 17 00:00:00 2001 From: ppanchen Date: Mon, 29 Sep 2025 10:18:30 +0300 Subject: [PATCH 01/11] - fixing namespace issue --- EchoTspServer/Program.cs | 249 +++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 125 deletions(-) diff --git a/EchoTspServer/Program.cs b/EchoTspServer/Program.cs index 5966c579..0f361c18 100644 --- a/EchoTspServer/Program.cs +++ b/EchoTspServer/Program.cs @@ -5,169 +5,168 @@ using System.Threading; using System.Threading.Tasks; -/// -/// This program was designed for test purposes only -/// Not for a review -/// -public class EchoServer +namespace EchoServer { - private readonly int _port; - private TcpListener _listener; - private CancellationTokenSource _cancellationTokenSource; - - - public EchoServer(int port) + public class EchoServer { - _port = port; - _cancellationTokenSource = new CancellationTokenSource(); - } + private readonly int _port; + private TcpListener _listener; + private CancellationTokenSource _cancellationTokenSource; - public async Task StartAsync() - { - _listener = new TcpListener(IPAddress.Any, _port); - _listener.Start(); - Console.WriteLine($"Server started on port {_port}."); - while (!_cancellationTokenSource.Token.IsCancellationRequested) + public EchoServer(int port) { - try - { - TcpClient client = await _listener.AcceptTcpClientAsync(); - Console.WriteLine("Client connected."); - - _ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token)); - } - catch (ObjectDisposedException) - { - // Listener has been closed - break; - } + _port = port; + _cancellationTokenSource = new CancellationTokenSource(); } - Console.WriteLine("Server shutdown."); - } - - private async Task HandleClientAsync(TcpClient client, CancellationToken token) - { - using (NetworkStream stream = client.GetStream()) + public async Task StartAsync() { - try + _listener = new TcpListener(IPAddress.Any, _port); + _listener.Start(); + Console.WriteLine($"Server started on port {_port}."); + + while (!_cancellationTokenSource.Token.IsCancellationRequested) { - byte[] buffer = new byte[8192]; - int bytesRead; + try + { + TcpClient client = await _listener.AcceptTcpClientAsync(); + Console.WriteLine("Client connected."); - while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0) + _ = Task.Run(() => HandleClientAsync(client, _cancellationTokenSource.Token)); + } + catch (ObjectDisposedException) { - // Echo back the received message - await stream.WriteAsync(buffer, 0, bytesRead, token); - Console.WriteLine($"Echoed {bytesRead} bytes to the client."); + // Listener has been closed + break; } } - catch (Exception ex) when (!(ex is OperationCanceledException)) - { - Console.WriteLine($"Error: {ex.Message}"); - } - finally + + Console.WriteLine("Server shutdown."); + } + + private async Task HandleClientAsync(TcpClient client, CancellationToken token) + { + using (NetworkStream stream = client.GetStream()) { - client.Close(); - Console.WriteLine("Client disconnected."); + try + { + byte[] buffer = new byte[8192]; + int bytesRead; + + while (!token.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, token)) > 0) + { + // Echo back the received message + await stream.WriteAsync(buffer, 0, bytesRead, token); + Console.WriteLine($"Echoed {bytesRead} bytes to the client."); + } + } + catch (Exception ex) when (!(ex is OperationCanceledException)) + { + Console.WriteLine($"Error: {ex.Message}"); + } + finally + { + client.Close(); + Console.WriteLine("Client disconnected."); + } } } - } - public void Stop() - { - _cancellationTokenSource.Cancel(); - _listener.Stop(); - _cancellationTokenSource.Dispose(); - Console.WriteLine("Server stopped."); - } - - public static async Task Main(string[] args) - { - EchoServer server = new EchoServer(5000); + public void Stop() + { + _cancellationTokenSource.Cancel(); + _listener.Stop(); + _cancellationTokenSource.Dispose(); + Console.WriteLine("Server stopped."); + } - // Start the server in a separate task - _ = Task.Run(() => server.StartAsync()); + public static async Task Main(string[] args) + { + EchoServer server = new EchoServer(5000); - string host = "127.0.0.1"; // Target IP - int port = 60000; // Target Port - int intervalMilliseconds = 5000; // Send every 3 seconds + // Start the server in a separate task + _ = Task.Run(() => server.StartAsync()); - using (var sender = new UdpTimedSender(host, port)) - { - Console.WriteLine("Press any key to stop sending..."); - sender.StartSending(intervalMilliseconds); + string host = "127.0.0.1"; // Target IP + int port = 60000; // Target Port + int intervalMilliseconds = 5000; // Send every 3 seconds - Console.WriteLine("Press 'q' to quit..."); - while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q) + using (var sender = new UdpTimedSender(host, port)) { - // Just wait until 'q' is pressed - } + Console.WriteLine("Press any key to stop sending..."); + sender.StartSending(intervalMilliseconds); - sender.StopSending(); - server.Stop(); - Console.WriteLine("Sender stopped."); + Console.WriteLine("Press 'q' to quit..."); + while (Console.ReadKey(intercept: true).Key != ConsoleKey.Q) + { + // Just wait until 'q' is pressed + } + + sender.StopSending(); + server.Stop(); + Console.WriteLine("Sender stopped."); + } } } -} -public class UdpTimedSender : IDisposable -{ - private readonly string _host; - private readonly int _port; - private readonly UdpClient _udpClient; - private Timer _timer; - - public UdpTimedSender(string host, int port) + public class UdpTimedSender : IDisposable { - _host = host; - _port = port; - _udpClient = new UdpClient(); - } + private readonly string _host; + private readonly int _port; + private readonly UdpClient _udpClient; + private Timer _timer; - public void StartSending(int intervalMilliseconds) - { - if (_timer != null) - throw new InvalidOperationException("Sender is already running."); + public UdpTimedSender(string host, int port) + { + _host = host; + _port = port; + _udpClient = new UdpClient(); + } - _timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds); - } + public void StartSending(int intervalMilliseconds) + { + if (_timer != null) + throw new InvalidOperationException("Sender is already running."); - ushort i = 0; + _timer = new Timer(SendMessageCallback, null, 0, intervalMilliseconds); + } - private void SendMessageCallback(object state) - { - try + ushort i = 0; + + private void SendMessageCallback(object state) { - //dummy data - Random rnd = new Random(); - byte[] samples = new byte[1024]; - rnd.NextBytes(samples); - i++; + try + { + //dummy data + Random rnd = new Random(); + byte[] samples = new byte[1024]; + rnd.NextBytes(samples); + i++; - byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray(); - var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port); + byte[] msg = (new byte[] { 0x04, 0x84 }).Concat(BitConverter.GetBytes(i)).Concat(samples).ToArray(); + var endpoint = new IPEndPoint(IPAddress.Parse(_host), _port); - _udpClient.Send(msg, msg.Length, endpoint); - Console.WriteLine($"Message sent to {_host}:{_port} "); + _udpClient.Send(msg, msg.Length, endpoint); + Console.WriteLine($"Message sent to {_host}:{_port} "); + } + catch (Exception ex) + { + Console.WriteLine($"Error sending message: {ex.Message}"); + } } - catch (Exception ex) + + public void StopSending() { - Console.WriteLine($"Error sending message: {ex.Message}"); + _timer?.Dispose(); + _timer = null; } - } - - public void StopSending() - { - _timer?.Dispose(); - _timer = null; - } - public void Dispose() - { - StopSending(); - _udpClient.Dispose(); + public void Dispose() + { + StopSending(); + _udpClient.Dispose(); + } } } \ No newline at end of file From 83122ddf91b6c7b98f4220ecfadb0df8e8494c0c Mon Sep 17 00:00:00 2001 From: ppanchen Date: Mon, 29 Sep 2025 10:22:07 +0300 Subject: [PATCH 02/11] - comment added --- EchoTspServer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EchoTspServer/Program.cs b/EchoTspServer/Program.cs index 0f361c18..82721a2e 100644 --- a/EchoTspServer/Program.cs +++ b/EchoTspServer/Program.cs @@ -13,7 +13,7 @@ public class EchoServer private TcpListener _listener; private CancellationTokenSource _cancellationTokenSource; - + //constuctor public EchoServer(int port) { _port = port; From 5bfdf16f273b2c4931b3c0ab3358f8167e20ac23 Mon Sep 17 00:00:00 2001 From: ppanchen Date: Mon, 6 Oct 2025 10:07:48 +0300 Subject: [PATCH 03/11] - added test coverage --- .github/workflows/sonarcloud.yml | 14 +++++++------- NetSdrClientAppTests/NetSdrClientAppTests.csproj | 6 +++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index e7840696..aca8b48d 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -70,13 +70,13 @@ jobs: run: dotnet restore NetSdrClient.sln - name: Build run: dotnet build NetSdrClient.sln -c Release --no-restore - #- name: Tests with coverage (OpenCover) - # run: | - # dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` - # /p:CollectCoverage=true ` - # /p:CoverletOutput=TestResults/coverage.xml ` - # /p:CoverletOutputFormat=opencover - # shell: pwsh + - name: Tests with coverage (OpenCover) + run: | + dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` + /p:CollectCoverage=true ` + /p:CoverletOutput=TestResults/coverage.xml ` + /p:CoverletOutputFormat=opencover + shell: pwsh # 3) END: SonarScanner - name: SonarScanner End run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" diff --git a/NetSdrClientAppTests/NetSdrClientAppTests.csproj b/NetSdrClientAppTests/NetSdrClientAppTests.csproj index 3cbc46af..457aa1e2 100644 --- a/NetSdrClientAppTests/NetSdrClientAppTests.csproj +++ b/NetSdrClientAppTests/NetSdrClientAppTests.csproj @@ -11,7 +11,11 @@ - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + From 727ac7786eec01f7e74ecff8edaa69212a6d8ba3 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Tue, 7 Oct 2025 23:40:28 +0300 Subject: [PATCH 04/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index aca8b48d..895de130 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -30,9 +30,9 @@ name: SonarCloud analysis on: push: - branches: [ "master" ] + branches: [ "main" ] pull_request: - branches: [ "master" ] + branches: [ "main" ] workflow_dispatch: permissions: @@ -56,8 +56,8 @@ jobs: dotnet tool install --global dotnet-sonarscanner echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH dotnet sonarscanner begin ` - /k:"ppanchen_NetSdrClient" ` - /o:"ppanchen" ` + /d:sonar.projectKey="LeVanchua_-" ` + /d:sonar.organization="levanchua" ` /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` /d:sonar.cs.opencover.reportsPaths="**/coverage.xml" ` /d:sonar.cpd.cs.minimumTokens=40 ` @@ -70,13 +70,13 @@ jobs: run: dotnet restore NetSdrClient.sln - name: Build run: dotnet build NetSdrClient.sln -c Release --no-restore - - name: Tests with coverage (OpenCover) - run: | - dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` - /p:CollectCoverage=true ` - /p:CoverletOutput=TestResults/coverage.xml ` - /p:CoverletOutputFormat=opencover - shell: pwsh + #- name: Tests with coverage (OpenCover) + # run: | + # dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` + # /p:CollectCoverage=true ` + # /p:CoverletOutput=TestResults/coverage.xml ` + # /p:CoverletOutputFormat=opencover + # shell: pwsh # 3) END: SonarScanner - name: SonarScanner End run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" From 90f46b71fb38e762bc2994ee1b840f10e5d5c498 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Tue, 7 Oct 2025 23:43:29 +0300 Subject: [PATCH 05/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 895de130..bc54faf5 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -56,8 +56,8 @@ jobs: dotnet tool install --global dotnet-sonarscanner echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH dotnet sonarscanner begin ` - /d:sonar.projectKey="LeVanchua_-" ` - /d:sonar.organization="levanchua" ` + /k:"LeVanchua_-" ` + /o:"levanchua" ` /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` /d:sonar.cs.opencover.reportsPaths="**/coverage.xml" ` /d:sonar.cpd.cs.minimumTokens=40 ` From 6e6eb65b302aa1f8743348118d9bc0af805f11b0 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 8 Oct 2025 00:00:36 +0300 Subject: [PATCH 06/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 108 ++++++++++++++----------------- 1 file changed, 49 insertions(+), 59 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index bc54faf5..ff0e5e7c 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,31 +1,3 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow helps you trigger a SonarCloud analysis of your code and populates -# GitHub Code Scanning alerts with the vulnerabilities found. -# Free for open source project. - -# 1. Login to SonarCloud.io using your GitHub account - -# 2. Import your project on SonarCloud -# * Add your GitHub organization first, then add your repository as a new project. -# * Please note that many languages are eligible for automatic analysis, -# which means that the analysis will start automatically without the need to set up GitHub Actions. -# * This behavior can be changed in Administration > Analysis Method. -# -# 3. Follow the SonarCloud in-product tutorial -# * a. Copy/paste the Project Key and the Organization Key into the args parameter below -# (You'll find this information in SonarCloud. Click on "Information" at the bottom left) -# -# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN -# (On SonarCloud, click on your avatar on top-right > My account > Security -# or go directly to https://sonarcloud.io/account/security/) - -# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/) -# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9) - name: SonarCloud analysis on: @@ -36,48 +8,66 @@ on: workflow_dispatch: permissions: - pull-requests: read # allows SonarCloud to decorate PRs with analysis results + contents: read + pull-requests: read # дозволяє SonarCloud додавати коментарі до PR jobs: - sonar-check: - name: Sonar Check - runs-on: windows-latest # безпечно для будь-яких .NET проектів + sonarcloud: + name: SonarCloud Analysis + runs-on: windows-latest + steps: - - uses: actions/checkout@v4 - with: { fetch-depth: 0 } + # 1️⃣ Отримуємо код репозиторію + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # потрібно для повної історії git - - uses: actions/setup-dotnet@v4 + # 2️⃣ Встановлюємо .NET SDK 8 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - # 1) BEGIN: SonarScanner for .NET + # 3️⃣ Встановлюємо SonarScanner + - name: Install SonarScanner + run: dotnet tool install --global dotnet-sonarscanner + shell: pwsh + + - name: Add dotnet tools to PATH + run: echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH + shell: pwsh + + # 4️⃣ Запуск початку аналізу Sonar - name: SonarScanner Begin + shell: pwsh run: | - dotnet tool install --global dotnet-sonarscanner - echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH dotnet sonarscanner begin ` - /k:"LeVanchua_-" ` - /o:"levanchua" ` - /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` - /d:sonar.cs.opencover.reportsPaths="**/coverage.xml" ` - /d:sonar.cpd.cs.minimumTokens=40 ` - /d:sonar.cpd.cs.minimumLines=5 ` - /d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml ` - /d:sonar.qualitygate.wait=true - shell: pwsh - # 2) BUILD & TEST - - name: Restore + /k:"LeVanchua_-" ` + /o:"levanchua" ` + /d:sonar.host.url="https://sonarcloud.io" ` + /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` + /d:sonar.cs.opencover.reportsPaths="**/TestResults/coverage.xml" ` + /d:sonar.exclusions="**/bin/**,**/obj/**,**/*.yml" ` + /d:sonar.qualitygate.wait=true + + # 5️⃣ Restore & Build + - name: Restore dependencies run: dotnet restore NetSdrClient.sln - - name: Build + + - name: Build project run: dotnet build NetSdrClient.sln -c Release --no-restore - #- name: Tests with coverage (OpenCover) - # run: | - # dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` - # /p:CollectCoverage=true ` - # /p:CoverletOutput=TestResults/coverage.xml ` - # /p:CoverletOutputFormat=opencover - # shell: pwsh - # 3) END: SonarScanner + + # 6️⃣ Тестування з покриттям (OpenCover) + - name: Run tests with coverage + shell: pwsh + run: | + dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` + /p:CollectCoverage=true ` + /p:CoverletOutputFormat=opencover ` + /p:CoverletOutput=TestResults/coverage.xml + + # 7️⃣ Завершення аналізу - name: SonarScanner End - run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" shell: pwsh + run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" From 8b24523073017483c0180285efabfc986b1b2ae5 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 8 Oct 2025 00:11:14 +0300 Subject: [PATCH 07/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 63 +++++++++++++++----------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index ff0e5e7c..58e68731 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,4 +1,4 @@ -name: SonarCloud analysis +name: SonarCloud Analysis on: push: @@ -8,66 +8,61 @@ on: workflow_dispatch: permissions: - contents: read - pull-requests: read # дозволяє SonarCloud додавати коментарі до PR + pull-requests: read jobs: - sonarcloud: - name: SonarCloud Analysis + sonar: + name: SonarCloud Scan runs-on: windows-latest - steps: - # 1️⃣ Отримуємо код репозиторію - - name: Checkout code - uses: actions/checkout@v4 + # Checkout repo + - uses: actions/checkout@v4 with: - fetch-depth: 0 # потрібно для повної історії git + fetch-depth: 0 - # 2️⃣ Встановлюємо .NET SDK 8 - - name: Setup .NET - uses: actions/setup-dotnet@v4 + # Setup .NET 8 SDK + - uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x' - # 3️⃣ Встановлюємо SonarScanner + # Install SonarScanner - name: Install SonarScanner - run: dotnet tool install --global dotnet-sonarscanner - shell: pwsh - - - name: Add dotnet tools to PATH - run: echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH + run: | + dotnet tool install --global dotnet-sonarscanner + echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH shell: pwsh - # 4️⃣ Запуск початку аналізу Sonar + # Begin SonarCloud analysis - name: SonarScanner Begin - shell: pwsh run: | dotnet sonarscanner begin ` /k:"LeVanchua_-" ` /o:"levanchua" ` - /d:sonar.host.url="https://sonarcloud.io" ` - /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` + /d:sonar.login="${{ secrets.SONAR_TOKEN }}" ` /d:sonar.cs.opencover.reportsPaths="**/TestResults/coverage.xml" ` - /d:sonar.exclusions="**/bin/**,**/obj/**,**/*.yml" ` + /d:sonar.cpd.cs.minimumTokens=40 ` + /d:sonar.cpd.cs.minimumLines=5 ` + /d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml ` /d:sonar.qualitygate.wait=true + shell: pwsh - # 5️⃣ Restore & Build - - name: Restore dependencies + # Restore & Build + - name: Restore Dependencies run: dotnet restore NetSdrClient.sln - - name: Build project + - name: Build Solution run: dotnet build NetSdrClient.sln -c Release --no-restore - # 6️⃣ Тестування з покриттям (OpenCover) - - name: Run tests with coverage - shell: pwsh + # Run tests with coverage + - name: Test with Coverage run: | dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` /p:CollectCoverage=true ` - /p:CoverletOutputFormat=opencover ` - /p:CoverletOutput=TestResults/coverage.xml + /p:CoverletOutput=TestResults/coverage.xml ` + /p:CoverletOutputFormat=opencover + shell: pwsh - # 7️⃣ Завершення аналізу + # End SonarCloud analysis - name: SonarScanner End + run: dotnet sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" shell: pwsh - run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" From 6514db4eb8bb9b6649bc5714341748ca0e456e67 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 8 Oct 2025 00:16:20 +0300 Subject: [PATCH 08/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 101 +++++++++++++++---------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 58e68731..7449c7bb 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,68 +1,63 @@ -name: SonarCloud Analysis +name: SonarCloud .NET 8 Analysis on: push: - branches: [ "main" ] + branches: + - main pull_request: - branches: [ "main" ] - workflow_dispatch: - -permissions: - pull-requests: read + types: [opened, synchronize, reopened] jobs: - sonar: - name: SonarCloud Scan - runs-on: windows-latest + build-and-analyze: + runs-on: ubuntu-latest steps: - # Checkout repo - - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - name: Checkout repository + uses: actions/checkout@v4 - # Setup .NET 8 SDK - - uses: actions/setup-dotnet@v4 + - name: Setup .NET 8 + uses: actions/setup-dotnet@v3 with: - dotnet-version: '8.0.x' + dotnet-version: 8.0.x - # Install SonarScanner - - name: Install SonarScanner - run: | - dotnet tool install --global dotnet-sonarscanner - echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH - shell: pwsh + - name: Install SonarScanner for .NET + run: dotnet tool install --global dotnet-sonarscanner - # Begin SonarCloud analysis - - name: SonarScanner Begin - run: | - dotnet sonarscanner begin ` - /k:"LeVanchua_-" ` - /o:"levanchua" ` - /d:sonar.login="${{ secrets.SONAR_TOKEN }}" ` - /d:sonar.cs.opencover.reportsPaths="**/TestResults/coverage.xml" ` - /d:sonar.cpd.cs.minimumTokens=40 ` - /d:sonar.cpd.cs.minimumLines=5 ` - /d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml ` - /d:sonar.qualitygate.wait=true - shell: pwsh + - name: Restore dependencies + run: dotnet restore - # Restore & Build - - name: Restore Dependencies - run: dotnet restore NetSdrClient.sln + - name: Build solution + run: dotnet build NetSdrClientApp.sln --no-restore --configuration Release - - name: Build Solution - run: dotnet build NetSdrClient.sln -c Release --no-restore - - # Run tests with coverage - - name: Test with Coverage + - name: Begin SonarCloud analysis + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + dotnet sonarscanner begin \ + /k:"LeVanchua_-" \ + /o:"" \ + /d:sonar.login="${SONAR_TOKEN}" \ + /d:sonar.projectBaseDir="${{ github.workspace }}" \ + /d:sonar.verbose=true \ + /d:sonar.cs.opencover.reportsPaths="**/TestResults/*/coverage.opencover.xml" + + - name: Run tests with coverage run: | - dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` - /p:CollectCoverage=true ` - /p:CoverletOutput=TestResults/coverage.xml ` - /p:CoverletOutputFormat=opencover - shell: pwsh + dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj \ + --no-build \ + --verbosity normal \ + --collect:"XPlat Code Coverage" \ + --results-directory TestResults || echo "No tests found, skipping" - # End SonarCloud analysis - - name: SonarScanner End - run: dotnet sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" - shell: pwsh + - name: Convert coverage to opencover (if exists) + run: | + COVERAGE_FILE=$(find TestResults -name 'coverage.cobertura.xml' | head -n 1) + if [ -f "$COVERAGE_FILE" ]; then + echo "Coverage file found: $COVERAGE_FILE" + else + echo "No coverage file found, skipping" + fi + + - name: End SonarCloud analysis + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: dotnet sonarscanner end /d:sonar.login="${SONAR_TOKEN}" From f0afb411d01be5e5c245379da77a8c8edd5811f9 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 8 Oct 2025 00:21:42 +0300 Subject: [PATCH 09/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 86 +++++++++++++------------------- 1 file changed, 34 insertions(+), 52 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 7449c7bb..789ecc11 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,4 +1,4 @@ -name: SonarCloud .NET 8 Analysis +name: .NET + SonarCloud on: push: @@ -8,56 +8,38 @@ on: types: [opened, synchronize, reopened] jobs: - build-and-analyze: + build: runs-on: ubuntu-latest + steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup .NET 8 - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.0.x - - - name: Install SonarScanner for .NET - run: dotnet tool install --global dotnet-sonarscanner - - - name: Restore dependencies - run: dotnet restore - - - name: Build solution - run: dotnet build NetSdrClientApp.sln --no-restore --configuration Release - - - name: Begin SonarCloud analysis - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - dotnet sonarscanner begin \ - /k:"LeVanchua_-" \ - /o:"" \ - /d:sonar.login="${SONAR_TOKEN}" \ - /d:sonar.projectBaseDir="${{ github.workspace }}" \ - /d:sonar.verbose=true \ - /d:sonar.cs.opencover.reportsPaths="**/TestResults/*/coverage.opencover.xml" - - - name: Run tests with coverage - run: | - dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj \ - --no-build \ - --verbosity normal \ - --collect:"XPlat Code Coverage" \ - --results-directory TestResults || echo "No tests found, skipping" - - - name: Convert coverage to opencover (if exists) - run: | - COVERAGE_FILE=$(find TestResults -name 'coverage.cobertura.xml' | head -n 1) - if [ -f "$COVERAGE_FILE" ]; then - echo "Coverage file found: $COVERAGE_FILE" - else - echo "No coverage file found, skipping" - fi - - - name: End SonarCloud analysis - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: dotnet sonarscanner end /d:sonar.login="${SONAR_TOKEN}" + - uses: actions/checkout@v3 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Install dependencies + run: dotnet restore + + - name: Run tests and collect coverage + run: | + dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj \ + /p:CollectCoverage=true \ + /p:CoverletOutputFormat=opencover \ + /p:CoverletOutput=coverage.opencover.xml + + - name: Begin SonarCloud Analysis + run: | + dotnet sonarscanner begin \ + /k:"LeVanchua_-" \ + /o:"levanchua" \ + /d:sonar.login="${{ secrets.SONAR_TOKEN }}" \ + /d:sonar.projectBaseDir="./NetSdrClientApp" \ + /d:sonar.cs.opencover.reportsPaths="coverage.opencover.xml" + + - name: Build + run: dotnet build NetSdrClientApp/NetSdrClientApp.csproj --no-restore + + - name: End SonarCloud Analysis + run: dotnet sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" From e70f1d944a846b92947d20d21dff9933df105109 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 8 Oct 2025 10:47:03 +0300 Subject: [PATCH 10/11] Update sonarcloud.yml --- .github/workflows/sonarcloud.yml | 114 ++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 38 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 789ecc11..bc54faf5 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -1,45 +1,83 @@ -name: .NET + SonarCloud +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# This workflow helps you trigger a SonarCloud analysis of your code and populates +# GitHub Code Scanning alerts with the vulnerabilities found. +# Free for open source project. + +# 1. Login to SonarCloud.io using your GitHub account + +# 2. Import your project on SonarCloud +# * Add your GitHub organization first, then add your repository as a new project. +# * Please note that many languages are eligible for automatic analysis, +# which means that the analysis will start automatically without the need to set up GitHub Actions. +# * This behavior can be changed in Administration > Analysis Method. +# +# 3. Follow the SonarCloud in-product tutorial +# * a. Copy/paste the Project Key and the Organization Key into the args parameter below +# (You'll find this information in SonarCloud. Click on "Information" at the bottom left) +# +# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN +# (On SonarCloud, click on your avatar on top-right > My account > Security +# or go directly to https://sonarcloud.io/account/security/) + +# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/) +# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9) + +name: SonarCloud analysis on: push: - branches: - - main + branches: [ "main" ] pull_request: - types: [opened, synchronize, reopened] + branches: [ "main" ] + workflow_dispatch: -jobs: - build: - runs-on: ubuntu-latest +permissions: + pull-requests: read # allows SonarCloud to decorate PRs with analysis results +jobs: + sonar-check: + name: Sonar Check + runs-on: windows-latest # безпечно для будь-яких .NET проектів steps: - - uses: actions/checkout@v3 - - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: 8.0.x - - - name: Install dependencies - run: dotnet restore - - - name: Run tests and collect coverage - run: | - dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj \ - /p:CollectCoverage=true \ - /p:CoverletOutputFormat=opencover \ - /p:CoverletOutput=coverage.opencover.xml - - - name: Begin SonarCloud Analysis - run: | - dotnet sonarscanner begin \ - /k:"LeVanchua_-" \ - /o:"levanchua" \ - /d:sonar.login="${{ secrets.SONAR_TOKEN }}" \ - /d:sonar.projectBaseDir="./NetSdrClientApp" \ - /d:sonar.cs.opencover.reportsPaths="coverage.opencover.xml" - - - name: Build - run: dotnet build NetSdrClientApp/NetSdrClientApp.csproj --no-restore - - - name: End SonarCloud Analysis - run: dotnet sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" + - uses: actions/checkout@v4 + with: { fetch-depth: 0 } + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' + + # 1) BEGIN: SonarScanner for .NET + - name: SonarScanner Begin + run: | + dotnet tool install --global dotnet-sonarscanner + echo "$env:USERPROFILE\.dotnet\tools" >> $env:GITHUB_PATH + dotnet sonarscanner begin ` + /k:"LeVanchua_-" ` + /o:"levanchua" ` + /d:sonar.token="${{ secrets.SONAR_TOKEN }}" ` + /d:sonar.cs.opencover.reportsPaths="**/coverage.xml" ` + /d:sonar.cpd.cs.minimumTokens=40 ` + /d:sonar.cpd.cs.minimumLines=5 ` + /d:sonar.exclusions=**/bin/**,**/obj/**,**/sonarcloud.yml ` + /d:sonar.qualitygate.wait=true + shell: pwsh + # 2) BUILD & TEST + - name: Restore + run: dotnet restore NetSdrClient.sln + - name: Build + run: dotnet build NetSdrClient.sln -c Release --no-restore + #- name: Tests with coverage (OpenCover) + # run: | + # dotnet test NetSdrClientAppTests/NetSdrClientAppTests.csproj -c Release --no-build ` + # /p:CollectCoverage=true ` + # /p:CoverletOutput=TestResults/coverage.xml ` + # /p:CoverletOutputFormat=opencover + # shell: pwsh + # 3) END: SonarScanner + - name: SonarScanner End + run: dotnet sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" + shell: pwsh From c984ba8a13c2687eb62fe5337405d2166827b721 Mon Sep 17 00:00:00 2001 From: LeVanchua Date: Wed, 29 Oct 2025 19:35:54 +0200 Subject: [PATCH 11/11] Update README.md --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0eb9d3b4..b60175bb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ # Лабораторні з реінжинірингу (8×) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=coverage)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=bugs)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) -[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=ppanchen_NetSdrClient&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=ppanchen_NetSdrClient) - +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=bugs)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=coverage)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=LeVanchua_-&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=LeVanchua_-) Цей репозиторій використовується для курсу **реінжиніринг ПЗ**. Мета — провести комплексний реінжиніринг спадкового коду NetSdrClient, включаючи рефакторинг архітектури, покращення якості коду, впровадження сучасних практик розробки та автоматизацію процесів контролю якості через CI/CD пайплайни.