diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 023d43f..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Build & Test 🧪 - -on: - push: - branches: [ main ] - pull_request: - workflow_dispatch: - -env: - DOTNET_VERSION: "9.x" - -jobs: - - build_and_test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Cache NuGet 🗂️ - uses: actions/cache@v4 - with: - path: ~/.nuget/packages - key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} - restore-keys: | - ${{ runner.os }}-nuget- - - - name: Setup .NET 📦 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - - name: Restore dependencies 📂 - run: dotnet restore CleanArchitecture.sln - - - name: Build solution 🧱 - run: dotnet build CleanArchitecture.sln --configuration Release --no-restore -warnaserror - - - name: Run all tests 🧪 - run: dotnet test CleanArchitecture.sln --configuration Release --no-build --logger "trx;LogFileName=test-results.trx" --results-directory TestResults - - - name: Install trx2junit tool 📦 - run: dotnet tool install --global trx2junit - - - name: Convert TRX → JUnit XML 📜 - run: $HOME/.dotnet/tools/trx2junit --output TestResults TestResults/*.trx - - - name: Publish JUnit Test Report 📊 - uses: mikepenz/action-junit-report@v2 - with: - report_paths: TestResults/test-results.xml - fail_on_failure: true - - - name: Upload Test Artifacts 📁 - uses: actions/upload-artifact@v4 - with: - name: test-results - path: TestResults/test-results.xml - - publish: - runs-on: ubuntu-latest - needs: build_and_test - if: github.event_name == 'workflow_dispatch' - - steps: - - uses: actions/checkout@v4 - - - name: Setup .NET 📦 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: ${{ env.DOTNET_VERSION }} - - - name: Publish 🚀 - run: dotnet publish CleanArchitecture.sln --configuration Release --output ./published --no-build - - - name: Upload published artifacts 📁 - uses: actions/upload-artifact@v4 - with: - name: published-app - path: published diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..05e48ca --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,156 @@ +name: Build and Test with Coverage 🧱🧪 + +on: + pull_request: + branches: + - main + +permissions: + contents: read + checks: write + pull-requests: write + +env: + DOTNET_VERSION: "9.x" + +jobs: + # ---------------------- + # 🔹 JOB BUILD + # ---------------------- + build: + name: Build Solution 🧱 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Restore dependencies + run: dotnet restore CleanArchitecture.sln + + - name: Build solution + run: dotnet build CleanArchitecture.sln --configuration Release --no-restore -v:detailed + + # ---------------------- + # 🔹 JOB TEST + # ---------------------- + test: + name: Run Tests & Coverage 🧪📊 + runs-on: ubuntu-latest + needs: build # dépend du build pour la séquence, mais reste dans un job séparé + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Restore dependencies + run: dotnet restore CleanArchitecture.sln + + - name: Build solution for tests + run: dotnet build CleanArchitecture.sln --configuration Release --no-restore + + - name: Run all tests with coverage + run: | + mkdir -p tests-results + dotnet test CleanArchitecture.sln \ + --logger "trx;LogFileName=test-results.trx" \ + --collect:"XPlat Code Coverage" \ + --results-directory ./tests-results \ + -v:detailed + continue-on-error: true + + - name: Publish test results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: tests-results/test-results.trx + + - name: Install xmllint + run: sudo apt-get update && sudo apt-get install -y libxml2-utils + + - name: Extract code coverage % + id: coverage_output + if: always() + run: | + coverage_file=$(find tests-results -name 'coverage.cobertura.xml' | head -n 1) + + if [ -z "$coverage_file" ]; then + echo "percentage=0" >> $GITHUB_OUTPUT + echo "❌ Aucun fichier de couverture trouvé." + exit 0 + fi + + coverage=$(xmllint --xpath "string(/coverage/@line-rate)" "$coverage_file") + percentage=$(awk "BEGIN { printf \"%.2f\", $coverage * 100 }") + echo "📊 **Couverture du code : $percentage%**" + echo "percentage=$percentage" >> $GITHUB_OUTPUT + + - name: Publish coverage as check + uses: actions/github-script@v7 + if: always() + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const percentage = "${{ steps.coverage_output.outputs.percentage }}"; + const sha = context.payload.pull_request + ? context.payload.pull_request.head.sha + : context.sha; + + await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: "Code Coverage", + head_sha: sha, + status: "completed", + conclusion: "neutral", + output: { + title: "Code Coverage Result", + summary: `Coverage: **${percentage}%**` + } + }); + + - name: Comment coverage on PR + if: always() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const percentage = "${{ steps.coverage_output.outputs.percentage }}"; + const pr = context.payload.pull_request?.number; + if (!pr) return; + + const body = `📊 **Code Coverage:** ${percentage}%`; + + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr, + }); + + const botComment = comments.data.find(c => + c.body?.includes("📊 **Code Coverage:**") + ); + + if (botComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr, + body, + }); + } diff --git a/CleanArchitecture.sln b/CleanArchitecture.sln index d4afea9..7ac797f 100644 --- a/CleanArchitecture.sln +++ b/CleanArchitecture.sln @@ -6,8 +6,8 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8FC526EA-218B-4615-8410-4E1850611F38}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig - .github\workflows\build.yml = .github\workflows\build.yml .github\dependabot.yml = .github\dependabot.yml + .github\workflows\ci.yml = .github\workflows\ci.yml Directory.Build.props = Directory.Build.props Directory.Packages.props = Directory.Packages.props EndProjectSection diff --git a/tests/FunctionalTests/Api.FunctionalTests/Api.FunctionalTests.csproj b/tests/FunctionalTests/Api.FunctionalTests/Api.FunctionalTests.csproj index 2559528..40e1b36 100644 --- a/tests/FunctionalTests/Api.FunctionalTests/Api.FunctionalTests.csproj +++ b/tests/FunctionalTests/Api.FunctionalTests/Api.FunctionalTests.csproj @@ -7,6 +7,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive +