Skip to content

Commit

Permalink
Merge pull request #12 from Black-Cockpit/integrating_static_code_ana…
Browse files Browse the repository at this point in the history
…lysis

👮 Integrated sonar cloud
  • Loading branch information
hasnimehdi91 authored Feb 16, 2025
2 parents 400069d + 2c936bd commit d297ebc
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 46 deletions.
42 changes: 0 additions & 42 deletions .github/workflows/build.yml

This file was deleted.

62 changes: 62 additions & 0 deletions .github/workflows/build_test_analyze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Build test and analyze
on:
push:
branches:
- master
pull_request:
branches:
- master
types:
- opened
- reopened
- edited
- synchronize

jobs:
# Build test and analyze source code
build_test_analyze:
runs-on: ubuntu-22.04
strategy:
matrix:
java-version: [ 21 ]
steps:
- name: Checkout Repository
uses: actions/checkout@v4

# Setup OpenJDK
- name: Setup OpenJDK
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: ${{ matrix.java-version }}

# Install all required .NET SDK versions
- name: Install .NET SDKs (6.0, 7.0, 8.0)
uses: actions/setup-dotnet@v1
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
# Install dependencies
- name: Install dependencies
run: |
sudo apt install -y make python3-pip python3-rpm python3-psycopg2
pip install 'python-keycloak==3.3.0' --user
dotnet tool install --global dotnet-sonarscanner
dotnet tool install --global Cake.Tool
dotnet tool install --global JetBrains.dotCover.GlobalTool
# Build test and analyze the project
- name: Build test and analyze the project
if: success()
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
# Copy Licence
cp LICENSE NETCore.Keycloak.Client/
# Build, test and analyze project with keycloak version 20
cd NETCore.Keycloak.Client.Tests
dotnet cake build_test_analyse.cake --kc_major_version=20 --sonar_token=${SONAR_TOKEN}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ out
**/containers/**
**/Assets/*.json

**/NETCore.Keycloak.Client/LICENSE

private.pem
location_db.bin

Expand Down Expand Up @@ -99,6 +101,9 @@ project.lock.json
project.fragment.lock.json
artifacts/

# SonarQube
**/.sonarqube

# StyleCop
StyleCopReport.xml

Expand Down Expand Up @@ -173,6 +178,7 @@ _TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover
**/dotCover*

# AxoCover is a Code Coverage Tool
.axoCover/*
Expand Down
2 changes: 1 addition & 1 deletion NETCore.Keycloak.Client.Tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ install_virtual_env:
fi
@echo "Creating directory ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}"
# Create a new virtual environment
@python3.9 -m venv ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}
@python3 -m venv ${CONF_DIR_CONTEXT}/${VIRTUAL_ENV_DIR}
# Activate the virtual environment and install dependencies
@pushd ${CONF_DIR_CONTEXT}/ && source ${VIRTUAL_ENV_DIR}/bin/activate && pip install -r requirements.txt
# Install required Ansible collections
Expand Down
2 changes: 0 additions & 2 deletions NETCore.Keycloak.Client.Tests/ansible.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ host_key_checking = False
executable = /bin/bash
allow_world_readable_tmpfiles = True
callbacks_enabled = profile_tasks, profile_roles
stdout_callback = yaml
stderr_callback = yaml
forks=50
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
Expand Down
107 changes: 107 additions & 0 deletions NETCore.Keycloak.Client.Tests/build_test_analyse.cake
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/// <summary>
/// Main Cake build script to manage the build, restore, test, and setup of the Keycloak testing environment.
/// Includes and calls tasks from external scripts.
/// </summary>

// Load external task scripts
#load "cakeScripts/check_tools.cake";
#load "cakeScripts/setup_keycloak_test_environment.cake";
#load "cakeScripts/sonar_analysis.cake";
#load "../build.cake";

// Update the solution context
slnContext = "..";

/// <summary>
/// Executes unit tests using JetBrains dotCover for code coverage analysis.
/// Runs the tests without rebuilding the project.
/// </summary>
Task("Test")
.IsDependentOn("Build")
.Does(() =>
{
Information("Running tests with dotCover...");

// Ensure dotnet is installed
var dotnetPath = Context.Tools.Resolve("dotnet");
if (dotnetPath == null)
{
Error("dotnet is not installed or cannot be found.");
Environment.Exit(255);
}

// Define the test command
var testCommand = $"dotcover test {slnContext}/NETCore.Keycloak.sln --configuration {configuration} -l:\"console;verbosity=normal\" --no-restore --no-build --dcReportType=HTML";

// Configure dotCover settings
var processSettings = new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append(testCommand),
RedirectStandardOutput = true,
RedirectStandardError = true
};

// Run tests with dotCover
var result = StartProcess(dotnetPath, processSettings, out var output, out var error);

// Evaluate the result of the process execution
if (result != 0)
{
Error("Unit tests failed with dotCover. Error:\n{0}", string.Join(Environment.NewLine, error));
Environment.Exit(255);
}

Information("Unit tests executed successfully with dotCover.");
});


/// <summary>
/// The BuildTestAnalyse task orchestrates the setup, testing, and analysis of the Keycloak client.
/// It ensures that the environment is correctly configured, executes end-to-end tests,
/// and performs SonarQube analysis while validating required parameters.
/// </summary>
Task("BuildTestAnalyse")
.Does(() =>
{
Information("Executing Keycloak client build, test, and analysis...");

// Generate a list of supported Keycloak versions from 20 to 26
var versions = Enumerable.Range(20, 26 - 20 + 1).ToList();

// Get the major version argument if provided
var kcMajorVersion = Argument<int?>("kc_major_version", null);

// Validate the provided version
if (!kcMajorVersion.HasValue || !versions.Contains(kcMajorVersion.Value))
{
Error($"Invalid Keycloak version: {kcMajorVersion}. Supported versions: {string.Join(", ", versions)}");
Environment.Exit(255);
}

// Retrieve the Sonar token from the arguments
var sonarToken = Argument<string>("sonar_token", null);

if (string.IsNullOrWhiteSpace(sonarToken))
{
// Ensure the Sonar token is provided before proceeding
Error("Sonar token is required.");
Environment.Exit(255);
}

// Log the processing of the specific Keycloak version
Information($"Processing Keycloak Version: {kcMajorVersion.Value}");

// Set environment variables for Keycloak and SonarQube
Environment.SetEnvironmentVariable("KC_TEST_VERSION", $"prepare_keycloak_{kcMajorVersion.Value}_environment");
Environment.SetEnvironmentVariable("KC_SONAR_TOKEN", sonarToken);

// Execute the required setup, testing, and analysis tasks
RunTarget("Setup-Testing-Environment");
RunTarget("SonarBegin");
RunTarget("Test");
RunTarget("SonarEnd");
});

// Execute the BuildTestAnalyse task
RunTarget("BuildTestAnalyse");
85 changes: 85 additions & 0 deletions NETCore.Keycloak.Client.Tests/cakeScripts/sonar_analysis.cake
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/// <summary>
/// Initiates SonarCloud analysis by executing the `dotnet sonarscanner begin` command.
/// This task resolves the `dotnet` executable, ensures the required Sonar token is provided,
/// and configures the necessary SonarCloud parameters for project analysis.
/// </summary>
Task("SonarBegin")
.Does(() =>
{
// Retrieve the Sonar token from the environment variable
var sonarToken = Environment.GetEnvironmentVariable("KC_SONAR_TOKEN") ?? "";

if (string.IsNullOrWhiteSpace(sonarToken))
{
// Ensure the token is provided before proceeding
Error("Sonar token is required.");
Environment.Exit(255);
}

// Resolve the path to the `dotnet` executable
FilePath dotnetPath = Context.Tools.Resolve("dotnet");

// Configure process settings for executing the SonarScanner command
var processSettings = new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append("sonarscanner begin")
.Append($"/d:sonar.token={sonarToken}")
.Append("/k:Black-Cockpit_NETCore.Keycloak")
.Append("/o:black-cockpit")
.Append("/d:sonar.host.url=\"https://sonarcloud.io\"")
.Append("/d:sonar.coverage.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
.Append("/d:sonar.test.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
.Append("/d:sonar.exclusions=\"**/NETCore.Keycloak.Client.Tests/**/*.*\"")
.Append("/d:sonar.cs.dotcover.reportsPaths=dotCover.Output.html"),
RedirectStandardOutput = true,
RedirectStandardError = true
};

// Execute the SonarScanner command
StartProcess(dotnetPath, processSettings);
});

/// <summary>
/// Finalizes the SonarCloud analysis by executing the `dotnet sonarscanner end` command.
/// This task ensures the required Sonar token is provided, resolves the `dotnet` executable,
/// and captures the process output and error streams for evaluation.
/// </summary>
Task("SonarEnd")
.IsDependentOn("Build")
.Does(() =>
{
// Retrieve the Sonar token from the environment variable
var sonarToken = Environment.GetEnvironmentVariable("KC_SONAR_TOKEN") ?? "";

if (string.IsNullOrWhiteSpace(sonarToken))
{
// Ensure the token is provided before proceeding
Error("Sonar token is required.");
Environment.Exit(255);
}

// Resolve the path to the `dotnet` executable
FilePath dotnetPath = Context.Tools.Resolve("dotnet");

// Configure process settings for executing the SonarScanner command
var processSettings = new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append("sonarscanner end")
.Append($"/d:sonar.token={sonarToken}"),
RedirectStandardOutput = true,
RedirectStandardError = true
};

// Execute the SonarScanner command and capture output/error streams
var result = StartProcess(dotnetPath, processSettings, out var output, out var error);

// Evaluate the result of the process execution
if (result != 0)
{
// Log the error message and exit if the command failed
Error("Sonar analysis finalization failed. Error:\n{0}", string.Join(Environment.NewLine, error));
Environment.Exit(255);
}
});
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@

<div align="center">

[![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)
[![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)
[![NuGet version](https://img.shields.io/nuget/v/Keycloak.NETCore.Client.svg)](https://www.nuget.org/packages/Keycloak.NETCore.Client/)
[![NuGet downloads](https://img.shields.io/nuget/dt/Keycloak.NETCore.Client.svg)](https://www.nuget.org/packages/Keycloak.NETCore.Client/)
[![GitHub Stars](https://img.shields.io/github/stars/Black-Cockpit/NETCore.Keycloak)](https://github.com/Black-Cockpit/NETCore.Keycloak/stargazers)
[![CodeFactor](https://www.codefactor.io/repository/github/black-cockpit/netcore.keycloak/badge)](https://www.codefactor.io/repository/github/black-cockpit/netcore.keycloak)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![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)
[![License](https://img.shields.io/github/license/Black-Cockpit/NETCore.Keycloak)](LICENSE)
[![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)

Expand Down

0 comments on commit d297ebc

Please sign in to comment.