name: Build on Runners

on:
  workflow_call:

env:
  NUGET_PACKAGES: ${{ github.workspace }}/packages
  DOTNET_CLI_TELEMETRY_OPTOUT: 1

permissions:
  contents: read

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - machine: windows-2022
            log-dir: "/c/ProgramData/OpenTelemetry .NET AutoInstrumentation/logs"
          - machine: ubuntu-22.04
            log-dir: "/var/log/opentelemetry/dotnet"
          - machine: macos-13
            log-dir: "/var/log/opentelemetry/dotnet"
          - machine: ubuntu-22.04-arm
            log-dir: "/var/log/opentelemetry/dotnet"
    runs-on: ${{ matrix.machine }}
    steps:

      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag: v4.2.2
        with:
          fetch-depth: 0 # fetching all, needed to correctly calculate version

      - name: Setup .NET
        uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # tag: v4.3.1
        with:
          dotnet-version: | 
            8.0.412
            9.0.302

      - name: Check for NuGet packages cache
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # tag: v4.2.3
        id: nuget-cache
        with:
          key: ${{ hashFiles('**/Directory.packages.props', './build/LibraryVersions.g.cs', '**/packages.config' ) }}
          path: ${{ env.NUGET_PACKAGES }}

      - name: Restore NuGet packages
        if: ${{ steps.nuget-cache.outputs.cache-hit != 'true' }}
        continue-on-error: false
        run: ./build.cmd Restore

      - name: Cache NuGet packages
        if: ${{ steps.nuget-cache.outputs.cache-hit != 'true' }}
        uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # tag: v4.2.3
        with:
          key: ${{ hashFiles('**/Directory.packages.props', './build/LibraryVersions.g.cs', '**/packages.config' ) }}
          path: ${{ env.NUGET_PACKAGES }}

      - name: Run BuildWorkflow
        run: ./build.cmd BuildWorkflow --no-restore ${{ steps.nuget-cache.outputs.cache-hit != 'true' }}

      - name: Download native Ubuntu 16.04 Artifacts from build job
        if: ${{ matrix.machine == 'ubuntu-22.04' }}
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # tag: v4.3.0
        with:
          name: bin-ubuntu1604-native
          path: bin/ci-artifacts/bin-ubuntu1604-native

      - name: Replace Ubuntu native code by Ubuntu 16.04 artifacts
        if: ${{ matrix.machine == 'ubuntu-22.04' }}
        run: |
          rm ./bin/tracer-home/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
          cp ./bin/ci-artifacts/bin-ubuntu1604-native/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so ./bin/tracer-home/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so

      - name: Install MacOS CoreUtils
        if: ${{ runner.os == 'macOS' }}
        run: brew install coreutils

      - name: Create test directory
        if: ${{ runner.os != 'Windows' }}
        run: sudo mkdir -p ${{ matrix.log-dir }} && sudo chmod a+rwx ${{ matrix.log-dir }}  # the instrumented process has no permissions to create log dir

      - name: Test the Shell scripts from README.md
        shell: bash
        run: |
          set -e
          dotnet publish -f net9.0 -c Release ./test/test-applications/integrations/TestApplication.Smoke
          export OTEL_DOTNET_AUTO_HOME="${PWD}/bin/tracer-home"
          . ./instrument.sh
          ./test/test-applications/integrations/bin/TestApplication.Smoke/Release/net9.0/publish/TestApplication.Smoke
            test "$(ls -A '${{ matrix.log-dir }}' )"

      - name: Test the Windows PowerShell module instructions from README.md
        if: ${{ runner.os == 'Windows' }}
        shell: powershell
        run: |
          $log_path = "C:\ProgramData\OpenTelemetry .NET AutoInstrumentation\logs\*"
          Import-Module "${PWD}/bin/installation-scripts/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/bin/TestApplication.Smoke/Release/net9.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/bin/TestApplication.Smoke/Release/net9.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
        if: always()
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # tag: v4.6.2
        with:
          name: bin-${{ matrix.machine }}
          path: bin/tracer-home

      - name: Upload installation scripts
        if: always()
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # tag: v4.6.2
        with:
          name: installation-scripts-${{ matrix.machine }}
          path: bin/installation-scripts

      - name: Regenerate LibraryVersions.g.cs
        # Regenerate the library versions file to surface any version changes made to the packages being tested.
        run: ./build.cmd GenerateLibraryVersionFiles

      - name: Generated files unchanged
        shell: bash
        run: |
          git status
          git diff
          [[ -z "$(git status --porcelain)" ]]
