From 030bc1de6efdc2f8350eb971d6477ff4685d1dc9 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Sun, 11 Feb 2024 23:37:14 +0200 Subject: [PATCH 1/7] Implemented a GitHub Actions testing pipeline --- .github/actions/get-dotnet-channel/action.yml | 22 ++ .github/actions/get-program-files/action.yml | 28 +++ .github/actions/test-build-cache/action.yml | 19 ++ .github/actions/test-execute-test/action.yml | 89 +++++++ .../test-setup-dotnet-windows/action.yml | 33 +++ .github/actions/test-setup-dotnet/action.yml | 27 +++ .../test-setup-mono-windows/action.yml | 45 ++++ .github/actions/test-upload-result/action.yml | 34 +++ .github/workflows/test-build.yml | 58 +++++ .github/workflows/test-qemu-dotnet.yml | 92 ++++++++ .github/workflows/test-qemu-mono.yml | 85 +++++++ .github/workflows/test-result-upload.yml | 33 +++ .github/workflows/test-unix-dotnet.yml | 75 ++++++ .github/workflows/test-unix-mono.yml | 72 ++++++ .github/workflows/test-windows-dotnet.yml | 67 ++++++ .github/workflows/test-windows-framework.yml | 61 +++++ .github/workflows/test-windows-mono.yml | 66 ++++++ .github/workflows/test.yml | 217 ++++++++++++++++++ Harmony.sln | 73 ++++++ 19 files changed, 1196 insertions(+) create mode 100644 .github/actions/get-dotnet-channel/action.yml create mode 100644 .github/actions/get-program-files/action.yml create mode 100644 .github/actions/test-build-cache/action.yml create mode 100644 .github/actions/test-execute-test/action.yml create mode 100644 .github/actions/test-setup-dotnet-windows/action.yml create mode 100644 .github/actions/test-setup-dotnet/action.yml create mode 100644 .github/actions/test-setup-mono-windows/action.yml create mode 100644 .github/actions/test-upload-result/action.yml create mode 100644 .github/workflows/test-build.yml create mode 100644 .github/workflows/test-qemu-dotnet.yml create mode 100644 .github/workflows/test-qemu-mono.yml create mode 100644 .github/workflows/test-result-upload.yml create mode 100644 .github/workflows/test-unix-dotnet.yml create mode 100644 .github/workflows/test-unix-mono.yml create mode 100644 .github/workflows/test-windows-dotnet.yml create mode 100644 .github/workflows/test-windows-framework.yml create mode 100644 .github/workflows/test-windows-mono.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/actions/get-dotnet-channel/action.yml b/.github/actions/get-dotnet-channel/action.yml new file mode 100644 index 00000000..2329b771 --- /dev/null +++ b/.github/actions/get-dotnet-channel/action.yml @@ -0,0 +1,22 @@ +name: Convert Target Framework to Channel +description: Convert Target Framework to Channel + +inputs: + target_framework: + description: 'The target framework to use' + required: true + +outputs: + channel: + description: 'The converted Channel variable' + value: ${{ steps.set_channel.outputs.channel }} + +runs: + using: "composite" + steps: + - name: Set Channel + id: set_channel + run: | + $channel = '${{inputs.target_framework}}'.Replace('coreapp', '').Replace('net', ''); + "channel=$channel" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + shell: pwsh diff --git a/.github/actions/get-program-files/action.yml b/.github/actions/get-program-files/action.yml new file mode 100644 index 00000000..95afca37 --- /dev/null +++ b/.github/actions/get-program-files/action.yml @@ -0,0 +1,28 @@ +name: Get ProgramFiles Path +description: Get ProgramFiles path for the architecture + +inputs: + architecture: + description: 'The architecture to use' + required: true + +outputs: + path: + description: 'The ProgramFiles path for the architecture' + value: ${{ steps.set-path.outputs.path }} + +runs: + using: "composite" + steps: + - name: Set Program Files path for ${{inputs.architecture}} + id: set-path + run: | + if ('${{ inputs.architecture == 'x86'}}' -eq 'true') { + $path = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFilesX86); + "path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + } + if ('${{ inputs.architecture == 'x64'}}' -eq 'true') { + $path = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFiles); + "path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + } + shell: pwsh diff --git a/.github/actions/test-build-cache/action.yml b/.github/actions/test-build-cache/action.yml new file mode 100644 index 00000000..5bd65e42 --- /dev/null +++ b/.github/actions/test-build-cache/action.yml @@ -0,0 +1,19 @@ +name: Test Download Build Cache +description: Download the build cache for the specified operating system and build configuration + +inputs: + os: + description: 'The operating system to use' + required: true + build_configuration: + description: 'The build configuration to use' + required: true + +runs: + using: "composite" + steps: + - name: Download Build Cache + uses: actions/download-artifact@v4 + with: + name: build-output-${{inputs.os}}-${{inputs.build_configuration}} + path: HarmonyTests/bin/ diff --git a/.github/actions/test-execute-test/action.yml b/.github/actions/test-execute-test/action.yml new file mode 100644 index 00000000..5f8f253a --- /dev/null +++ b/.github/actions/test-execute-test/action.yml @@ -0,0 +1,89 @@ +name: Test Execute Test +description: Executes the tests + +inputs: + os: + description: 'The operating system to use' + required: true + architecture: + description: 'The architecture to use' + required: true + runtime-type: + description: 'Values: "dotnet", "mono", "fx"' + required: true + target_framework: + description: 'The target framework to use' + required: true + build_configuration: + description: 'The build configuration to use' + required: true + upload_tests: + description: 'Whether to upload the test results' + required: true + experimental: + description: 'Whether the tests are mandatory for the build to pass' + required: true + +runs: + using: "composite" + steps: + - name: Set Test Args + id: test-args + run: | + $run_settings_args = 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=${{inputs.architecture}}' + "run_settings_args=$run_settings_args" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + + $vstest = '"HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" --framework:${{inputs.target_framework}} --logger:trx --logger:"console;verbosity=normal" --blame'; + "vstest=$vstest" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + + $dotnet = '"HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" -f ${{inputs.target_framework}} -l trx -l "console;verbosity=normal" --blame'; + "dotnet=$dotnet" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + shell: pwsh + + - name: Get Program Files path for ${{inputs.architecture}} + uses: ./.github/actions/get-program-files + id: get-program-files + with: + architecture: ${{inputs.architecture}} + + - name: Perform Tests Windows Mono + if: ${{inputs.os == 'windows' && inputs.runtime-type == 'mono'}} + run: | + $vspath = vswhere -latest -property installationPath; + $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; + + $mono = "${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe"; + & "$mono" "$vstest" ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + shell: pwsh + + - name: Perform Tests Windows FX + if: ${{inputs.os == 'windows' && inputs.runtime-type == 'fx'}} + run: | + $vspath = vswhere -latest -property installationPath; + $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; + + & "$vstest" ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + shell: pwsh + + - name: Perform Tests Windows .NET + if: ${{inputs.os == 'windows' && inputs.runtime-type == 'dotnet'}} + run: | + dotnet test ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + shell: pwsh + + - name: Perform Tests Ubuntu/MacOS/MacOS-arm64 .NET/Mono + if: ${{inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} + run: | + dotnet test ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + shell: pwsh + + - name: Upload Test Result + uses: ./.github/actions/test-upload-result + if: ${{(inputs.upload_tests == 'true') && (always() || failure())}} + with: + os: ${{inputs.os}} + architecture: ${{inputs.architecture}} + runtime-type: ${{inputs.runtime-type}} + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + experimental: ${{inputs.experimental == 'true'}} diff --git a/.github/actions/test-setup-dotnet-windows/action.yml b/.github/actions/test-setup-dotnet-windows/action.yml new file mode 100644 index 00000000..fd4e1ef0 --- /dev/null +++ b/.github/actions/test-setup-dotnet-windows/action.yml @@ -0,0 +1,33 @@ +name: Setup .NET Windows +description: Setup .NET for Windows using the provided target framework and architecture + +inputs: + architecture: + description: 'The .NET architecture to setup' + required: true + target_framework: + description: 'The .NET target framework to setup' + required: true + +runs: + using: "composite" + steps: + - name: Get .NET Channel for ${{inputs.target_framework}} + uses: ./.github/actions/get-dotnet-channel + id: get_channel + with: + target_framework: ${{inputs.target_framework}} + + - name: Get Program Files path for ${{inputs.architecture}} + uses: ./.github/actions/get-program-files + id: get-program-files + with: + architecture: ${{inputs.architecture}} + + - name: Setup .NET ${{inputs.architecture}} + run: | + Invoke-WebRequest 'https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1; + .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel LTS -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel STS -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel ${{steps.get_channel.outputs.channel}} -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + shell: pwsh diff --git a/.github/actions/test-setup-dotnet/action.yml b/.github/actions/test-setup-dotnet/action.yml new file mode 100644 index 00000000..4c0deb1b --- /dev/null +++ b/.github/actions/test-setup-dotnet/action.yml @@ -0,0 +1,27 @@ +name: Setup .NET +description: Setup .NET using the provided target framework and architecture + +inputs: + architecture: + description: 'The .NET architecture to setup' + required: true + target_framework: + description: 'The .NET target framework to setup' + required: true + +runs: + using: "composite" + steps: + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + + - name: Get .NET Channel for ${{inputs.target_framework}} + uses: ./.github/actions/get-dotnet-channel + id: get_channel + with: + target_framework: ${{inputs.target_framework}} + + - name: Setup .NET ${{steps.get_channel.outputs.channel}} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{steps.get_channel.outputs.channel}} diff --git a/.github/actions/test-setup-mono-windows/action.yml b/.github/actions/test-setup-mono-windows/action.yml new file mode 100644 index 00000000..21df55e3 --- /dev/null +++ b/.github/actions/test-setup-mono-windows/action.yml @@ -0,0 +1,45 @@ +name: Setup Mono Windows +description: Setup Mono for Windows using the latest version + +inputs: + architecture: + description: 'The architecture to setup Mono for' + required: true + +outputs: + path: + description: 'The Mono path for the architecture' + value: '${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe' + +runs: + using: "composite" + steps: + - name: Setup Mono x86 Manually + if: inputs.architecture == 'x86' + run: | + curl -L https://download.mono-project.com/archive/mono-latest-x86-preview.msi -o mono.msi; + $file = "mono.msi" + $log = "install.log" + $procMain = Start-Process "msiexec" "/i `"$file`" /qn /l*! `"$log`"" -NoNewWindow -PassThru + $procLog = Start-Process "powershell" "Get-Content -Path `"$log`" -Wait" -NoNewWindow -PassThru + $procMain.WaitForExit() + $procLog.Kill() + shell: pwsh + + - name: Setup Mono x64 Manually + if: inputs.architecture == 'x64' + run: | + curl -L https://download.mono-project.com/archive/mono-latest-x64-preview.msi -o mono.msi; + $file = "mono.msi" + $log = "install.log" + $procMain = Start-Process "msiexec" "/i `"$file`" /qn /l*! `"$log`"" -NoNewWindow -PassThru + $procLog = Start-Process "powershell" "Get-Content -Path `"$log`" -Wait" -NoNewWindow -PassThru + $procMain.WaitForExit() + $procLog.Kill() + shell: pwsh + + - name: Get Program Files path for ${{inputs.architecture}} + uses: ./.github/actions/get-program-files + id: get-program-files + with: + architecture: ${{inputs.architecture}} diff --git a/.github/actions/test-upload-result/action.yml b/.github/actions/test-upload-result/action.yml new file mode 100644 index 00000000..f51f68ea --- /dev/null +++ b/.github/actions/test-upload-result/action.yml @@ -0,0 +1,34 @@ +name: Test Upload Result +description: Test Upload Result + +inputs: + os: + description: 'The operating system to use' + required: true + architecture: + description: 'The architecture to use' + required: true + runtime-type: + description: 'Values: "dotnet", "mono", "fx"' + required: true + target_framework: + description: 'The target framework to use' + required: true + build_configuration: + description: 'The build configuration to use' + required: true + experimental: + description: 'Whether the tests are mandatory for the build to pass' + required: true + #type: boolean # We don't have boolean types in composites https://github.com/actions/runner/issues/2238 + +runs: + using: "composite" + steps: + - name: Upload Test Results + uses: actions/upload-artifact@v4 + if: ${{success() || failure()}} + with: + name: ${{(inputs.experimental == 'true' && 'experimental-') || ''}}test-results-${{inputs.runtime-type}}-${{inputs.os}}-${{inputs.architecture}}-${{inputs.target_framework}}-${{inputs.build_configuration}} + path: '**/*.trx' + if-no-files-found: ${{(inputs.experimental == 'true' && 'ignore') || 'warn'}} diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml new file mode 100644 index 00000000..c21d7251 --- /dev/null +++ b/.github/workflows/test-build.yml @@ -0,0 +1,58 @@ +name: Template Testing Build +# We build the binaries for all os and configurations +# So we don't have to do that on each test run + +on: + workflow_call: + inputs: + os: + required: true + type: string + description: 'The operating system to use' + image: + required: true + type: string + description: 'The image to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + publish: + required: true + type: boolean + description: 'Whether to publish the build artifacts' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + build-output-cache: + name: Upload Test Build Output Cache + runs-on: ${{inputs.image}} + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + + - name: Build + run: | + dotnet build -c ${{inputs.build_configuration}} Harmony.sln + + - name: Upload Test Build Output Cache + uses: actions/upload-artifact@v4 + with: + name: build-output-${{inputs.os}}-${{inputs.build_configuration}} + path: HarmonyTests/bin/**/* + + - name: Upload Harmony zip + if: ${{inputs.publish}} + uses: actions/upload-artifact@v4 + with: + name: Harmony-${{inputs.build_configuration}}-${{inputs.os}} + path: Harmony/bin/Harmony*.zip diff --git a/.github/workflows/test-qemu-dotnet.yml b/.github/workflows/test-qemu-dotnet.yml new file mode 100644 index 00000000..a1d3c302 --- /dev/null +++ b/.github/workflows/test-qemu-dotnet.yml @@ -0,0 +1,92 @@ +name: Template Testing Unix .NET + +on: + workflow_call: + inputs: + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + run_settings_args: + required: true + type: string + description: 'The run settings arguments to use for tests' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + unix-net: + name: .NET ubuntu-arm64 ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: ubuntu-latest + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 7 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: ubuntu + build_configuration: ${{inputs.build_configuration}} + + - name: Get .NET Channel for ${{inputs.target_framework}} + uses: ./.github/actions/get-dotnet-channel + id: get_channel + with: + target_framework: ${{inputs.target_framework}} + + - name: Test .NET + uses: uraimo/run-on-arch-action@v2.7.1 + id: build + with: + arch: aarch64 + distro: ubuntu22.04 + shell: /bin/bash + env: | + DOTNET_NOLOGO: ${{env.DOTNET_NOLOGO}} + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: ${{env.DOTNET_SKIP_FIRST_TIME_EXPERIENCE}} + DOTNET_CLI_TELEMETRY_OPTOUT: ${{env.DOTNET_CLI_TELEMETRY_OPTOUT}} + dockerRunArgs: | + --volume "${PWD}/src:/src" + install: | + apt-get update + apt-get install -y wget libc6 libgcc-s1 libgssapi-krb5-2 libicu70 liblttng-ust1 libssl3 libstdc++6 libunwind8 zlib1g + + wget https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh; + chmod +x dotnet-install.sh; + ./dotnet-install.sh --channel LTS --no-path > /dev/null; + ./dotnet-install.sh --channel STS --no-path > /dev/null; + ./dotnet-install.sh --channel ${{steps.get_channel.outputs.channel}} --no-path > /dev/null; + run: | + LD_LIBRARY_PATH="/usr/local/lib" /root/.dotnet/dotnet test "HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" -f ${{inputs.target_framework}} -l trx -l "console;verbosity=normal" --blame -- ${{inputs.run_settings_args}}; + + - name: Upload Test Result + uses: ./.github/actions/test-upload-result + if: ${{inputs.upload_tests}} + with: + os: ${{inputs.os}} + architecture: ${{inputs.architecture}} + runtime-type: dotnet + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-qemu-mono.yml b/.github/workflows/test-qemu-mono.yml new file mode 100644 index 00000000..6a68cc13 --- /dev/null +++ b/.github/workflows/test-qemu-mono.yml @@ -0,0 +1,85 @@ +name: Template Testing Qemu Mono + +on: + workflow_call: + inputs: + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + run_settings_args: + required: true + type: string + description: 'The run settings arguments to use for tests' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + ubuntu-mono-arm64: + name: Mono ubuntu-arm64 ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: ubuntu-latest + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 7 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: ubuntu + build_configuration: ${{inputs.build_configuration}} + + - name: Test Mono + uses: uraimo/run-on-arch-action@v2.7.1 + id: build + with: + arch: aarch64 + distro: ubuntu22.04 + shell: /bin/bash + env: | + DOTNET_NOLOGO: ${{env.DOTNET_NOLOGO}} + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: ${{env.DOTNET_SKIP_FIRST_TIME_EXPERIENCE}} + DOTNET_CLI_TELEMETRY_OPTOUT: ${{env.DOTNET_CLI_TELEMETRY_OPTOUT}} + dockerRunArgs: | + --volume "${PWD}/src:/src" + install: | + apt-get update + apt-get install -y wget libc6 libgcc-s1 libgssapi-krb5-2 libicu70 liblttng-ust1 libssl3 libstdc++6 libunwind8 zlib1g mono-devel + + wget https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh; + chmod +x dotnet-install.sh; + ./dotnet-install.sh --channel LTS --no-path > /dev/null; + ./dotnet-install.sh --channel STS --no-path > /dev/null; + run: | + LD_LIBRARY_PATH="/usr/local/lib" /root/.dotnet/dotnet test "HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" -f ${{inputs.target_framework}} -l trx -l "console;verbosity=normal" --blame -- ${{inputs.run_settings_args}}; + + - name: Upload Test Result + uses: ./.github/actions/test-upload-result + if: ${{inputs.upload_tests}} + with: + os: ${{inputs.os}} + architecture: ${{inputs.architecture}} + runtime-type: mono + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-result-upload.yml b/.github/workflows/test-result-upload.yml new file mode 100644 index 00000000..f19ab847 --- /dev/null +++ b/.github/workflows/test-result-upload.yml @@ -0,0 +1,33 @@ +name: Template Testing Result Upload + +on: + workflow_call: + inputs: + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +jobs: + build-binaries: + name: Build Binaries + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Download Test Results + uses: actions/download-artifact@v4 + with: + pattern: ${{(inputs.experimental && 'experimental-') || ''}}test-results-* + path: test-results + + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + check_name: Test Results ${{(inputs.experimental && '(Experimental)') || ''}} + files: test-results/**/*.trx + fail_on: ${{(inputs.experimental && 'nothing') || 'test failures'}} + check_run: ${{!inputs.experimental}} + comment_mode: ${{(inputs.experimental && 'off') || 'always'}} diff --git a/.github/workflows/test-unix-dotnet.yml b/.github/workflows/test-unix-dotnet.yml new file mode 100644 index 00000000..af2b35bf --- /dev/null +++ b/.github/workflows/test-unix-dotnet.yml @@ -0,0 +1,75 @@ +name: Template Testing Unix .NET + +on: + workflow_call: + inputs: + os: + required: true + type: string + description: 'The operating system to use' + image: + required: true + type: string + description: 'The image to use' + architecture: + required: true + type: string + description: 'The architecture to use' + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + unix-net: + name: .NET ${{ inputs.os }}-${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: ${{inputs.image}} + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: ${{inputs.os}} + build_configuration: ${{inputs.build_configuration}} + + - name: Setup .NET Latest/${{inputs.target_framework}} ${{inputs.architecture}} + uses: ./.github/actions/test-setup-dotnet + with: + architecture: ${{inputs.architecture}} + target_framework: ${{inputs.target_framework}} + + - name: Test .NET ${{inputs.architecture}} + uses: ./.github/actions/test-execute-test + with: + os: ${{inputs.os}} + architecture: ${{inputs.architecture}} + runtime-type: dotnet + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + upload_tests: ${{inputs.upload_tests}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-unix-mono.yml b/.github/workflows/test-unix-mono.yml new file mode 100644 index 00000000..d9d00ac4 --- /dev/null +++ b/.github/workflows/test-unix-mono.yml @@ -0,0 +1,72 @@ +name: Template Testing Unix Mono + +on: + workflow_call: + inputs: + os: + required: true + type: string + description: 'The operating system to use' + image: + required: true + type: string + description: 'The image to use' + architecture: + required: true + type: string + description: 'The architecture to use' + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + unix-mono: + name: Mono ${{ inputs.os }}-${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: ${{inputs.image}} + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: ${{inputs.os}} + build_configuration: ${{inputs.build_configuration}} + + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + + - name: Test Mono ${{inputs.architecture}} + uses: ./.github/actions/test-execute-test + with: + os: ${{inputs.os}} + architecture: ${{inputs.architecture}} + runtime-type: mono + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + upload_tests: ${{inputs.upload_tests}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-dotnet.yml b/.github/workflows/test-windows-dotnet.yml new file mode 100644 index 00000000..40b8bbe3 --- /dev/null +++ b/.github/workflows/test-windows-dotnet.yml @@ -0,0 +1,67 @@ +name: Template Testing Windows .NET + +on: + workflow_call: + inputs: + architecture: + required: true + type: string + description: 'The architecture to use' + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + unix-net: + name: .NET ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: windows-latest + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: windows + build_configuration: ${{inputs.build_configuration}} + + - name: Setup .NET Latest/${{inputs.target_framework}} ${{inputs.architecture}} + uses: ./.github/actions/test-setup-dotnet-windows + with: + architecture: ${{inputs.architecture}} + target_framework: ${{inputs.target_framework}} + + - name: Test .NET ${{inputs.architecture}} + uses: ./.github/actions/test-execute-test + with: + os: windows + architecture: ${{inputs.architecture}} + runtime-type: dotnet + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + upload_tests: ${{inputs.upload_tests}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-framework.yml b/.github/workflows/test-windows-framework.yml new file mode 100644 index 00000000..a6408a72 --- /dev/null +++ b/.github/workflows/test-windows-framework.yml @@ -0,0 +1,61 @@ +name: Template Testing Windows .NET Framework + +on: + workflow_call: + inputs: + architecture: + required: true + type: string + description: 'The architecture to use' + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + windows-net-framework: + name: .NET FX ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: windows-2019 + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: windows + build_configuration: ${{inputs.build_configuration}} + + - name: Test Framework ${{inputs.architecture}} + uses: ./.github/actions/test-execute-test + with: + os: windows + architecture: ${{inputs.architecture}} + runtime-type: fx + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + upload_tests: ${{inputs.upload_tests}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-mono.yml b/.github/workflows/test-windows-mono.yml new file mode 100644 index 00000000..49b75b43 --- /dev/null +++ b/.github/workflows/test-windows-mono.yml @@ -0,0 +1,66 @@ +name: Template Testing Windows Mono + +on: + workflow_call: + inputs: + architecture: + required: true + type: string + description: 'The architecture to use' + target_framework: + required: true + type: string + description: 'The target framework to use' + build_configuration: + required: true + type: string + description: 'The build configuration to use' + upload_tests: + required: false + type: boolean + default: true + description: 'Whether to upload the test results' + experimental: + required: false + type: boolean + default: false + description: 'Whether the tests are mandatory for the build to pass' + +env: + # Disable the .NET logo in the console output. + DOTNET_NOLOGO: true + # Disable the .NET first time experience to skip caching NuGet packages and speed up the build. + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + # Disable sending .NET CLI telemetry to Microsoft. + DOTNET_CLI_TELEMETRY_OPTOUT: true + +jobs: + windows-mono: + name: Mono ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + runs-on: windows-latest + continue-on-error: ${{inputs.experimental}} + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + with: + os: windows + build_configuration: ${{inputs.build_configuration}} + + - name: Setup Mono ${{inputs.architecture}} + uses: ./.github/actions/test-setup-mono-windows + with: + architecture: ${{inputs.architecture}} + + - name: Test Mono ${{inputs.architecture}} + uses: ./.github/actions/test-execute-test + with: + os: windows + architecture: ${{inputs.architecture}} + runtime-type: mono + target_framework: ${{inputs.target_framework}} + build_configuration: ${{inputs.build_configuration}} + upload_tests: ${{inputs.upload_tests}} + experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..70e39dff --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,217 @@ +name: Perform Testing + +on: + push: + branches: + - master + paths-ignore: + - '.github/workflows/docs.yml' + - 'Harmony/Documentation/*' + pull_request: + branches: + - master + paths-ignore: + - '.github/workflows/docs.yml' + - 'Harmony/Documentation/*' + workflow_dispatch: + +env: + # You are interested in changing these values + BUILD_CONFIGURATIONS: "['ReleaseFat', 'ReleaseThin']" + DOTNET_TARGET_FRAMEWORKS: "['netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0']" + DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64: "['net6.0', 'net7.0', 'net8.0']" + FRAMEWORK_TARGET_FRAMEWORKS: "['net35', 'net452', 'net472', 'net48']" + +jobs: + + # https://stackoverflow.com/a/77549656 + variables: + name: Variable Accessibility Workaround for Jobs + runs-on: ubuntu-latest + outputs: + BUILD_CONFIGURATIONS: ${{ env.BUILD_CONFIGURATIONS }} + DOTNET_TARGET_FRAMEWORKS: ${{ env.DOTNET_TARGET_FRAMEWORKS }} + DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64: ${{ env.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64 }} + FRAMEWORK_TARGET_FRAMEWORKS: ${{ env.FRAMEWORK_TARGET_FRAMEWORKS }} + steps: + - name: Compute outputs + run: | + echo "BUILD_CONFIGURATIONS=${{env.BUILD_CONFIGURATIONS}}" >> $GITHUB_OUTPUT + echo "DOTNET_TARGET_FRAMEWORKS=${{env.DOTNET_TARGET_FRAMEWORKS}}" >> $GITHUB_OUTPUT + echo "DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64=${{env.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64}}" >> $GITHUB_OUTPUT + echo "FRAMEWORK_TARGET_FRAMEWORKS=${{env.FRAMEWORK_TARGET_FRAMEWORKS}}" >> $GITHUB_OUTPUT + + # Ideally we should be able to build binaries on Ubuntu to all platforms to test + # and have a job that will create binaries on each platform and compare the output dll's + build-binaries: + name: Build Binaries + needs: variables + strategy: + matrix: + image: [ { os: 'windows', code: 'windows-latest' }, { os: 'ubuntu', code: 'ubuntu-latest' }, { os: 'macos', code: 'macos-13' }, { os: 'macos-arm64', code: 'macos-14' } ] + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-build.yml + with: + os: ${{ matrix.image.os }} + image: ${{ matrix.image.code }} + build_configuration: ${{ matrix.build_configuration }} + publish: ${{ matrix.image.os == 'windows' }} + + windows-dotnet: + name: Windows .NET x86/x64 + needs: [variables, build-binaries] + strategy: + matrix: + architecture: ['x86', 'x64'] + target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS)}} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-windows-dotnet.yml + with: + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + + windows-framework: + name: Windows .NET Framework x86/x64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + architecture: ['x86', 'x64'] + target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-windows-framework.yml + with: + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + + windows-mono: + name: Windows Mono x86/x64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + architecture: ['x86', 'x64'] + target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-windows-mono.yml + with: + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + + ubuntu-macos-x64-dotnet: + name: Ubuntu/MacOS .NET x64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + image: [ { os: 'ubuntu', code: 'ubuntu-latest' }, { os: 'macos', code: 'macos-13' } ] + architecture: ['x64'] + target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS)}} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-unix-dotnet.yml + with: + os: ${{ matrix.image.os }} + image: ${{ matrix.image.code }} + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + + ubuntu-macos-x64-mono: + name: Ubuntu/MacOS Mono x64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + image: [ { os: 'ubuntu', code: 'ubuntu-latest' }, { os: 'macos', code: 'macos-13' } ] + architecture: ['x64'] + target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-unix-mono.yml + with: + os: ${{ matrix.image.os }} + image: ${{ matrix.image.code }} + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + + ubuntu-arm64-dotnet: + name: Ubuntu .NET arm64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) }} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-qemu-dotnet.yml + with: + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + run_settings_args: 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=arm64' + experimental: true + + ubuntu-arm64-mono: + name: Ubuntu .NET arm64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) }} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-qemu-mono.yml + with: + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + run_settings_args: 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=arm64' + experimental: true + + macos-arm64-dotnet: + name: MacOS .NET arm64 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + image: [ { os: 'macos-arm64', code: 'macos-14' } ] + architecture: ['arm64'] + target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) }} + build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} + uses: ./.github/workflows/test-unix-dotnet.yml + with: + os: ${{ matrix.image.os }} + image: ${{ matrix.image.code }} + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + build_configuration: ${{ matrix.build_configuration }} + experimental: true + + test-results: + name: Download and Upload Test Results + needs: [windows-dotnet, windows-framework, windows-mono, ubuntu-macos-x64-dotnet, ubuntu-macos-x64-mono, ubuntu-arm64-dotnet, ubuntu-arm64-mono, macos-arm64-dotnet] + if: always() + uses: ./.github/workflows/test-result-upload.yml + + test-results-experimental: + name: Download and Upload Test Results (Experimental) + needs: [windows-dotnet, windows-framework, windows-mono, ubuntu-macos-x64-dotnet, ubuntu-macos-x64-mono, ubuntu-arm64-dotnet, ubuntu-arm64-mono, macos-arm64-dotnet] + if: always() + uses: ./.github/workflows/test-result-upload.yml + with: + experimental: true + + cleanup-build-output: + name: Cleanup Build Output + needs: [test-results, test-results-experimental] + runs-on: ubuntu-latest + if: always() + steps: + - uses: joutvhu/delete-artifact@v2 + with: + pattern: build-output-* + - uses: joutvhu/delete-artifact@v2 + with: + pattern: test-results-* + - uses: joutvhu/delete-artifact@v2 + with: + pattern: experimental-test-results-* diff --git a/Harmony.sln b/Harmony.sln index a77c1df0..2083929a 100644 --- a/Harmony.sln +++ b/Harmony.sln @@ -31,6 +31,66 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Documentation", "Harmony\Do EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibrary", "TestLibrary\TestLibrary.csproj", "{11F828EC-7C50-48F4-A30D-9BED06837F3A}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{597B1581-64EA-4F8F-A703-17B642B05C94}" + ProjectSection(SolutionItems) = preProject + .github\workflows\test.yml = .github\workflows\test.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{71B8832A-3E69-4908-98FE-EE9680F5EF25}" + ProjectSection(SolutionItems) = preProject + .github\workflows\test-build.yml = .github\workflows\test-build.yml + .github\workflows\test-qemu-dotnet.yml = .github\workflows\test-qemu-dotnet.yml + .github\workflows\test-qemu-mono.yml = .github\workflows\test-qemu-mono.yml + .github\workflows\test-result-upload.yml = .github\workflows\test-result-upload.yml + .github\workflows\test-unix-dotnet.yml = .github\workflows\test-unix-dotnet.yml + .github\workflows\test-unix-mono.yml = .github\workflows\test-unix-mono.yml + .github\workflows\test-windows-dotnet.yml = .github\workflows\test-windows-dotnet.yml + .github\workflows\test-windows-framework.yml = .github\workflows\test-windows-framework.yml + .github\workflows\test-windows-mono.yml = .github\workflows\test-windows-mono.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "actions", "actions", "{9A886F28-B059-46CC-BE43-EA234CE1DD78}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-setup-mono-windows", "test-setup-mono-windows", "{FF253D20-5CFB-42A6-BC33-A0E213C3CF7E}" + ProjectSection(SolutionItems) = preProject + .github\actions\setup-mono-windows\action.yml = .github\actions\test-setup-mono-windows\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "get-program-files", "get-program-files", "{685B28DF-D62E-4A68-842D-C3E6D4CFB24B}" + ProjectSection(SolutionItems) = preProject + .github\actions\get-programfiles\action.yml = .github\actions\get-program-files\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-build-cache", "test-build-cache", "{BBEC08CE-1F26-46B3-9EC2-F1BC7B692A56}" + ProjectSection(SolutionItems) = preProject + .github\actions\setup-shared\action.yml = .github\actions\test-build-cache\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-setup-dotnet-windows", "test-setup-dotnet-windows", "{AE672D7F-D913-4CED-A6B3-A21001E5C8DF}" + ProjectSection(SolutionItems) = preProject + .github\actions\test-setup-dotnet-windows\action.yml = .github\actions\test-setup-dotnet-windows\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "get-dotnet-channel", "get-dotnet-channel", "{B0927B75-AE86-460B-9C42-6DED427304C6}" + ProjectSection(SolutionItems) = preProject + .github\actions\get-dotnet-channel\action.yml = .github\actions\get-dotnet-channel\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-upload-result", "test-upload-result", "{145A597F-00D3-42D0-930D-85EF1257FA6D}" + ProjectSection(SolutionItems) = preProject + .github\actions\test-upload-result\action.yml = .github\actions\test-upload-result\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-execute-test", "test-execute-test", "{E625C76C-C4AA-43A9-AFB5-BD1D605A4F48}" + ProjectSection(SolutionItems) = preProject + .github\actions\test-execute-test\action.yml = .github\actions\test-execute-test\action.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-setup-dotnet", "test-setup-dotnet", "{15C84537-CCEF-43F5-B556-34369D7B320D}" + ProjectSection(SolutionItems) = preProject + .github\actions\test-setup-dotnet\action.yml = .github\actions\test-setup-dotnet\action.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution DebugFat|Any CPU = DebugFat|Any CPU @@ -78,4 +138,17 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {61622750-C658-496F-B2E2-75D94AF6CF8B} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {597B1581-64EA-4F8F-A703-17B642B05C94} = {887FC7DA-9A29-4130-92E7-66E21E76CAC4} + {71B8832A-3E69-4908-98FE-EE9680F5EF25} = {597B1581-64EA-4F8F-A703-17B642B05C94} + {9A886F28-B059-46CC-BE43-EA234CE1DD78} = {887FC7DA-9A29-4130-92E7-66E21E76CAC4} + {FF253D20-5CFB-42A6-BC33-A0E213C3CF7E} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {685B28DF-D62E-4A68-842D-C3E6D4CFB24B} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {BBEC08CE-1F26-46B3-9EC2-F1BC7B692A56} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {AE672D7F-D913-4CED-A6B3-A21001E5C8DF} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {B0927B75-AE86-460B-9C42-6DED427304C6} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {145A597F-00D3-42D0-930D-85EF1257FA6D} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {E625C76C-C4AA-43A9-AFB5-BD1D605A4F48} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + {15C84537-CCEF-43F5-B556-34369D7B320D} = {9A886F28-B059-46CC-BE43-EA234CE1DD78} + EndGlobalSection EndGlobal From d94bce611455652ed135bf866d67112fdbac84e0 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Mon, 12 Feb 2024 00:04:21 +0200 Subject: [PATCH 2/7] Disabled potential failed annotations --- .github/workflows/test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 70e39dff..8db3d4ea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -140,6 +140,7 @@ jobs: ubuntu-arm64-dotnet: name: Ubuntu .NET arm64 needs: [variables, build-binaries] + if: false # TODO: Enable once we are able to ignore a failed job strategy: fail-fast: false matrix: @@ -155,6 +156,7 @@ jobs: ubuntu-arm64-mono: name: Ubuntu .NET arm64 needs: [variables, build-binaries] + if: false # TODO: Enable once we are able to ignore a failed job strategy: fail-fast: false matrix: @@ -170,6 +172,7 @@ jobs: macos-arm64-dotnet: name: MacOS .NET arm64 needs: [variables, build-binaries] + if: false # TODO: Enable once we are able to ignore a failed job strategy: fail-fast: false matrix: @@ -195,7 +198,7 @@ jobs: test-results-experimental: name: Download and Upload Test Results (Experimental) needs: [windows-dotnet, windows-framework, windows-mono, ubuntu-macos-x64-dotnet, ubuntu-macos-x64-mono, ubuntu-arm64-dotnet, ubuntu-arm64-mono, macos-arm64-dotnet] - if: always() + if: false && always() # TODO: Enable once we are able to ignore a failed job uses: ./.github/workflows/test-result-upload.yml with: experimental: true @@ -213,5 +216,6 @@ jobs: with: pattern: test-results-* - uses: joutvhu/delete-artifact@v2 + if: false # TODO: Enable once we are able to ignore a failed job with: pattern: experimental-test-results-* From 6b01022ddddf50b4bc22b40f3b37b068c6b50b43 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Tue, 13 Feb 2024 00:09:28 +0200 Subject: [PATCH 3/7] Added non parallel variant without prebuild --- .github/actions/get-dotnet-channel/action.yml | 35 ++++- .github/actions/test-execute-test/action.yml | 93 +++++++++++-- .../test-setup-dotnet-windows/action.yml | 17 ++- .github/actions/test-setup-dotnet/action.yml | 14 +- .github/actions/test-upload-result/action.yml | 2 +- .github/workflows/test-build.yml | 7 + .github/workflows/test-qemu-dotnet.yml | 2 +- .github/workflows/test-qemu-mono.yml | 2 +- .github/workflows/test-result-upload.yml | 1 + .github/workflows/test-unix-dotnet.yml | 29 ++-- .github/workflows/test-unix-mono.yml | 20 ++- .github/workflows/test-windows-dotnet.yml | 27 +++- .github/workflows/test-windows-framework.yml | 17 ++- .github/workflows/test-windows-mono.yml | 17 ++- .github/workflows/test.yml | 125 ++++++++++++------ 15 files changed, 314 insertions(+), 94 deletions(-) diff --git a/.github/actions/get-dotnet-channel/action.yml b/.github/actions/get-dotnet-channel/action.yml index 2329b771..8667a16e 100644 --- a/.github/actions/get-dotnet-channel/action.yml +++ b/.github/actions/get-dotnet-channel/action.yml @@ -1,22 +1,43 @@ name: Convert Target Framework to Channel -description: Convert Target Framework to Channel +description: | + Convert Target Framework to Channel. + Use `target_framework` for a single conversion with `channel` as output. + Use `target_framework_array` for a single conversion with `channels_multiline` as output. inputs: target_framework: description: 'The target framework to use' - required: true + required: false + target_framework_array: + description: 'The target framework array to use' + required: false outputs: channel: description: 'The converted Channel variable' - value: ${{ steps.set_channel.outputs.channel }} + value: ${{steps.set_output.outputs.channel}} + channels_multiline: + description: 'The converted Channels multiline variable' + value: ${{steps.set_output.outputs.channels_multiline}} runs: using: "composite" steps: - - name: Set Channel - id: set_channel + - name: Set Channels + id: set_output run: | - $channel = '${{inputs.target_framework}}'.Replace('coreapp', '').Replace('net', ''); - "channel=$channel" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + $channel = $target_framework.Replace('coreapp', '').Replace('net', ''); + "channel=$channel" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + } + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + $EOF = -join (1..15 | ForEach {[char]((48..57)+(65..90)+(97..122) | Get-Random)}); + "channels_multiline<<$EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + foreach ($target_framework in ConvertFrom-Json "${{inputs.target_framework_array}}") { + $target_framework.Replace('coreapp', '').Replace('net', '') | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + } + "$EOF" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + } shell: pwsh diff --git a/.github/actions/test-execute-test/action.yml b/.github/actions/test-execute-test/action.yml index 5f8f253a..89c6ddfa 100644 --- a/.github/actions/test-execute-test/action.yml +++ b/.github/actions/test-execute-test/action.yml @@ -1,5 +1,7 @@ name: Test Execute Test -description: Executes the tests +description: | + Execute the tests for the specified operating system, architecture, runtime type, target framework, and build configuration. + You can use `target_framework` for a single test or `target_framework_array` for multiple tests. inputs: os: @@ -14,9 +16,15 @@ inputs: target_framework: description: 'The target framework to use' required: true + target_framework_array: + description: 'The target frameworks to use' + required: true build_configuration: description: 'The build configuration to use' required: true + manual_build: + description: 'Whether to build manually before running the tests' + required: true upload_tests: description: 'Whether to upload the test results' required: true @@ -27,33 +35,60 @@ inputs: runs: using: "composite" steps: + - name: Get Program Files path for ${{inputs.architecture}} + uses: ./.github/actions/get-program-files + id: get-program-files + with: + architecture: ${{inputs.architecture}} + - name: Set Test Args id: test-args run: | - $run_settings_args = 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=${{inputs.architecture}}' + $run_settings_args = 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=${{inputs.architecture}}'; "run_settings_args=$run_settings_args" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; - $vstest = '"HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" --framework:${{inputs.target_framework}} --logger:trx --logger:"console;verbosity=normal" --blame'; + $vstest = "--logger:trx --logger:'console;verbosity=normal' --blame"; "vstest=$vstest" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; - $dotnet = '"HarmonyTests/bin/Release/${{inputs.target_framework}}/HarmonyTests.dll" -f ${{inputs.target_framework}} -l trx -l "console;verbosity=normal" --blame'; + $dotnet = "-l trx -l 'console;verbosity=normal' --blame"; "dotnet=$dotnet" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; shell: pwsh - - name: Get Program Files path for ${{inputs.architecture}} - uses: ./.github/actions/get-program-files - id: get-program-files - with: - architecture: ${{inputs.architecture}} + - name: Build if required + if: ${{inputs.manual_build == 'true'}} + run: | + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + dotnet build Harmony.sln -c ${{inputs.build_configuration}} -f $target_framework; + } + + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + foreach ($target_framework in ConvertFrom-Json $target_frameworks) { + dotnet build Harmony.sln -c ${{inputs.build_configuration}} -f $target_framework; + } + } + shell: pwsh - name: Perform Tests Windows Mono if: ${{inputs.os == 'windows' && inputs.runtime-type == 'mono'}} run: | + $mono = "${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe"; + $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - $mono = "${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe"; - & "$mono" "$vstest" ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + foreach ($target_framework in ConvertFrom-Json $target_frameworks) { + & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + } shell: pwsh - name: Perform Tests Windows FX @@ -62,19 +97,49 @@ runs: $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - & "$vstest" ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + foreach ($target_framework in ConvertFrom-Json $target_frameworks) { + & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + } shell: pwsh - name: Perform Tests Windows .NET if: ${{inputs.os == 'windows' && inputs.runtime-type == 'dotnet'}} run: | - dotnet test ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + foreach ($target_framework in ConvertFrom-Json $target_frameworks) { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + } shell: pwsh - name: Perform Tests Ubuntu/MacOS/MacOS-arm64 .NET/Mono if: ${{inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} run: | - dotnet test ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + $target_framework = "${{inputs.target_framework}}"; + if ($target_framework -ne '') { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -ne '') { + foreach ($target_framework in ConvertFrom-Json $target_frameworks) { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + } + } shell: pwsh - name: Upload Test Result diff --git a/.github/actions/test-setup-dotnet-windows/action.yml b/.github/actions/test-setup-dotnet-windows/action.yml index fd4e1ef0..10b3b6c0 100644 --- a/.github/actions/test-setup-dotnet-windows/action.yml +++ b/.github/actions/test-setup-dotnet-windows/action.yml @@ -8,6 +8,9 @@ inputs: target_framework: description: 'The .NET target framework to setup' required: true + target_framework_array: + description: 'The .NET target frameworks to setup' + required: true runs: using: "composite" @@ -17,6 +20,7 @@ runs: id: get_channel with: target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} - name: Get Program Files path for ${{inputs.architecture}} uses: ./.github/actions/get-program-files @@ -29,5 +33,16 @@ runs: Invoke-WebRequest 'https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1; .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel LTS -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel STS -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; - .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel ${{steps.get_channel.outputs.channel}} -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + + $channel = "${{steps.get_channel.outputs.channel}}"; + if ($channel -ne '') { + .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel $channel -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + } + + $channels = "${{steps.get_channel.outputs.channels_multiline}}"; + if ($channels -ne '') { + foreach ($channel in ($channels -split "[\r\n]+")) { + .\dotnet-install.ps1 -Runtime dotnet -SkipNonVersionedFiles -NoPath -Channel $channel -Architecture ${{inputs.architecture}} -InstallDir "${{steps.get-program-files.outputs.path}}/dotnet"; + } + } shell: pwsh diff --git a/.github/actions/test-setup-dotnet/action.yml b/.github/actions/test-setup-dotnet/action.yml index 4c0deb1b..667b19cb 100644 --- a/.github/actions/test-setup-dotnet/action.yml +++ b/.github/actions/test-setup-dotnet/action.yml @@ -8,6 +8,9 @@ inputs: target_framework: description: 'The .NET target framework to setup' required: true + target_framework_array: + description: 'The .NET target frameworks to setup' + required: true runs: using: "composite" @@ -15,13 +18,16 @@ runs: - name: Setup .NET Sdk uses: actions/setup-dotnet@v4 - - name: Get .NET Channel for ${{inputs.target_framework}} + - name: Get .NET Channels uses: ./.github/actions/get-dotnet-channel - id: get_channel + id: get_channels with: target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} - - name: Setup .NET ${{steps.get_channel.outputs.channel}} + - name: Setup .NET ${{steps.get_channels.outputs.channels_multiline}} uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{steps.get_channel.outputs.channel}} + dotnet-version: | + ${{steps.get_channels.outputs.channel}} + ${{steps.get_channels.outputs.channels_multiline}} diff --git a/.github/actions/test-upload-result/action.yml b/.github/actions/test-upload-result/action.yml index f51f68ea..4e8d6ca8 100644 --- a/.github/actions/test-upload-result/action.yml +++ b/.github/actions/test-upload-result/action.yml @@ -13,7 +13,7 @@ inputs: required: true target_framework: description: 'The target framework to use' - required: true + required: false build_configuration: description: 'The build configuration to use' required: true diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index c21d7251..0542a471 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -17,6 +17,11 @@ on: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + description: 'Whether to do the build' + default: true publish: required: true type: boolean @@ -34,6 +39,8 @@ jobs: build-output-cache: name: Upload Test Build Output Cache runs-on: ${{inputs.image}} + if: ${{!inputs.manual_build || inputs.publish}} + timeout-minutes: 8 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-qemu-dotnet.yml b/.github/workflows/test-qemu-dotnet.yml index a1d3c302..023f0890 100644 --- a/.github/workflows/test-qemu-dotnet.yml +++ b/.github/workflows/test-qemu-dotnet.yml @@ -39,7 +39,7 @@ jobs: name: .NET ubuntu-arm64 ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: ubuntu-latest continue-on-error: ${{inputs.experimental}} - timeout-minutes: 7 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-qemu-mono.yml b/.github/workflows/test-qemu-mono.yml index 6a68cc13..83c5e51f 100644 --- a/.github/workflows/test-qemu-mono.yml +++ b/.github/workflows/test-qemu-mono.yml @@ -39,7 +39,7 @@ jobs: name: Mono ubuntu-arm64 ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: ubuntu-latest continue-on-error: ${{inputs.experimental}} - timeout-minutes: 7 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-result-upload.yml b/.github/workflows/test-result-upload.yml index f19ab847..5843f4ea 100644 --- a/.github/workflows/test-result-upload.yml +++ b/.github/workflows/test-result-upload.yml @@ -13,6 +13,7 @@ jobs: build-binaries: name: Build Binaries runs-on: ubuntu-latest + timeout-minutes: 5 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-unix-dotnet.yml b/.github/workflows/test-unix-dotnet.yml index af2b35bf..d98adce3 100644 --- a/.github/workflows/test-unix-dotnet.yml +++ b/.github/workflows/test-unix-dotnet.yml @@ -19,10 +19,19 @@ on: required: true type: string description: 'The target framework to use' + target_framework_array: + required: true + type: string + description: 'The target frameworks to use' build_configuration: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + default: true + description: 'Whether to build manually before running the tests' upload_tests: required: false type: boolean @@ -44,25 +53,27 @@ env: jobs: unix-net: - name: .NET ${{ inputs.os }}-${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} + name: .NET ${{inputs.os}}-${{inputs.architecture}} ${{ inputs.target_framework }} ${{inputs.build_configuration}} runs-on: ${{inputs.image}} continue-on-error: ${{inputs.experimental}} - timeout-minutes: 5 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 + - name: Setup .NET ${{inputs.architecture}} + uses: ./.github/actions/test-setup-dotnet + with: + architecture: ${{inputs.architecture}} + target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} + - name: Download Build Cache uses: ./.github/actions/test-build-cache + if: ${{!inputs.manual_build}} with: os: ${{inputs.os}} build_configuration: ${{inputs.build_configuration}} - - name: Setup .NET Latest/${{inputs.target_framework}} ${{inputs.architecture}} - uses: ./.github/actions/test-setup-dotnet - with: - architecture: ${{inputs.architecture}} - target_framework: ${{inputs.target_framework}} - - name: Test .NET ${{inputs.architecture}} uses: ./.github/actions/test-execute-test with: @@ -70,6 +81,8 @@ jobs: architecture: ${{inputs.architecture}} runtime-type: dotnet target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} build_configuration: ${{inputs.build_configuration}} + manual_build: ${{inputs.manual_build}} upload_tests: ${{inputs.upload_tests}} experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-unix-mono.yml b/.github/workflows/test-unix-mono.yml index d9d00ac4..701321ec 100644 --- a/.github/workflows/test-unix-mono.yml +++ b/.github/workflows/test-unix-mono.yml @@ -19,10 +19,19 @@ on: required: true type: string description: 'The target framework to use' + target_framework_array: + required: true + type: string + description: 'The target frameworks to use' build_configuration: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + default: true + description: 'Whether to build manually before running the tests' upload_tests: required: false type: boolean @@ -47,19 +56,20 @@ jobs: name: Mono ${{ inputs.os }}-${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: ${{inputs.image}} continue-on-error: ${{inputs.experimental}} - timeout-minutes: 5 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + - name: Download Build Cache uses: ./.github/actions/test-build-cache + if: ${{!inputs.manual_build}} with: os: ${{inputs.os}} build_configuration: ${{inputs.build_configuration}} - - name: Setup .NET Sdk - uses: actions/setup-dotnet@v4 - - name: Test Mono ${{inputs.architecture}} uses: ./.github/actions/test-execute-test with: @@ -67,6 +77,8 @@ jobs: architecture: ${{inputs.architecture}} runtime-type: mono target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} build_configuration: ${{inputs.build_configuration}} + manual_build: ${{inputs.manual_build}} upload_tests: ${{inputs.upload_tests}} experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-dotnet.yml b/.github/workflows/test-windows-dotnet.yml index 40b8bbe3..87c43af8 100644 --- a/.github/workflows/test-windows-dotnet.yml +++ b/.github/workflows/test-windows-dotnet.yml @@ -11,10 +11,19 @@ on: required: true type: string description: 'The target framework to use' + target_framework_array: + required: true + type: string + description: 'The target frameworks to use' build_configuration: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + default: true + description: 'Whether to build manually before running the tests' upload_tests: required: false type: boolean @@ -39,21 +48,23 @@ jobs: name: .NET ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: windows-latest continue-on-error: ${{inputs.experimental}} - timeout-minutes: 5 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 - - name: Download Build Cache - uses: ./.github/actions/test-build-cache - with: - os: windows - build_configuration: ${{inputs.build_configuration}} - - name: Setup .NET Latest/${{inputs.target_framework}} ${{inputs.architecture}} uses: ./.github/actions/test-setup-dotnet-windows with: architecture: ${{inputs.architecture}} target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} + + - name: Download Build Cache + uses: ./.github/actions/test-build-cache + if: ${{!inputs.manual_build}} + with: + os: windows + build_configuration: ${{inputs.build_configuration}} - name: Test .NET ${{inputs.architecture}} uses: ./.github/actions/test-execute-test @@ -62,6 +73,8 @@ jobs: architecture: ${{inputs.architecture}} runtime-type: dotnet target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} build_configuration: ${{inputs.build_configuration}} + manual_build: ${{inputs.manual_build}} upload_tests: ${{inputs.upload_tests}} experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-framework.yml b/.github/workflows/test-windows-framework.yml index a6408a72..52fbbab2 100644 --- a/.github/workflows/test-windows-framework.yml +++ b/.github/workflows/test-windows-framework.yml @@ -11,10 +11,19 @@ on: required: true type: string description: 'The target framework to use' + target_framework_array: + required: true + type: string + description: 'The target frameworks to use' build_configuration: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + default: true + description: 'Whether to build manually before running the tests' upload_tests: required: false type: boolean @@ -39,12 +48,16 @@ jobs: name: .NET FX ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: windows-2019 continue-on-error: ${{inputs.experimental}} - timeout-minutes: 5 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + - name: Download Build Cache uses: ./.github/actions/test-build-cache + if: ${{!inputs.manual_build}} with: os: windows build_configuration: ${{inputs.build_configuration}} @@ -56,6 +69,8 @@ jobs: architecture: ${{inputs.architecture}} runtime-type: fx target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} build_configuration: ${{inputs.build_configuration}} + manual_build: ${{inputs.manual_build}} upload_tests: ${{inputs.upload_tests}} experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test-windows-mono.yml b/.github/workflows/test-windows-mono.yml index 49b75b43..0e6a247d 100644 --- a/.github/workflows/test-windows-mono.yml +++ b/.github/workflows/test-windows-mono.yml @@ -11,10 +11,19 @@ on: required: true type: string description: 'The target framework to use' + target_framework_array: + required: true + type: string + description: 'The target frameworks to use' build_configuration: required: true type: string description: 'The build configuration to use' + manual_build: + required: false + type: boolean + default: true + description: 'Whether to build manually before running the tests' upload_tests: required: false type: boolean @@ -39,12 +48,16 @@ jobs: name: Mono ${{ inputs.architecture }} ${{ inputs.target_framework }} ${{ inputs.build_configuration }} runs-on: windows-latest continue-on-error: ${{inputs.experimental}} - timeout-minutes: 5 + timeout-minutes: 8 steps: - uses: actions/checkout@v4 + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + - name: Download Build Cache uses: ./.github/actions/test-build-cache + if: ${{!inputs.manual_build}} with: os: windows build_configuration: ${{inputs.build_configuration}} @@ -61,6 +74,8 @@ jobs: architecture: ${{inputs.architecture}} runtime-type: mono target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} build_configuration: ${{inputs.build_configuration}} + manual_build: ${{inputs.manual_build}} upload_tests: ${{inputs.upload_tests}} experimental: ${{inputs.experimental}} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8db3d4ea..b5a5a1da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,20 @@ on: workflow_dispatch: env: + # Right now we can't run experimental tests that can fail, since it will affect the PR + # We could potentially exclude experimental build on PR and only run it on master push + EXPERIMENTAL: false + # If set true, each target framework will be tested in it's own job instead of a single job + # NOTE: At some point when we'll have more target frameworks, parallelization should be more efficient + # It also will be more efficient once the `windows` workers will have a faster startup time + # METRICS: + # PARALLEL: true & PREBUILD: true ~ 15 minutes + # PARALLEL: false ~ 7 minutes + PARALLEL: false + # Whether we should build the binaries before running the tests + # Use with `PARALLEL: true` to reduce the execution time of test jobs, this increasing the throughput + PREBUILD: false + # You are interested in changing these values BUILD_CONFIGURATIONS: "['ReleaseFat', 'ReleaseThin']" DOTNET_TARGET_FRAMEWORKS: "['netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0']" @@ -29,13 +43,19 @@ jobs: name: Variable Accessibility Workaround for Jobs runs-on: ubuntu-latest outputs: - BUILD_CONFIGURATIONS: ${{ env.BUILD_CONFIGURATIONS }} - DOTNET_TARGET_FRAMEWORKS: ${{ env.DOTNET_TARGET_FRAMEWORKS }} - DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64: ${{ env.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64 }} - FRAMEWORK_TARGET_FRAMEWORKS: ${{ env.FRAMEWORK_TARGET_FRAMEWORKS }} + EXPERIMENTAL: ${{env.EXPERIMENTAL}} + PARALLEL: ${{env.PARALLEL}} + PREBUILD: ${{env.PREBUILD}} + BUILD_CONFIGURATIONS: ${{env.BUILD_CONFIGURATIONS}} + DOTNET_TARGET_FRAMEWORKS: ${{env.DOTNET_TARGET_FRAMEWORKS}} + DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64: ${{env.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64}} + FRAMEWORK_TARGET_FRAMEWORKS: ${{env.FRAMEWORK_TARGET_FRAMEWORKS}} steps: - name: Compute outputs run: | + echo "EXPERIMENTAL=${{env.EXPERIMENTAL}}" >> $GITHUB_OUTPUT + echo "PARALLEL=${{env.PARALLEL}}" >> $GITHUB_OUTPUT + echo "PREBUILD=${{env.PREBUILD}}" >> $GITHUB_OUTPUT echo "BUILD_CONFIGURATIONS=${{env.BUILD_CONFIGURATIONS}}" >> $GITHUB_OUTPUT echo "DOTNET_TARGET_FRAMEWORKS=${{env.DOTNET_TARGET_FRAMEWORKS}}" >> $GITHUB_OUTPUT echo "DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64=${{env.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64}}" >> $GITHUB_OUTPUT @@ -52,10 +72,11 @@ jobs: build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-build.yml with: - os: ${{ matrix.image.os }} - image: ${{ matrix.image.code }} - build_configuration: ${{ matrix.build_configuration }} - publish: ${{ matrix.image.os == 'windows' }} + os: ${{matrix.image.os}} + image: ${{matrix.image.code}} + build_configuration: ${{matrix.build_configuration}} + publish: ${{matrix.image.os == 'windows'}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} windows-dotnet: name: Windows .NET x86/x64 @@ -63,13 +84,15 @@ jobs: strategy: matrix: architecture: ['x86', 'x64'] - target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS)}} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-windows-dotnet.yml with: - architecture: ${{ matrix.architecture }} - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + architecture: ${{matrix.architecture}} + target_framework: ${{matrix.target_framework}} + target_framework_array: ${{needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} windows-framework: name: Windows .NET Framework x86/x64 @@ -78,13 +101,15 @@ jobs: fail-fast: false matrix: architecture: ['x86', 'x64'] - target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-windows-framework.yml with: - architecture: ${{ matrix.architecture }} - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + architecture: ${{matrix.architecture}} + target_framework: ${{matrix.target_framework}} + target_framework_array: ${{needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} windows-mono: name: Windows Mono x86/x64 @@ -93,13 +118,15 @@ jobs: fail-fast: false matrix: architecture: ['x86', 'x64'] - target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-windows-mono.yml with: - architecture: ${{ matrix.architecture }} - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + architecture: ${{matrix.architecture}} + target_framework: ${{matrix.target_framework}} + target_framework_array: ${{needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} ubuntu-macos-x64-dotnet: name: Ubuntu/MacOS .NET x64 @@ -109,15 +136,17 @@ jobs: matrix: image: [ { os: 'ubuntu', code: 'ubuntu-latest' }, { os: 'macos', code: 'macos-13' } ] architecture: ['x64'] - target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS)}} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-unix-dotnet.yml with: - os: ${{ matrix.image.os }} - image: ${{ matrix.image.code }} - architecture: ${{ matrix.architecture }} - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + os: ${{matrix.image.os}} + image: ${{matrix.image.code}} + architecture: ${{matrix.architecture}} + target_framework: ${{matrix.target_framework }} + target_framework_array: ${{needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} ubuntu-macos-x64-mono: name: Ubuntu/MacOS Mono x64 @@ -127,58 +156,64 @@ jobs: matrix: image: [ { os: 'ubuntu', code: 'ubuntu-latest' }, { os: 'macos', code: 'macos-13' } ] architecture: ['x64'] - target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-unix-mono.yml with: - os: ${{ matrix.image.os }} - image: ${{ matrix.image.code }} - architecture: ${{ matrix.architecture }} - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + os: ${{matrix.image.os}} + image: ${{matrix.image.code}} + architecture: ${{matrix.architecture}} + target_framework: ${{matrix.target_framework}} + target_framework_array: ${{needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} ubuntu-arm64-dotnet: name: Ubuntu .NET arm64 needs: [variables, build-binaries] - if: false # TODO: Enable once we are able to ignore a failed job + if: ${{needs.variables.outputs.EXPERIMENTAL == 'true'}} strategy: fail-fast: false matrix: - target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) }} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-qemu-dotnet.yml with: - target_framework: ${{ matrix.target_framework }} + target_framework: ${{matrix.target_framework}} + #target_framework_array: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64)}} build_configuration: ${{ matrix.build_configuration }} run_settings_args: 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=arm64' + #manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} experimental: true ubuntu-arm64-mono: name: Ubuntu .NET arm64 needs: [variables, build-binaries] - if: false # TODO: Enable once we are able to ignore a failed job + if: ${{needs.variables.outputs.EXPERIMENTAL == 'true'}} strategy: fail-fast: false matrix: - target_framework: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) }} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-qemu-mono.yml with: - target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + target_framework: ${{matrix.target_framework}} + #target_framework_array: ${{fromJson(needs.variables.outputs.FRAMEWORK_TARGET_FRAMEWORKS)}} + build_configuration: ${{matrix.build_configuration}} run_settings_args: 'NUnit.DefaultTestNamePattern="{C}:{m}{a}" RunConfiguration.TargetPlatform=arm64' + #manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} experimental: true macos-arm64-dotnet: name: MacOS .NET arm64 needs: [variables, build-binaries] - if: false # TODO: Enable once we are able to ignore a failed job + if: ${{needs.variables.outputs.EXPERIMENTAL == 'true'}} strategy: fail-fast: false matrix: image: [ { os: 'macos-arm64', code: 'macos-14' } ] architecture: ['arm64'] - target_framework: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) }} + target_framework: ${{fromJson((needs.variables.outputs.PARALLEL == 'true' && needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64) || '[""]')}} build_configuration: ${{fromJson(needs.variables.outputs.BUILD_CONFIGURATIONS)}} uses: ./.github/workflows/test-unix-dotnet.yml with: @@ -186,7 +221,9 @@ jobs: image: ${{ matrix.image.code }} architecture: ${{ matrix.architecture }} target_framework: ${{ matrix.target_framework }} - build_configuration: ${{ matrix.build_configuration }} + target_framework_array: ${{fromJson(needs.variables.outputs.DOTNET_TARGET_FRAMEWORKS_MACOS_ARM64)}} + build_configuration: ${{matrix.build_configuration}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} experimental: true test-results: @@ -198,7 +235,7 @@ jobs: test-results-experimental: name: Download and Upload Test Results (Experimental) needs: [windows-dotnet, windows-framework, windows-mono, ubuntu-macos-x64-dotnet, ubuntu-macos-x64-mono, ubuntu-arm64-dotnet, ubuntu-arm64-mono, macos-arm64-dotnet] - if: false && always() # TODO: Enable once we are able to ignore a failed job + if: ${{needs.variables.outputs.EXPERIMENTAL == 'true' && always()}} uses: ./.github/workflows/test-result-upload.yml with: experimental: true @@ -216,6 +253,6 @@ jobs: with: pattern: test-results-* - uses: joutvhu/delete-artifact@v2 - if: false # TODO: Enable once we are able to ignore a failed job + if: ${{needs.variables.outputs.PARALLEL == 'true'}} with: pattern: experimental-test-results-* From a2ab69916ed2a89e602879e38c09968e6f78e149 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Tue, 13 Feb 2024 17:21:52 +0200 Subject: [PATCH 4/7] Simplified expressions --- .github/actions/test-execute-test/action.yml | 68 ++++++-------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/.github/actions/test-execute-test/action.yml b/.github/actions/test-execute-test/action.yml index 89c6ddfa..7f14b31d 100644 --- a/.github/actions/test-execute-test/action.yml +++ b/.github/actions/test-execute-test/action.yml @@ -52,22 +52,21 @@ runs: $dotnet = "-l trx -l 'console;verbosity=normal' --blame"; "dotnet=$dotnet" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + + $target_framework = "${{inputs.target_framework}}"; + $target_frameworks = "${{inputs.target_framework_array}}"; + if ($target_frameworks -eq '') { + $target_frameworks = "['$target_framework']"; + } + "target_frameworks=$target_frameworks" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; shell: pwsh - name: Build if required if: ${{inputs.manual_build == 'true'}} run: | - $target_framework = "${{inputs.target_framework}}"; - if ($target_framework -ne '') { + foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { dotnet build Harmony.sln -c ${{inputs.build_configuration}} -f $target_framework; } - - $target_frameworks = "${{inputs.target_framework_array}}"; - if ($target_frameworks -ne '') { - foreach ($target_framework in ConvertFrom-Json $target_frameworks) { - dotnet build Harmony.sln -c ${{inputs.build_configuration}} -f $target_framework; - } - } shell: pwsh - name: Perform Tests Windows Mono @@ -77,17 +76,9 @@ runs: $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - - $target_framework = "${{inputs.target_framework}}"; - if ($target_framework -ne '') { - & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - - $target_frameworks = "${{inputs.target_framework_array}}"; - if ($target_frameworks -ne '') { - foreach ($target_framework in ConvertFrom-Json $target_frameworks) { - & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } + + foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh @@ -96,49 +87,26 @@ runs: run: | $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - - $target_framework = "${{inputs.target_framework}}"; - if ($target_framework -ne '') { - & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - - $target_frameworks = "${{inputs.target_framework_array}}"; - if ($target_frameworks -ne '') { - foreach ($target_framework in ConvertFrom-Json $target_frameworks) { - & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } + + foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh - name: Perform Tests Windows .NET if: ${{inputs.os == 'windows' && inputs.runtime-type == 'dotnet'}} run: | - $target_framework = "${{inputs.target_framework}}"; - if ($target_framework -ne '') { - dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - - $target_frameworks = "${{inputs.target_framework_array}}"; - if ($target_frameworks -ne '') { - foreach ($target_framework in ConvertFrom-Json $target_frameworks) { - dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; - } + foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh - name: Perform Tests Ubuntu/MacOS/MacOS-arm64 .NET/Mono if: ${{inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} run: | - $target_framework = "${{inputs.target_framework}}"; - if ($target_framework -ne '') { - dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - - $target_frameworks = "${{inputs.target_framework_array}}"; if ($target_frameworks -ne '') { - foreach ($target_framework in ConvertFrom-Json $target_frameworks) { - dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; - } + foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh From 668a5d216f94e50c53359b18e5b3ab7e2ad08276 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Tue, 13 Feb 2024 17:26:48 +0200 Subject: [PATCH 5/7] Combined tests, build binaries on ubuntu for faster completion --- .github/actions/test-execute-test/action.yml | 32 ++++---------------- .github/workflows/test.yml | 2 +- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/.github/actions/test-execute-test/action.yml b/.github/actions/test-execute-test/action.yml index 7f14b31d..eb1e025b 100644 --- a/.github/actions/test-execute-test/action.yml +++ b/.github/actions/test-execute-test/action.yml @@ -69,42 +69,22 @@ runs: } shell: pwsh - - name: Perform Tests Windows Mono - if: ${{inputs.os == 'windows' && inputs.runtime-type == 'mono'}} - run: | - $mono = "${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe"; - - $vspath = vswhere -latest -property installationPath; - $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - - foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { - & "$mono" "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - shell: pwsh - - - name: Perform Tests Windows FX + - name: Perform Tests Windows FX/Mono if: ${{inputs.os == 'windows' && inputs.runtime-type == 'fx'}} run: | + $mono = "${{steps.get-program-files.outputs.path}}/Mono/bin/mono.exe"; + $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { - & "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; - } - shell: pwsh - - - name: Perform Tests Windows .NET - if: ${{inputs.os == 'windows' && inputs.runtime-type == 'dotnet'}} - run: | - foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { - dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; + & ${{(inputs.runtime-type == 'mono' && '"$mono"') || ''}} "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh - - name: Perform Tests Ubuntu/MacOS/MacOS-arm64 .NET/Mono - if: ${{inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} + - name: Perform Tests Windows .NET | Ubuntu/MacOS/MacOS-arm64 .NET/Mono + if: ${{(inputs.os == 'windows' && inputs.runtime-type == 'dotnet') || inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} run: | - if ($target_frameworks -ne '') { foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; } diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b5a5a1da..599bcc22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -75,7 +75,7 @@ jobs: os: ${{matrix.image.os}} image: ${{matrix.image.code}} build_configuration: ${{matrix.build_configuration}} - publish: ${{matrix.image.os == 'windows'}} + publish: ${{matrix.image.os == 'ubuntu'}} manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} windows-dotnet: From 09321a026eb79efaa6786f049d4fe0a9ed587a85 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Tue, 13 Feb 2024 17:32:37 +0200 Subject: [PATCH 6/7] String usage fix --- .github/actions/test-execute-test/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/test-execute-test/action.yml b/.github/actions/test-execute-test/action.yml index eb1e025b..80419204 100644 --- a/.github/actions/test-execute-test/action.yml +++ b/.github/actions/test-execute-test/action.yml @@ -56,7 +56,7 @@ runs: $target_framework = "${{inputs.target_framework}}"; $target_frameworks = "${{inputs.target_framework_array}}"; if ($target_frameworks -eq '') { - $target_frameworks = "['$target_framework']"; + $target_frameworks = "'['$target_framework']'"; } "target_frameworks=$target_frameworks" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; shell: pwsh @@ -64,7 +64,7 @@ runs: - name: Build if required if: ${{inputs.manual_build == 'true'}} run: | - foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + foreach ($target_framework in ConvertFrom-Json "${{steps.test-args.outputs.target_frameworks}}") { dotnet build Harmony.sln -c ${{inputs.build_configuration}} -f $target_framework; } shell: pwsh @@ -77,7 +77,7 @@ runs: $vspath = vswhere -latest -property installationPath; $vstest = join-path $vspath "Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; - foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + foreach ($target_framework in ConvertFrom-Json "${{steps.test-args.outputs.target_frameworks}}") { & ${{(inputs.runtime-type == 'mono' && '"$mono"') || ''}} "$vstest" "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" --framework:$target_framework ${{steps.test-args.outputs.vstest}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh @@ -85,7 +85,7 @@ runs: - name: Perform Tests Windows .NET | Ubuntu/MacOS/MacOS-arm64 .NET/Mono if: ${{(inputs.os == 'windows' && inputs.runtime-type == 'dotnet') || inputs.os == 'ubuntu' || inputs.os == 'macos' || inputs.os == 'macos-arm64'}} run: | - foreach ($target_framework in ConvertFrom-Json ${{steps.test-args.outputs.target_frameworks}}) { + foreach ($target_framework in ConvertFrom-Json "${{steps.test-args.outputs.target_frameworks}}") { dotnet test "HarmonyTests/bin/Release/$target_framework/HarmonyTests.dll" -f $target_framework ${{steps.test-args.outputs.dotnet}} -- ${{steps.test-args.outputs.run_settings_args}}; } shell: pwsh From 6f551407d8e2c8c33e03dfad8d7179d7edb48525 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Tue, 13 Feb 2024 18:04:54 +0200 Subject: [PATCH 7/7] Triggering pipeline --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 599bcc22..5b4bd258 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,7 +29,7 @@ env: # Whether we should build the binaries before running the tests # Use with `PARALLEL: true` to reduce the execution time of test jobs, this increasing the throughput PREBUILD: false - + # You are interested in changing these values BUILD_CONFIGURATIONS: "['ReleaseFat', 'ReleaseThin']" DOTNET_TARGET_FRAMEWORKS: "['netcoreapp3.0', 'netcoreapp3.1', 'net5.0', 'net6.0', 'net7.0', 'net8.0']" @@ -37,7 +37,7 @@ env: FRAMEWORK_TARGET_FRAMEWORKS: "['net35', 'net452', 'net472', 'net48']" jobs: - + # https://stackoverflow.com/a/77549656 variables: name: Variable Accessibility Workaround for Jobs