Skip to content

Commit

Permalink
Implemented a GitHub Actions testing pipeline (#575)
Browse files Browse the repository at this point in the history
* Implemented a GitHub Actions testing pipeline
* Disabled potential failed annotations
* Added non parallel variant without prebuild
* Simplified expressions
* Combined tests, build binaries on ubuntu for faster completion
* String usage fix
* Triggering pipeline
  • Loading branch information
Aragas authored Feb 13, 2024
1 parent fd02327 commit 5ce8bd9
Show file tree
Hide file tree
Showing 19 changed files with 1,368 additions and 0 deletions.
43 changes: 43 additions & 0 deletions .github/actions/get-dotnet-channel/action.yml
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions .github/actions/get-program-files/action.yml
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions .github/actions/test-build-cache/action.yml
Original file line number Diff line number Diff line change
@@ -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/
102 changes: 102 additions & 0 deletions .github/actions/test-execute-test/action.yml
Original file line number Diff line number Diff line change
@@ -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'}}
48 changes: 48 additions & 0 deletions .github/actions/test-setup-dotnet-windows/action.yml
Original file line number Diff line number Diff line change
@@ -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
33 changes: 33 additions & 0 deletions .github/actions/test-setup-dotnet/action.yml
Original file line number Diff line number Diff line change
@@ -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}}
45 changes: 45 additions & 0 deletions .github/actions/test-setup-mono-windows/action.yml
Original file line number Diff line number Diff line change
@@ -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}}
34 changes: 34 additions & 0 deletions .github/actions/test-upload-result/action.yml
Original file line number Diff line number Diff line change
@@ -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'}}
Loading

0 comments on commit 5ce8bd9

Please sign in to comment.