diff --git a/.github/workflows/codacy.yml b/.github/workflows/codacy.yml index 10523ba..faa8443 100644 --- a/.github/workflows/codacy.yml +++ b/.github/workflows/codacy.yml @@ -1,5 +1,4 @@ - -name: Codacy Bootstrap Issues +name: Sync Codacy Issues on: workflow_dispatch: @@ -100,3 +99,71 @@ jobs: await new Promise(resolve => setTimeout(resolve, 2000)); } } + + - name: Close Resolved GitHub Issues + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const dryRun = "${{ github.event.inputs.dry_run }}" === "true"; + const rawIssues = JSON.parse(fs.readFileSync('filtered_issues.json', 'utf8')); + + // Build current Codacy set (only *active* issues, not ignored) + const currentCodacyIds = new Set( + rawIssues.filter(i => !i.ignored).map(i => i.issueId) + ); + + // Build ignored Codacy set + const ignoredCodacyIds = new Set( + rawIssues.filter(i => i.ignored).map(i => i.issueId) + ); + + // Fetch ALL GitHub issues with codacy label + const allIssues = await github.paginate( + github.rest.issues.listForRepo, + { + owner: context.repo.owner, + repo: context.repo.repo, + state: "all", + labels: ["codacy"] + } + ); + + for (const ghIssue of allIssues) { + const matches = ghIssue.body?.match(/codacy-issue-([a-f0-9]+)/g); + if (!matches) continue; + + for (const match of matches) { + const issueId = match.replace("codacy-issue-", ""); + + // Close if not active OR explicitly ignored + if ((!currentCodacyIds.has(issueId) || ignoredCodacyIds.has(issueId)) + && ghIssue.state === "open") { + if (dryRun) { + console.log(`[DRY RUN] Would close issue #${ghIssue.number} (Codacy issueId ${issueId})`); + } else { + // Add comment before closing + const reason = ignoredCodacyIds.has(issueId) + ? "Auto closed because Codacy issue is marked as *ignored*" + : "Auto closed as not found in last analysis"; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ghIssue.number, + body: reason + }); + + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ghIssue.number, + state: "closed" + }); + console.log(`❌ Closed GitHub issue #${ghIssue.number} for Codacy issueId ${issueId}`); + } + } + } + } + + \ No newline at end of file diff --git a/.github/workflows/nightlybuild.yml b/.github/workflows/nightlybuild.yml index 7e5b834..ab0612c 100644 --- a/.github/workflows/nightlybuild.yml +++ b/.github/workflows/nightlybuild.yml @@ -39,11 +39,19 @@ jobs: dotnet test "TransactionProcessor.Tests\TransactionProcessor.Tests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov4.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" dotnet test "TransactionProcessor.DatabaseTests\TransactionProcessor.DatabaseTests.csproj" /p:CollectCoverage=true /p:Exclude="[xunit*]*" /p:ExcludeByAttribute="Obsolete" /p:ExcludeByAttribute="GeneratedCodeAttribute" /p:ExcludeByAttribute="CompilerGeneratedAttribute" /p:ExcludeByAttribute="ExcludeFromCodeCoverageAttribute" /p:CoverletOutput="../lcov5.info" /maxcpucount:1 /p:CoverletOutputFormat="lcov" - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 + - name: Install LCOV merger + run: npm install -g lcov-result-merger + + - name: Merge LCOV reports + run: | + mkdir -p coverage + lcov-result-merger "*.info" > lcov.info + + - name: Upload merged coverage to Codacy + uses: codacy/codacy-coverage-reporter-action@v1 with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./lcov1.info,./lcov2.info,./lcov3.info,./lcov4.info,./lcov5.info + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: ./lcov.info - name: Build Docker Image run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest @@ -51,19 +59,6 @@ jobs: - name: Run Integration Tests run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --logger "trx;LogFileName=test-results.trx" - - name: Extract Failed Tests (PowerShell) - if: ${{ failure() }} - run: | - $xml = [xml](Get-Content /home/runner/work/TransactionProcessor/TransactionProcessor/TransactionProcessor.IntegrationTests/test-results.trx) - $failedTests = $xml.TestRun.Results.UnitTestResult | Where-Object { $_.outcome -eq "Failed" } - if ($failedTests) { - Write-Host "::error::Failed Tests:" - foreach ($test in $failedTests) { - Write-Host "::error::- $($test.testName)" - } - } - shell: pwsh - - uses: actions/upload-artifact@v4.4.0 if: ${{ failure() }} with: