diff --git a/.github/actions/get-dotnet-channel/action.yml b/.github/actions/get-dotnet-channel/action.yml new file mode 100644 index 00000000..8667a16e --- /dev/null +++ b/.github/actions/get-dotnet-channel/action.yml @@ -0,0 +1,43 @@ +name: 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: false + target_framework_array: + description: 'The target framework array to use' + required: false + +outputs: + channel: + description: 'The converted Channel variable' + 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 Channels + id: set_output + run: | + $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/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..80419204 --- /dev/null +++ b/.github/actions/test-execute-test/action.yml @@ -0,0 +1,102 @@ +name: Test Execute Test +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: + 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 + 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 + experimental: + description: 'Whether the tests are mandatory for the build to pass' + required: true + +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=$run_settings_args" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + + $vstest = "--logger:trx --logger:'console;verbosity=normal' --blame"; + "vstest=$vstest" | Out-File -FilePath $env:GITHUB_OUTPUT -Append; + + $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: | + 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 + + - 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}}") { + & ${{(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 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}}") { + 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 + 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..10b3b6c0 --- /dev/null +++ b/.github/actions/test-setup-dotnet-windows/action.yml @@ -0,0 +1,48 @@ +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 + target_framework_array: + description: 'The .NET target frameworks 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}} + target_framework_array: ${{inputs.target_framework_array}} + + - 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"; + + $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 new file mode 100644 index 00000000..667b19cb --- /dev/null +++ b/.github/actions/test-setup-dotnet/action.yml @@ -0,0 +1,33 @@ +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 + target_framework_array: + description: 'The .NET target frameworks to setup' + required: true + +runs: + using: "composite" + steps: + - name: Setup .NET Sdk + uses: actions/setup-dotnet@v4 + + - name: Get .NET Channels + uses: ./.github/actions/get-dotnet-channel + id: get_channels + with: + target_framework: ${{inputs.target_framework}} + target_framework_array: ${{inputs.target_framework_array}} + + - name: Setup .NET ${{steps.get_channels.outputs.channels_multiline}} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + ${{steps.get_channels.outputs.channel}} + ${{steps.get_channels.outputs.channels_multiline}} 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..4e8d6ca8 --- /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: false + 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..0542a471 --- /dev/null +++ b/.github/workflows/test-build.yml @@ -0,0 +1,65 @@ +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' + manual_build: + required: false + type: boolean + description: 'Whether to do the build' + default: true + 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}} + if: ${{!inputs.manual_build || inputs.publish}} + timeout-minutes: 8 + 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..023f0890 --- /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: 8 + 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..83c5e51f --- /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: 8 + 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..5843f4ea --- /dev/null +++ b/.github/workflows/test-result-upload.yml @@ -0,0 +1,34 @@ +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 + timeout-minutes: 5 + 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..d98adce3 --- /dev/null +++ b/.github/workflows/test-unix-dotnet.yml @@ -0,0 +1,88 @@ +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' + 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 + 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: 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: 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}} + 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 new file mode 100644 index 00000000..701321ec --- /dev/null +++ b/.github/workflows/test-unix-mono.yml @@ -0,0 +1,84 @@ +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' + 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 + 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: 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: 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}} + 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 new file mode 100644 index 00000000..87c43af8 --- /dev/null +++ b/.github/workflows/test-windows-dotnet.yml @@ -0,0 +1,80 @@ +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' + 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 + 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: 8 + steps: + - uses: actions/checkout@v4 + + - 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 + with: + os: windows + 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 new file mode 100644 index 00000000..52fbbab2 --- /dev/null +++ b/.github/workflows/test-windows-framework.yml @@ -0,0 +1,76 @@ +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' + 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 + 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: 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}} + + - 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}} + 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 new file mode 100644 index 00000000..0e6a247d --- /dev/null +++ b/.github/workflows/test-windows-mono.yml @@ -0,0 +1,81 @@ +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' + 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 + 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: 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}} + + - 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}} + 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 new file mode 100644 index 00000000..5b4bd258 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,258 @@ +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: + # 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']" + 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: + 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 + 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 == 'ubuntu'}} + manual_build: ${{needs.variables.outputs.PREBUILD != 'true'}} + + windows-dotnet: + name: Windows .NET x86/x64 + needs: [variables, build-binaries] + strategy: + matrix: + architecture: ['x86', 'x64'] + 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}} + 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 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + architecture: ['x86', 'x64'] + 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}} + 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 + needs: [variables, build-binaries] + strategy: + fail-fast: false + matrix: + architecture: ['x86', 'x64'] + 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}} + 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 + 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.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 }} + 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 + 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.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}} + 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: ${{needs.variables.outputs.EXPERIMENTAL == 'true'}} + strategy: + fail-fast: false + matrix: + 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_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: ${{needs.variables.outputs.EXPERIMENTAL == 'true'}} + strategy: + fail-fast: false + matrix: + 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}} + #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: ${{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.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: + os: ${{ matrix.image.os }} + image: ${{ matrix.image.code }} + architecture: ${{ matrix.architecture }} + target_framework: ${{ matrix.target_framework }} + 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: + 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: ${{needs.variables.outputs.EXPERIMENTAL == 'true' && 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 + if: ${{needs.variables.outputs.PARALLEL == 'true'}} + 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