GuilhermeStracini/POC-GHActions-CI-NetFramework

View on GitHub
.github/workflows/build-bump-version.yml

Summary

Maintainability
Test Coverage
name: Build & Bump Version

on:
  push:
    branches:
      - '*'
      - '*/*'
      - '**'
      - '!main'
    paths-ignore:
      - "**/Properties/AssemblyInfo.cs"
      - "**/Properties/Version.txt"
  workflow_dispatch:

concurrency:
  group: bump-version
  cancel-in-progress: true

env:
  GHA_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"

jobs:
  updateVersion:
    name: Build & Patch
    runs-on: windows-latest
    permissions:
      pull-requests: write

    steps:

      - name: Generate a token
        id: generate_token
        uses: tibdex/github-app-token@v2.1.0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}

      - name: Update PR with comment (build started)
        uses: mshick/add-pr-comment@v2
        with:
          repo-token: ${{ steps.generate_token.outputs.token }}
          refresh-message-position: true
          message-id: 'begin'
          message: |
            **Build debug & Version bump:** :beginner: [Build started](${{ env.GHA_URL }})

      - name: Generate check
        uses: LouisBrunner/checks-action@v2.0.0
        id: generate_check
        if: always()
        with:
          token: ${{ steps.generate_token.outputs.token }}
          name: 'Build & Bump Version'
          status: 'in_progress'

      - name: Checkout code
        uses: actions/checkout@v4
        with:
          token: ${{ steps.generate_token.outputs.token }}
          ref: ${{ github.event.pull_request.head.ref }}

      - name: Check for changes in Src or .github/workflows directory
        uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            src:
              - "Src/**"
              - ".github/workflows/**"

      - name: Set solution name
        run: |
          echo "solution=$([io.path]::GetFileNameWithoutExtension($(Get-ChildItem -Path .\* -Include *.sln)))" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "projectPath=$((Get-ChildItem -Path .\Src\ -Directory | Select-Object -First 1).Name)" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "sonar_key=$("${{ github.repository }}" -replace "/","_")" | Out-File -FilePath $env:GITHUB_ENV -Append

      - name: Update PR with comment (build started solution)
        uses: mshick/add-pr-comment@v2
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          repo-token: ${{ steps.generate_token.outputs.token }}
          refresh-message-position: true
          message-id: 'begin'
          message: |
            **Build debug & Version bump:** :beginner: [Building ${{ env.solution }}.sln](${{ env.GHA_URL }})

      - name: Update PR with comment (build started solution)
        uses: mshick/add-pr-comment@v2
        if: steps.changes.outputs.src == 'false'
        with:
          repo-token: ${{ steps.generate_token.outputs.token }}
          refresh-message-position: true
          message-id: 'begin'
          message: |
            **Build debug & Version bump:** :alien: [Not building ${{ env.solution }}.sln](${{ env.GHA_URL }}), no source files changed.

      - name: Set up Java
        uses: actions/setup-java@v4
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          distribution: 'temurin'
          java-version: 21

      - name: Cache SonarCloud packages
        uses: actions/cache@v4
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          path: ~\sonar\cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar

      - name: Cache SonarCloud scanner
        id: cache-sonar-scanner
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        uses: actions/cache@v4
        with:
          path: .\.sonar\scanner
          key: ${{ runner.os }}-sonar-scanner
          restore-keys: ${{ runner.os }}-sonar-scanner

      - name: Install SonarCloud scanner
        if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
        shell: powershell
        run: |
          New-Item -Path .\.sonar\scanner -ItemType Directory
          dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner

      - name: Add MSBuild to PATH
        uses: microsoft/setup-msbuild@v2
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          msbuild-architecture: x64
        env:
          ACTIONS_ALLOW_UNSECURE_COMMANDS: true

      - name: Setup Nuget
        uses: nuget/setup-nuget@v2
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        env:
          ACTIONS_ALLOW_UNSECURE_COMMANDS: true

      - name: Setup VSTest
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        uses: darenm/Setup-VSTest@v1.3

      - name: DotNet Tool Install Coverlet
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: dotnet tool install --global coverlet.console

      - name: Restore NuGet packages
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: nuget restore "${{ env.solution }}.sln"

      - name: Build & Test
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        env:
          DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
          TERM: xterm
        run: |
          .\.sonar\scanner\dotnet-sonarscanner begin /k:"${{ env.sonar_key }}" /o:"$("${{ github.repository_owner }}".ToLower())" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.vscoveragexml.reportsPaths="Tests\${{ env.solution }}.UnitTests\coverage.cobertura.xml"
          msbuild "${{ env.solution }}.sln" /p:Configuration=Debug -verbosity:detailed -flp1:"logfile=msbuild.errors.log;errorsonly" -flp2:"logfile=msbuild.warnings.log;warningsonly"
          coverlet "Tests\${{ env.solution }}.UnitTests\bin\Debug\${{ env.solution }}.UnitTests.dll" -t "vstest.console.exe" -a "Tests\${{ env.solution }}.UnitTests\bin\Debug\${{ env.solution }}.UnitTests.dll" -o "Tests\${{ env.solution }}.UnitTests\\" -f cobertura
          .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
      
      - name: Install DeepSource scanner
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: |
          curl -L https://github.com/DeepSourceCorp/cli/releases/download/v0.8.6/deepsource_0.8.6_windows_x86_64.tar.gz > deepsource.tar.gz
          tar -xzf deepsource.tar.gz

      - name: Analyze before commit
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        env:
          DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
        run: .\deepsource report --analyzer test-coverage --key csharp --value-file "Tests\${{ env.solution }}.UnitTests\coverage.cobertura.xml"
      
      - name: Set version from a file
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: |
          echo "version=$(type Src/${{ env.projectPath }}/Properties/Version.txt)" | Out-File -FilePath $env:GITHUB_ENV -Append
      
      - name: Read warnings.txt
        uses: guibranco/github-file-reader-action-v2@v2.2.698
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        id: warnings
        with:
         path: msbuild.warnings.log

      - name: Read errors.txt        
        uses: guibranco/github-file-reader-action-v2@v2.2.698
        if: failure() && (steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch')
        id: errors
        with:
         path: msbuild.errors.log

      - name: Update PR with comment (version)
        uses: mshick/add-pr-comment@v2
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          repo-token: ${{ steps.generate_token.outputs.token }}
          refresh-message-position: true
          message-id: 'version'
          message: |
            **Build debug & Version bump:** :dart: [Build succeeded](${{ env.GHA_URL }}) - New version: ${{ env.version }}

      - name: Set check as successfully before new commit
        uses: LouisBrunner/checks-action@v2.0.0
        if: success()
        with:
          token: ${{ steps.generate_token.outputs.token }}
          conclusion: 'success'
          check_id: ${{ steps.generate_check.outputs.check_id }}
          output: |
            {"summary":"New version: ${{ env.version }}"}

      - name: Set check as the action required before new commit
        uses: LouisBrunner/checks-action@v2.0.0
        if: failure()
        with:
          token: ${{ steps.generate_token.outputs.token }}
          conclusion: 'action_required'
          action_url: ${{ env.GHA_URL }}
          check_id: ${{ steps.generate_check.outputs.check_id }}
          output: |
            {"summary": "Build failed!"}

      - name: Setup GIT config
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: |
          git config user.name "net-framework-updater[bot]"
          git config user.email "136581072+net-framework-updater[bot]@users.noreply.github.com"
          git config --global --add --bool push.autoSetupRemote true

      - name: Commit and Push
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        run: |
          git add .
          git commit -a -m "Version bump (CI)"
          echo "sha1=$(git rev-parse HEAD)" | Out-File -FilePath $env:GITHUB_ENV -Append
          git push
          
      - name: Analyze after commit
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        env:
          DEEPSOURCE_DSN: ${{ secrets.DEEPSOURCE_DSN }}
        run: .\deepsource report --analyzer test-coverage --key csharp --value-file "Tests\${{ env.solution }}.UnitTests\coverage.cobertura.xml"

      - name: Update PR with comment
        uses: mshick/add-pr-comment@v2
        if: always() && (steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch')
        with:
          repo-token: ${{ steps.generate_token.outputs.token }}
          refresh-message-position: true
          message-id: 'final'
          message: |
            **Build debug & Version bump:** :white_check_mark: [Successfully builded and patched](${{ env.GHA_URL }}) **${{ env.solution }}.sln**.
            
            **Version:** :hash: ${{ env.version }}
            **Warnings:** :warning:
            ```
            ${{ steps.warnings.outputs.contents }}
            ```
          message-failure: |
            **Build debug & Version bump:** :x: [Failed](${{ env.GHA_URL }})

            **Errors:** :no_entry:
            ```
            ${{ steps.errors.outputs.contents }}
            ```
          message-cancelled: |
            **Build debug & Version bump:** :o: [Cancelled](${{ env.GHA_URL }})

      - name: Set check as successfully after a new commit
        uses: LouisBrunner/checks-action@v2.0.0
        if: steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch'
        with:
          token: ${{ steps.generate_token.outputs.token }}
          conclusion: 'success'
          name: 'Build & Bump Version'
          output: |
            {"summary":"New version: ${{ env.version }}"}

      - name: Update check run status (Success)
        uses: guibranco/github-status-action-v2@v1.1.13
        if: success() && (steps.changes.outputs.src == 'true' || github.event_name == 'workflow_dispatch')
        with:
          authToken: ${{ steps.generate_token.outputs.token }}
          context: 'Build & Bump Version'
          description: 'Build ${{ env.solution}}.sln - Version: ${{ env.version }}'
          state: 'success'
          sha: ${{ env.sha1 }}
          target_url: ${{ env.GHA_URL }}

      - name: Update check run status (Failure or Cancellation)
        uses: guibranco/github-status-action-v2@v1.1.13
        if: failure() || cancelled()
        with:
          authToken: ${{ steps.generate_token.outputs.token }}
          context: 'Build & Bump Version'
          description: ${{ job.status }}
          state: 'failure'
          sha: ${{ github.event.pull_request.head.sha || github.sha }}
          target_url: ${{ env.GHA_URL }}