diff --git a/.github/actions/perform-static-analysis/action.yaml b/.github/actions/perform-static-analysis/action.yaml index 86a8a20..9e9dd68 100644 --- a/.github/actions/perform-static-analysis/action.yaml +++ b/.github/actions/perform-static-analysis/action.yaml @@ -44,14 +44,12 @@ runs: run: | mkdir -p .sonar/scanner dotnet tool install dotnet-sonarscanner --tool-path ./.sonar/scanner - dotnet tool install dotnet-coverage --tool-path ./.sonar/scanner + dotnet tool install dotnet-reportgenerator-globaltool --tool-path ./.sonar/scanner + - name: Build and analyze shell: bash run: | - echo "${{ inputs.sonar_project_key }}" - echo "${{ inputs.sonar_organisation_key }}" - echo "${{ inputs.sonar_token }}" - ./.sonar/scanner/dotnet-sonarscanner begin /k:"${{ inputs.sonar_project_key }}" /o:"${{ inputs.sonar_organisation_key }}" /d:sonar.token="${{ inputs.sonar_token }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths="coverage.xml" /d:sonar.typescript.lcov.reportsPaths="src/web/coverage/lcov.info" /d:sonar.lang.patterns.ts=**/*.ts,**/*.tsx,**/*.cts,**/*.mts /d:sonar.lang.patterns.js=**/*.js,**/*.jsx,**/*.cjs,**/*.mjs,**/*.vue /d:sonar.javascript.enabled=false - dotnet build src/ServiceLayer.sln - ./.sonar/scanner/dotnet-coverage collect -f xml -o coverage.xml dotnet test src/ServiceLayer.sln - ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${{ inputs.sonar_token }}" + export SONAR_PROJECT_KEY="${{ inputs.sonar_project_key }}" + export SONAR_ORGANISATION_KEY="${{ inputs.sonar_organisation_key }}" + export SONAR_TOKEN="${{ inputs.sonar_token }}" + make test-coverage diff --git a/.github/workflows/stage-2-test.yaml b/.github/workflows/stage-2-test.yaml index e771596..07d3095 100644 --- a/.github/workflows/stage-2-test.yaml +++ b/.github/workflows/stage-2-test.yaml @@ -65,20 +65,6 @@ jobs: - name: "Save the linting result" run: | echo "Nothing to save" - test-coverage: - name: "Test coverage" - needs: [test-unit] - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: "Checkout code" - uses: actions/checkout@v4 - - name: "Run test coverage check" - run: | - make test-coverage - - name: "Save the coverage check result" - run: | - echo "Nothing to save" perform-static-analysis: name: "Perform static analysis" needs: [test-unit] diff --git a/.gitignore b/.gitignore index 3de328c..988da95 100644 --- a/.gitignore +++ b/.gitignore @@ -288,3 +288,7 @@ __queuestorage__ # Gitleaks report gitleaks-report.json + +coverage/ +.sonar/ +.sonarqube/ diff --git a/scripts/tests/coverage.sh b/scripts/tests/coverage.sh new file mode 100755 index 0000000..e505131 --- /dev/null +++ b/scripts/tests/coverage.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -euo pipefail + +: "${SONAR_TOKEN:?SONAR_TOKEN is required}" +: "${SONAR_PROJECT_KEY:?SONAR_PROJECT_KEY is required}" +: "${SONAR_ORGANISATION_KEY:?SONAR_ORGANISATION_KEY is required}" + +SONAR_SCANNER="./.sonar/scanner/dotnet-sonarscanner" +REPORT_GENERATOR="./.sonar/scanner/reportgenerator" + + + +$SONAR_SCANNER begin /k:"$SONAR_PROJECT_KEY" /o:"$SONAR_ORGANISATION_KEY" /d:sonar.token="$SONAR_TOKEN" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.coverageReportPaths="coverage/converted/SonarQube.xml" + +dotnet build src/ServiceLayer.sln + +make test-unit ARGS="--no-build" + +$REPORT_GENERATOR \ + -reports:coverage/**/coverage.cobertura.xml \ + -targetdir:coverage/converted \ + -reporttypes:SonarQube + +$SONAR_SCANNER end /d:sonar.token="$SONAR_TOKEN" diff --git a/scripts/tests/test.mk b/scripts/tests/test.mk index aab47c6..6c0ed9c 100644 --- a/scripts/tests/test.mk +++ b/scripts/tests/test.mk @@ -65,12 +65,12 @@ test: # Run all the test tasks @Testing test-load _test: - set -e - script="./scripts/tests/${name}.sh" - if [ -e "$${script}" ]; then - exec $${script} - else - echo "make test-${name} not implemented: $${script} not found" >&2 + @set -e; \ + script="./scripts/tests/$(name).sh"; \ + if [ -e "$$script" ]; then \ + exec "$$script"; \ + else \ + echo "make test-$(name) not implemented: $$script not found" >&2; \ fi ${VERBOSE}.SILENT: \ diff --git a/scripts/tests/unit.sh b/scripts/tests/unit.sh index f116215..2696f20 100755 --- a/scripts/tests/unit.sh +++ b/scripts/tests/unit.sh @@ -1,29 +1,23 @@ #!/bin/bash - set -euo pipefail -cd "$(git rev-parse --show-toplevel)" - -dir="$PWD" -UnitDir="$dir/tests/" -ResDir="$UnitDir"results-unit -Format="trx" - -# Find all *.csproj files excluding the IntegrationTests folder and execute dotnet test, with build for now -find "$UnitDir" -name '*.csproj' -not -path "$UnitDir/IntegrationTests/*" | while read -r file; do - echo -e "\nRunning unit tests for:\n$file" - dotnet test "$file" --filter "TestCategory!=Integration" --logger $Format --verbosity quiet -done - - -# Move all trx result files into a separate folder, for easier reporting -mkdir -p "$ResDir" -find "$UnitDir" -name "*.$Format" -not -path "$ResDir/*" | while read -r resfile; do - mv "$resfile" "$ResDir" +BUILD_ARGS="" +if [[ "${1:-}" == "--no-build" ]]; then + BUILD_ARGS="--no-build" +fi + +COVERAGE_DIR="coverage" +TEST_PROJECTS=$(find tests -name '*.csproj') + +rm -rf "$COVERAGE_DIR" +mkdir -p "$COVERAGE_DIR" + +for proj in $TEST_PROJECTS; do + proj_name=$(basename "$proj" .csproj) + out_file="$COVERAGE_DIR/$proj_name.coverage.xml" + echo "🧪 Running coverage for $proj -> $out_file" + dotnet test "$proj" \ + $BUILD_ARGS \ + --collect:"XPlat Code Coverage" \ + --results-directory coverage done - -# List created results -echo -e "\nCreated result files:\n" -find "$ResDir" -name "*.$Format" - -# echo "Test execution completed. See scripts/tests/unit.sh for more."