name: ci

on:
  push:
    branches: [ main ]
  pull_request:
  workflow_dispatch:

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - machine: windows-2022
            containers: windows
            log-dir: "/c/ProgramData/OpenTelemetry .NET AutoInstrumentation/logs"
          - machine: ubuntu-20.04
            containers: linux
            log-dir: "/var/log/opentelemetry/dotnet"
          - machine: macos-11
            containers: none
            log-dir: "/var/log/opentelemetry/dotnet"
    runs-on: ${{ matrix.machine }}
    steps:
      - uses: actions/checkout@v3.3.0
      - uses: actions/setup-dotnet@v3.0.3
        with:
          dotnet-version: | 
            6.0.x
            7.0.x
      - name: Install SQL Server (localdb)
        uses: potatoqualitee/mssqlsuite@v1.7
        if: ${{ runner.os == 'Windows' }}
        with: 
          install: localdb
      - run: ./build.cmd Workflow --containers ${{ matrix.containers }}
      - name: Upload logs
        uses: actions/upload-artifact@v3.1.2
        if: always()
        with:
          name: logs-${{ matrix.machine }}
          path: build_data/
      - run: brew install coreutils
        if: ${{ runner.os == 'macOS' }}
      - name: Create test directory
        run: sudo mkdir -p ${{ matrix.log-dir }} && sudo chmod a+rwx ${{ matrix.log-dir }}  # the instrumented process has no permissions to create log dir
        if: ${{ runner.os != 'Windows' }}
      - name: Test the Shell scripts from README.md
        shell: bash
        run: |
          set -e
          dotnet publish -f net7.0 -c Release ./test/test-applications/integrations/TestApplication.Smoke
          export OTEL_DOTNET_AUTO_HOME="${PWD}/bin/tracer-home"
          . ./instrument.sh
          ./test/test-applications/integrations/TestApplication.Smoke/bin/Release/net7.0/publish/TestApplication.Smoke
            test "$(ls -A '${{ matrix.log-dir }}' )"
      - name: Test the PowerShell module instructions from README.md
        if: ${{ runner.os == 'Windows' }}
        shell: powershell
        run: |
          $log_path = "C:\ProgramData\OpenTelemetry .NET AutoInstrumentation\logs\*"
          Import-Module "${PWD}/OpenTelemetry.DotNet.Auto.psm1"
          [System.Environment]::SetEnvironmentVariable("OTEL_DOTNET_AUTO_INSTALL_DIR", "${PWD}/bin/tracer-home", [System.EnvironmentVariableTarget]::Machine)
          Register-OpenTelemetryForCurrentSession -OTelServiceName "MyServiceDisplayName"
          ./test/test-applications/integrations/TestApplication.Smoke/bin/Release/net7.0/TestApplication.Smoke.exe
          if (-not $?) { throw "dotnet help returned exit code: $LASTEXITCODE" }
          if (-not (Test-Path $log_path)) { throw "Log file does not exist. Instrumentation test failed." }
          Remove-Item $log_path
          Unregister-OpenTelemetryForCurrentSession
          ./test/test-applications/integrations/TestApplication.Smoke/bin/Release/net7.0/TestApplication.Smoke.exe
          if (-not $?) { throw "dotnet help returned exit code: $LASTEXITCODE" }
          if (Test-Path $log_path) { throw "Log file exists. Instrumentation unregister failed." }
      - name: Upload binaries
        uses: actions/upload-artifact@v3.1.2
        if: always()
        with:
          name: bin-${{ matrix.machine }}
          path: bin/tracer-home
      - name: Delete SQL Server MSI
        if: ${{ runner.os == 'Windows' }}
        shell: bash
        run: |
          rm SqlLocalDB.msi
      - name: Generated files unchanged
        shell: bash
        run: |
          git status
          git diff
          [[ -z "$(git status --porcelain)" ]]

  build-container:
    strategy:
      fail-fast: false
      matrix:
        include:
          - base-image: alpine
            os-type: linux-musl
          - base-image: centos
            os-type: linux-glibc
    runs-on: ubuntu-20.04
    timeout-minutes: 60
    steps:
    - uses: actions/checkout@v3.3.0
    - name: Build in Docker container
      run: |
        set -e
        docker build -t mybuildimage -f "./docker/${{ matrix.base-image }}.dockerfile" ./docker
        docker run -e OS_TYPE=${{ matrix.os-type }} --rm --mount type=bind,source="${GITHUB_WORKSPACE}",target=/project mybuildimage \
          ./build.sh Workflow --containers none
    - name: Test the Shell scripts from README.md in Docker container
      run: |
        set -e
        docker build -t mybuildimage -f "./docker/${{ matrix.base-image }}.dockerfile" ./docker
        docker run --mount type=bind,source="${GITHUB_WORKSPACE}",target=/project --rm mybuildimage /bin/sh -c '
          set -e
          dotnet publish -f net7.0 -c Release ./test/test-applications/integrations/TestApplication.Smoke
          export OTEL_DOTNET_AUTO_HOME="${PWD}/bin/tracer-home"
          . ./instrument.sh
          ./test/test-applications/integrations/TestApplication.Smoke/bin/Release/net7.0/publish/TestApplication.Smoke
            test "$(ls -A /var/log/opentelemetry/dotnet )"
        '
    - name: Publish Linux build
      uses: actions/upload-artifact@v3.1.2
      with:
        name: bin-${{ matrix.base-image }}
        path: bin/tracer-home
      if: (${{ job.status }} != 'cancelled')
      continue-on-error: true

  pack:
    needs: build

    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3.3.0
      - uses: nuget/setup-nuget@v1.1.1

      - name: Download Windows Artifacts from build job
        uses: actions/download-artifact@v3.0.2
        with:
          name: bin-windows-2022
          path: nuget/bin-windows

      - name: Download CentOS Artifacts from build job
        uses: actions/download-artifact@v3.0.2
        with:
          name: bin-centos
          path: nuget/bin-linux-glibc

      - name: Download Alpine Artifacts from build job
        uses: actions/download-artifact@v3.0.2
        with:
          name: bin-alpine
          path: nuget/bin-linux-musl

      - name: Download Mac-OS Artifacts from build job
        uses: actions/download-artifact@v3.0.2
        with:
          name: bin-macos-11
          path: nuget/bin-macos

      - name: Build NuGet package
        run: nuget pack OpenTelemetry.AutoInstrumentation.nuspec -Properties NoWarn=NU5100,NU5123,NU5128
        working-directory: nuget

      - name: Upload Nuget
        uses: actions/upload-artifact@v3.1.2
        with:
          name: OpenTelemetry.AutoInstrumentation.Nuget
          path: nuget/*.nupkg
