Skip to content

Commit d297ebc

Browse files
authored
Merge pull request #12 from Black-Cockpit/integrating_static_code_analysis
👮 Integrated sonar cloud
2 parents 400069d + 2c936bd commit d297ebc

File tree

9 files changed

+273
-46
lines changed

9 files changed

+273
-46
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Build test and analyze
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
types:
10+
- opened
11+
- reopened
12+
- edited
13+
- synchronize
14+
15+
jobs:
16+
# Build test and analyze source code
17+
build_test_analyze:
18+
runs-on: ubuntu-22.04
19+
strategy:
20+
matrix:
21+
java-version: [ 21 ]
22+
steps:
23+
- name: Checkout Repository
24+
uses: actions/checkout@v4
25+
26+
# Setup OpenJDK
27+
- name: Setup OpenJDK
28+
uses: actions/setup-java@v3
29+
with:
30+
distribution: 'adopt'
31+
java-version: ${{ matrix.java-version }}
32+
33+
# Install all required .NET SDK versions
34+
- name: Install .NET SDKs (6.0, 7.0, 8.0)
35+
uses: actions/setup-dotnet@v1
36+
with:
37+
dotnet-version: |
38+
6.0.x
39+
7.0.x
40+
8.0.x
41+
42+
# Install dependencies
43+
- name: Install dependencies
44+
run: |
45+
sudo apt install -y make python3-pip python3-rpm python3-psycopg2
46+
pip install 'python-keycloak==3.3.0' --user
47+
dotnet tool install --global dotnet-sonarscanner
48+
dotnet tool install --global Cake.Tool
49+
dotnet tool install --global JetBrains.dotCover.GlobalTool
50+
51+
# Build test and analyze the project
52+
- name: Build test and analyze the project
53+
if: success()
54+
env:
55+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
56+
run: |
57+
# Copy Licence
58+
cp LICENSE NETCore.Keycloak.Client/
59+
60+
# Build, test and analyze project with keycloak version 20
61+
cd NETCore.Keycloak.Client.Tests
62+
dotnet cake build_test_analyse.cake --kc_major_version=20 --sonar_token=${SONAR_TOKEN}

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ out
3838
**/containers/**
3939
**/Assets/*.json
4040

41+
**/NETCore.Keycloak.Client/LICENSE
42+
4143
private.pem
4244
location_db.bin
4345

@@ -99,6 +101,9 @@ project.lock.json
99101
project.fragment.lock.json
100102
artifacts/
101103

104+
# SonarQube
105+
**/.sonarqube
106+
102107
# StyleCop
103108
StyleCopReport.xml
104109

@@ -173,6 +178,7 @@ _TeamCity*
173178

174179
# DotCover is a Code Coverage Tool
175180
*.dotCover
181+
**/dotCover*
176182

