DEV Community

lastlink
lastlink

Posted on

dotnet-ci-pipelines

My Workflow

Note: # description: A project to demonstrate using github actions for a .net core 3.1 project. Uses unit tests, json snapshots, database tests using docker service containers. Demonstrates their use in github actions, bitbucket, azure devops, and gitlab.

Submission Category:

Note: # Maintainer Must-Haves

Yaml File or Link to Code

GitHub logo lastlink / dotnet-ci-pipelines

dotnet ci cd pipelines for github, azure devops, gitlab, bitbucket, and etc.

DOTNET CORE CI PIPELINE EXAMPLE:

Goal to have dotnet core c# example pipelines for major git source control dev ops including github, azure devops, gitlab, bitbucket, and etc. Should auto run only on a new pull request, show test results in native ui per website, code coverage, and some additional manual steps running code quality analysis. Badge support native is also nice or from https://shields.io/category/build. Also will try service containers and database unit tests Originally off of gitlab-ci-example-dotnetcore.

Contribution

  • Please do a pull request to the proper source control pipeline that you are trying to update.

TOC

[ ] GitHub Actions Actions Status

  • limits 2,000 (per month) to 20 concurrent jobs support windows, ubuntu, mac
    • doesn't currently support retry and max timeout although will cancel when limit reached.
  • Badges - workflow
  • api docs - docfx html only
  • [!] Tests - no…

name: .NET Core

# use https://marketplace.visualstudio.com/items?itemName=me-dutour-mathieu.vscode-github-actions to validate yml in vscode
env:
  NUGET_PACKAGES_DIRECTORY: '.nupkg'
  RESHARPER_CLI_NAME: 'JetBrains.ReSharper.CommandLineTools.Unix'
  RESHARPER_CLI_VERSION: "2019.2.3"
  DOCKER_DRIVER: overlay
  CONTAINER_IMAGE: codeclimate/codeclimate
  CONTAINER_TAG: '0.85.2'
  rIds: ${{ secrets.rIds }}
  dotnetVersion: 3.1.102