177183
# AxoCover is a Code Coverage Tool
178184
.axoCover/*

NETCore.Keycloak.Client.Tests/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ install_virtual_env:
3737
fi
3838
@echo "Creating directory ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}"
3939
# Create a new virtual environment
40-
@python3.9 -m venv ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}
40+
@python3 -m venv ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}
4141
# Activate the virtual environment and install dependencies
4242
@pushd ${CONF_DIR_CONTEXT}/ && source ${VIRTUAL_ENV_DIR}/bin/activate && pip install -r requirements.txt
4343
# Install required Ansible collections

NETCore.Keycloak.Client.Tests/ansible.cfg

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ host_key_checking = False
55
executable = /bin/bash
66
allow_world_readable_tmpfiles = True
77
callbacks_enabled = profile_tasks, profile_roles
8-
stdout_callback = yaml
9-
stderr_callback = yaml
108
forks=50
119
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
1210
pipelining = True
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/// <summary>
2+
/// Main Cake build script to manage the build, restore, test, and setup of the Keycloak testing environment.
3+
/// Includes and calls tasks from external scripts.
4+
/// </summary>
5+
6+
// Load external task scripts
7+
#load "cakeScripts/check_tools.cake";
8+
#load "cakeScripts/setup_keycloak_test_environment.cake";
9+
#load "cakeScripts/sonar_analysis.cake";
10+
#load "../build.cake";
11+
12+
// Update the solution context
13+
slnContext = "..";
14+
15+
/// <summary>
16+
/// Executes unit tests using JetBrains dotCover for code coverage analysis.
17+
/// Runs the tests without rebuilding the project.
18+
/// </summary>
19+
Task("Test")
20+
.IsDependentOn("Build")
21+
.Does(() =>
22+
{
23+
Information("Running tests with dotCover...");
24+
25+
// Ensure dotnet is installed
26+
var dotnetPath = Context.Tools.Resolve("dotnet");
27+
if (dotnetPath == null)
28+
{
29+
Error("dotnet is not installed or cannot be found.");
30+
Environment.Exit(255);
31+
}
32+
33+
// Define the test command
34+
var testCommand = $"dotcover test {slnContext}/NETCore.Keycloak.sln --configuration {configuration} -l:\"console;verbosity=normal\" --no-restore --no-build --dcReportType=HTML";
35+
36+
// Configure dotCover settings
37+
var processSettings = new ProcessSettings
38+
{
39+
Arguments = new ProcessArgumentBuilder()
40+
.Append(testCommand),
41+
RedirectStandardOutput = true,
42+
RedirectStandardError = true
43+
};
44+
45+
// Run tests with dotCover
46+
var result = StartProcess(dotnetPath, processSettings, out var output, out var error);
47+
48+
// Evaluate the result of the process execution
49+
if (result != 0)
50+
{
51+
Error("Unit tests failed with dotCover. Error:\n{0}", string.Join(Environment.NewLine, error));
52+
Environment.Exit(255);
53+
}
54+
55+
Information("Unit tests executed successfully with dotCover.");
56+
});
57+
58+
59+
/// <summary>
60+
/// The BuildTestAnalyse task orchestrates the setup, testing, and analysis of the Keycloak client.
61+
/// It ensures that the environment is correctly configured, executes end-to-end tests,
62+
/// and performs SonarQube analysis while validating required parameters.
63+
/// </summary>
64+
Task("BuildTestAnalyse")
65+
.Does(() =>
66+
{
67+
Information("Executing Keycloak client build, test, and analysis...");
68+
69+
// Generate a list of supported Keycloak versions from 20 to 26
70+
var versions = Enumerable.Range(20, 26 - 20 + 1).ToList();
71+
72+
// Get the major version argument if provided
73+
var kcMajorVersion = Argument<int?>("kc_major_version", null);
74+
75+
// Validate the provided version
76+
if (!kcMajorVersion.HasValue || !versions.Contains(kcMajorVersion.Value))
77+
{
78+
Error($"Invalid Keycloak version: {kcMajorVersion}. Supported versions: {string.Join(", ", versions)}");
79+
Environment.Exit(255);
80+
}
81+
82+
// Retrieve the Sonar token from the arguments
83+
var sonarToken = Argument<string>("sonar_token", null);
84+
85+
if (string.IsNullOrWhiteSpace(sonarToken))
86+
{
87+
// Ensure the Sonar token is provided before proceeding
88+
Error("Sonar token is required.");
89+
Environment.Exit(255);
90+
}
91+
92+
// Log the processing of the specific Keycloak version
93+
Information($"Processing Keycloak Version: {kcMajorVersion.Value}");
94+
95+
// Set environment variables for Keycloak and SonarQube
96+
Environment.SetEnvironmentVariable("KC_TEST_VERSION", $"prepare_keycloak_{kcMajorVersion.Value}_environment");
97+
Environment.SetEnvironmentVariable("KC_SONAR_TOKEN", sonarToken);
98+
99+
// Execute the required setup, testing, and analysis tasks
100+
RunTarget("Setup-Testing-Environment");
101+
RunTarget("SonarBegin");
102+
RunTarget("Test");
103+
RunTarget("SonarEnd");
104+
});
105+
106+
// Execute the BuildTestAnalyse task
107+
RunTarget("BuildTestAnalyse");
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/// <summary>
2+
/// Initiates SonarCloud analysis by executing the `dotnet sonarscanner begin` command.
3+
/// This task resolves the `dotnet` executable, ensures the required Sonar token is provided,
4+
/// and configures the necessary SonarCloud parameters for project analysis.
5+
/// </summary>
6+
Task("SonarBegin")
7+
.Does(() =>
8+
{
9+
// Retrieve the Sonar token from the environment variable
10+
var sonarToken = Environment.GetEnvironmentVariable("KC_SONAR_TOKEN") ?? "";
11+
12+
if (string.IsNullOrWhiteSpace(sonarToken))
13+
{
14+
// Ensure the token is provided before proceeding
15+
Error("Sonar token is required.");
16+
Environment.Exit(255);
17+
}
18+
19+
// Resolve the path to the `dotnet` executable
20+
FilePath dotnetPath = Context.Tools.Resolve("dotnet");
21+
22+
// Configure process settings for executing the SonarScanner command
23+
var processSettings = new ProcessSettings
24+
{
25+
Arguments = new ProcessArgumentBuilder()
26+
.Append("sonarscanner begin")
27+
.Append($"/d:sonar.token={sonarToken}")
28+
.Append("/k:Black-Cockpit_NETCore.Keycloak")
29+
.Append("/o:black-cockpit")
30+
.Append("/d:sonar.host.url=\"https://sonarcloud.io\"")
31+
.Append("/d:sonar.coverage.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
32+
.Append("/d:sonar.test.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
33+
.Append("/d:sonar.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
34+
.Append("/d:sonar.cs.dotcover.reportsPaths=dotCover.Output.html"),
35+
RedirectStandardOutput = true,
36+
RedirectStandardError = true
37+
};
38+
39+
// Execute the SonarScanner command
40+
StartProcess(dotnetPath, processSettings);
41+
});
42+
43+
/// <summary>
44+
/// Finalizes the SonarCloud analysis by executing the `dotnet sonarscanner end` command.
45+
/// This task ensures the required Sonar token is provided, resolves the `dotnet` executable,
46+
/// and captures the process output and error streams for evaluation.
47+
/// </summary>
48+
Task("SonarEnd")
49+
.IsDependentOn("Build")
50+
.Does(() =>
51+
{
52+
// Retrieve the Sonar token from the environment variable
53+
var sonarToken = Environment.GetEnvironmentVariable("KC_SONAR_TOKEN") ?? "";
54+
55+
if (string.IsNullOrWhiteSpace(sonarToken))
56+
{
57+
// Ensure the token is provided before proceeding
58+
Error("Sonar token is required.");
59+
Environment.Exit(255);
60+
}
61+
62+
// Resolve the path to the `dotnet` executable
63+
FilePath dotnetPath = Context.Tools.Resolve("dotnet");
64+
65+
// Configure process settings for executing the SonarScanner command
66+
var processSettings = new ProcessSettings
67+
{
68+
Arguments = new ProcessArgumentBuilder()
69+
.Append("sonarscanner end")
70+
.Append($"/d:sonar.token={sonarToken}"),
71+
RedirectStandardOutput = true,
72+
RedirectStandardError = true
73+
};
74+
75+
// Execute the SonarScanner command and capture output/error streams
76+
var result = StartProcess(dotnetPath, processSettings, out var output, out var error);
77+
78+
// Evaluate the result of the process execution
79+
if (result != 0)
80+
{
81+
// Log the error message and exit if the command failed
82+
Error("Sonar analysis finalization failed. Error:\n{0}", string.Join(Environment.NewLine, error));
83+
Environment.Exit(255);
84+
}
85+
});
File renamed without changes.

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@
1111

1212
<div align="center">
1313

14-
[![GitHub Build Status](https://github.com/Black-Cockpit/NETCore.Keycloak/actions/workflows/build.yml/badge.svg)](https://github.com/Black-Cockpit/NETCore.Keycloak/actions/workflows/build.yml)
14+
[![GitHub Build Status](https://github.com/Black-Cockpit/NETCore.Keycloak/actions/workflows/build_test_analyze.yml/badge.svg)](https://github.com/Black-Cockpit/NETCore.Keycloak/actions/workflows/build.yml)
1515
[![NuGet version](https://img.shields.io/nuget/v/Keycloak.NETCore.Client.svg)](https://www.nuget.org/packages/Keycloak.NETCore.Client/)
1616
[![NuGet downloads](https://img.shields.io/nuget/dt/Keycloak.NETCore.Client.svg)](https://www.nuget.org/packages/Keycloak.NETCore.Client/)
1717
[![GitHub Stars](https://img.shields.io/github/stars/Black-Cockpit/NETCore.Keycloak)](https://github.com/Black-Cockpit/NETCore.Keycloak/stargazers)
1818
[![CodeFactor](https://www.codefactor.io/repository/github/black-cockpit/netcore.keycloak/badge)](https://www.codefactor.io/repository/github/black-cockpit/netcore.keycloak)
1919
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FBlack-Cockpit%2FNETCore.Keycloak.svg?type=shield&issueType=security)](https://app.fossa.com/projects/git%2Bgithub.com%2FBlack-Cockpit%2FNETCore.Keycloak?ref=badge_shield&issueType=security)
20+
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
21+
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
22+
[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
23+
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
24+
[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
25+
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
26+
[![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
27+
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
28+
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=bugs)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
29+
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
30+
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=Black-Cockpit_NETCore.Keycloak&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=Black-Cockpit_NETCore.Keycloak)
2031
[![License](https://img.shields.io/github/license/Black-Cockpit/NETCore.Keycloak)](LICENSE)
2132
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FBlack-Cockpit%2FNETCore.Keycloak.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2FBlack-Cockpit%2FNETCore.Keycloak?ref=badge_shield&issueType=license)
2233

0 commit comments

Comments
 (0)