on:
  pull_request:
    branches:
      - master
  push:
    branches:
      - master

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.dotnetVersion}}
    - name: Build with dotnet
      run: |
        export DOTNET_CLI_TELEMETRY_OPTOUT=1
        dotnet publish -c Release
    - name: Tests
      run: |
        cp MyProject.Repository.Test/Data/appSettings.gitlab.json MyProject.Repository.Test/Data/AppSettings.json
        dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='./TestResults/'
    - name: Coverage Report
      run: |
        dotnet --version
        dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools
        ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:TextSummary;
        ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:Html;
        ./tools/reportgenerator "-reports:**/TestResults/coverage.opencover.xml;" "-targetdir:Reports" -reportTypes:Badges;
        cat ./Reports/Summary.txt
    - uses: actions/upload-artifact@v1
      with:
          name: CodeCoverage
          path: Reports
    - name: Resharper Code Quality
      run: |
        # apt update && apt install -y curl zip unzip
        curl -LO "https://download.jetbrains.com/resharper/ReSharperUltimate.$RESHARPER_CLI_VERSION/$RESHARPER_CLI_NAME.$RESHARPER_CLI_VERSION.zip"
        unzip -q $RESHARPER_CLI_NAME.$RESHARPER_CLI_VERSION.zip -d "resharper"
        mkdir -p CodeQuality
        files=(*.sln)
        sh ./resharper/dupfinder.sh "${files[0]}" --output=CodeQuality/dupfinderReport.html --format=Html
        sh ./resharper/inspectcode.sh "${files[0]}" --output=CodeQuality/inspectcodeReport.html --format=Html
    - uses: actions/upload-artifact@v1
      with:
          name: CodeQuality
          path: CodeQuality
    - name: prerelease
      if: ${{ env.rIds }} != ''
      run: |
        echo 'build, obfuscate, and release'
        dotnet tool install Obfuscar.GlobalTool --tool-path tools --version 2.2.28
        bash scripts/extractRelease.sh
        export rIds=${{ env.rIds }}
        bash ./scripts/pipeline.sh
        bash ./scripts/finalRelease.sh
    - name: upload release
      uses: actions/upload-artifact@v2
      if: ${{ env.rIds }} != ''
      with:
        name: Release_unix
        path: Release/post

  build-win:
    runs-on: windows-latest
    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.dotnetVersion}}
    - name: Build with dotnet
      run: |
        set DOTNET_CLI_TELEMETRY_OPTOUT=1
        dotnet publish -c Release
    - name: Tests
      run: |
        copy MyProject.Repository.Test/Data/appSettings.gitlab.json MyProject.Repository.Test/Data/AppSettings.json
        dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='.\TestResults\'
    - name: prerelease
      if: ${{ env.rIds }} != ''
      run: |
        echo "build, obfuscate, and release"
        dotnet tool install Obfuscar.GlobalTool --tool-path tools --version 2.2.28
        .\scripts\extractRelease.cmd
        set rIds=$env:rIds
        .\scripts\pipeline.cmd
        .\scripts\finalRelease.cmd
    - name: upload release
      uses: actions/upload-artifact@v2
      if: ${{ env.rIds }} != ''
      with:
        name: Release_win
        path: Release\post

  unit_test_db_mssql:
    runs-on: ubuntu-latest
    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      localhost_mysql:
        # Docker Hub image
        image: mcr.microsoft.com/mssql/server:2019-latest
        #
        ports:
          # Opens tcp port 6379 on the host and service container
          - 1433:1433
        env:
          GIT_SUBMODULE_STRATEGY: recursive
          ACCEPT_EULA: Y
          SA_PASSWORD: yourStrong(!)Password
    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.dotnetVersion}}
    - name: enabledb
      run: cp ./MyProject.Repository.Test/Data/appSettings.bitbucket.mssql.json ./MyProject.Repository.Test/Data/AppSettings.json
    - name: Tests
      run: |
        cd MyProject.Repository.Test
        dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='./TestResults/'

  unit_test_db_postgres:
    runs-on: ubuntu-latest
    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: postgres:11
        #
        ports:
          - 5432:5432
        # Provide the password for postgres
        env:
          POSTGRES_DB: mockDb
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: "mysecretpassword"
          POSTGRES_HOST_AUTH_METHOD: trust
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.dotnetVersion}}
    - name: enabledb
      run: cp ./MyProject.Repository.Test/Data/appSettings.devops.postgres.json ./MyProject.Repository.Test/Data/AppSettings.json
    - name: Tests
      run: |
        cd MyProject.Repository.Test
        dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='./TestResults/'

  unit_test_db_mysql:
    runs-on: ubuntu-latest
    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: mysql:5.7.29
        #
        ports:
          - 3306:3306
        env:
          MYSQL_DATABASE: "mockDb"
          MYSQL_ROOT_PASSWORD: "mysecretpw"
    steps:
    - uses: actions/checkout@v1
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: ${{ env.dotnetVersion}}
    - name: enabledb
      run: cp ./MyProject.Repository.Test/Data/appSettings.devops.mysql.json ./MyProject.Repository.Test/Data/AppSettings.json
    - name: Tests
      run: |
        cd MyProject.Repository.Test
        dotnet test --logger "junit" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput='./TestResults/'

  code_docs:
    runs-on: windows-latest
    name: code documentation
    steps:
      - uses: actions/checkout@v1
      - name: docfx
        run: |
          curl -LO "https://github.com/dotnet/docfx/releases/download/v2.48/docfx.zip"
          powershell.exe -NoP -NonI -Command "Expand-Archive '.\docfx.zip' '.\docfx\'" 
          ./docfx/docfx.exe
      - uses: actions/upload-artifact@v1
        with:
          name: CodeDocs
          path: _site

  security:
    runs-on: ubuntu-latest
    name: Snyk Security Scan
    steps:
      - uses: actions/checkout@v1
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: ${{ env.dotnetVersion}}
      - name: Build with dotnet
        run: |
          export DOTNET_CLI_TELEMETRY_OPTOUT=1
          dotnet build
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/dotnet@master
        with:
          args: --file=MyProject.sln
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Additional Resources / Info

Note: # https://github.com/lastlink/dotnet-ci-pipelines/blob/master/.github/workflows/dotnetcore.yml

Note: # @lastlink

[Reminder]: # (Submissions are due on December 8th, 2021 (11:59 PM PT or 2 AM ET/6 AM UTC on December 9th).

Discussion (0)