diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..d1936ea --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "xamlstyler.console": { + "version": "3.2501.8", + "commands": [ + "xstyler" + ] + } + } +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d4bbf0f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,175 @@ + +# https://docs.github.com/actions/using-workflows/about-workflows +# https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main or release branches + push: + branches: [ main, 'dev', 'feature/*' ] + pull_request: + branches: [ main, 'dev', 'feature/*' ] + + # Allows you to run this workflow manually from the Actions tab (with inputs!) + # https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_dispatchinputs + workflow_dispatch: + inputs: + diagnostics: + description: 'Enable diagnostics (binlogs, dumps, etc) for this run' + required: false + default: false + type: boolean + verbosity: + description: 'MSBuild verbosity (quiet, minimal, normal, detailed, diagnostic)' + required: true + default: 'normal' + type: choice + options: + - quiet + - minimal + - normal + - detailed + - diagnostic + configuration: + description: 'Build configuration to use' + required: true + default: 'Debug' + type: choice + options: + - Debug + - Release + merge_group: + +env: + DOTNET_VERSION: ${{ '9.0.x' }} + CONFIGURATION: ${{ github.event.inputs.configuration || 'Debug' }} + VERBOSITY: ${{ github.event.inputs.verbosity || 'normal' }} + IS_MAIN: ${{ github.ref == 'refs/heads/main' }} + IS_PR: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + # Check XAML Styling before trying to do anything else as a gate + Xaml-Style-Check: + runs-on: windows-2022 + + steps: + - name: Install .NET SDK v${{ env.DOTNET_VERSION }} + uses: actions/setup-dotnet@v5.1.0 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: Checkout Repository + uses: actions/checkout@v6.0.2 + with: + submodules: recursive + + # Restore Tools from Manifest list in the Repository + - name: Restore dotnet tools + run: dotnet tool restore + + - name: Check XAML Styling + run: powershell -version 5.1 -command "./ApplyXamlStyling.ps1 -Passive" -ErrorAction Stop + + build: + needs: [Xaml-Style-Check] + runs-on: windows-2022 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # give UWP more room to breathe + - name: Configure Pagefile + uses: al-cheb/configure-pagefile-action@v1.5 + with: + minimum-size: 32GB + maximum-size: 32GB + disk-root: "C:" + + - name: Enable User-Mode Dumps collecting + if: (github.event.inputs.diagnostics || 'false') == 'true' + shell: powershell + run: | + New-Item '${{ github.workspace }}\CrashDumps' -Type Directory + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpFolder' -Type ExpandString -Value '${{ github.workspace }}\CrashDumps' + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpCount' -Type DWord -Value '10' + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpType' -Type DWord -Value '2' + + - name: Install .NET SDK v${{ env.DOTNET_VERSION }} + uses: actions/setup-dotnet@v5.1.0 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: .NET Info (if diagnostics) + if: (github.event.inputs.diagnostics || 'false') == 'true' + run: dotnet --info + + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: Checkout Repository + uses: actions/checkout@v6.0.2 + with: + submodules: recursive + + # Restore Tools from Manifest list in the Repository + - name: Restore dotnet tools + run: dotnet tool restore + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + with: + vs-version: '[17.9,)' + + # Build solution + - name: MSBuild + run: > + msbuild.exe /restore + /p:Configuration=${{ env.CONFIGURATION }} + /p:Platform=x64 + /m + ${{ github.event.inputs.diagnostics == 'true' && '/bl' || '' }} + /v:${{ env.VERBOSITY }} + XamlStudio.slnx + + # Run tests + - name: Setup VSTest Path + uses: darenm/setup-vstest@3a16d909a1f3bbc65b52f8270d475d905e7d3e44 + + - name: Run XAML Studio Unit Tests + id: test-platform + run: vstest.console.exe ./XamlStudio.Toolkit.UnitTests/**/XamlStudio.Toolkit.UnitTests.build.appxrecipe /Framework:FrameworkUap10 /logger:"trx;LogFileName=XamlStudio.trx" /Blame + + - name: Artifact - Diagnostic Logs + uses: actions/upload-artifact@v6 + if: ${{ (github.event.inputs.diagnostics || 'false') == 'true' && always() }} + with: + name: build-logs-xaml-studio + path: ./**/*.*log + + - name: Artifact - ILC Repro + uses: actions/upload-artifact@v6 + if: ${{ (github.event.inputs.diagnostics || 'false') == 'true' && always() }} + with: + name: ilc-repro + path: ./*.zip + + # https://github.com/dorny/paths-filter#custom-processing-of-changed-files + - name: Detect If any Dump Files + id: detect-dump + if: always() + working-directory: ${{ github.workspace }} + run: | + echo "DUMP_FILE=$(Get-ChildItem .\CrashDumps\*.dmp -ErrorAction SilentlyContinue)" >> $env:GITHUB_OUTPUT + + - name: Artifact - WER crash dumps + uses: actions/upload-artifact@v6 + if: ${{ (github.event.inputs.diagnostics || 'false') == 'true' && always() }} + with: + name: CrashDumps-xaml-studio + path: '${{ github.workspace }}/CrashDumps' + + - name: Analyze Dump + if: ${{ steps.detect-dump.outputs.DUMP_FILE != '' && (github.event.inputs.diagnostics || 'false') == 'true' && always() }} + run: | + dotnet tool install --global dotnet-dump + dotnet-dump analyze ${{ steps.detect-dump.outputs.DUMP_FILE }} -c "clrstack" -c "pe -lines" -c "exit" diff --git a/ApplyXamlStyling.ps1 b/ApplyXamlStyling.ps1 new file mode 100644 index 0000000..06359b1 --- /dev/null +++ b/ApplyXamlStyling.ps1 @@ -0,0 +1,128 @@ +<# + .SYNOPSIS + Modify XAML files to adhere to XAML Styler settings. + + .DESCRIPTION + The Apply XAML Stying Script can be used to check or modify XAML files with the repo's XAML Styler settings. + Learn more about XAML Styler at https://github.com/Xavalon/XamlStyler + + By default, uses git status to check all new or modified files. + + Use "PS> Help .\ApplyXamlStyling.ps1 -Full" for more details on parameters. + + .PARAMETER LastCommit + Runs against last commit vs. current changes + + .PARAMETER Unstaged + Runs against unstaged changed files + + .PARAMETER Staged + Runs against staged files vs. current changes + + .PARAMETER Main + Runs against main vs. current branch + + .PARAMETER Passive + Runs a passive check against all files in the repo for the CI + + .EXAMPLE + PS> .\ApplyXamlStyling.ps1 -Main +#> +param( + [switch]$LastCommit = $false, + [switch]$Unstaged = $false, + [switch]$Staged = $false, + [switch]$Main = $false, + [switch]$Passive = $false +) + +Write-Output "Use 'Help .\ApplyXamlStyling.ps1' for more info or '-Main' to run against all files." +Write-Output "" +Write-Output "Restoring dotnet tools..." +dotnet tool restore + +if (-not $Passive) +{ + # Look for unstaged changed files by default + $gitDiffCommand = "git status -s --porcelain" + + if ($Main) + { + Write-Output 'Checking Current Branch against `main` Files Only' + $branch = git status | Select-String -Pattern "On branch (?.*)$" + if ($null -eq $branch.Matches) + { + $branch = git status | Select-String -Pattern "HEAD detached at (?.*)$" + if ($null -eq $branch.Matches) + { + Write-Error 'Don''t know how to fetch branch from `git status`:' + git status | Write-Error + exit 1 + } + } + $branch = $branch.Matches.groups[1].Value + $gitDiffCommand = "git diff origin/main $branch --name-only --diff-filter=ACM" + } + elseif ($Unstaged) + { + # Look for unstaged files + Write-Output "Checking Unstaged Files" + $gitDiffCommand = "git diff --name-only --diff-filter=ACM" + } + elseif ($Staged) + { + # Look for staged files + Write-Output "Checking Staged Files Only" + $gitDiffCommand = "git diff --cached --name-only --diff-filter=ACM" + } + elseif ($LastCommit) + { + # Look at last commit files + Write-Output "Checking the Last Commit's Files Only" + $gitDiffCommand = "git diff HEAD^ HEAD --name-only --diff-filter=ACM" + } + else + { + Write-Output "Checking Git Status Files Only" + } + + Write-Output "Running Git Diff: $gitDiffCommand" + $files = Invoke-Expression $gitDiffCommand | Select-String -Pattern "\.xaml$" + + if (-not $Passive -and -not $Main -and -not $Unstaged -and -not $Staged -and -not $LastCommit) + { + # Remove 'status' column of 3 characters at beginning of lines + $files = $files | ForEach-Object { $_.ToString().Substring(3) } + } + + if ($files.count -gt 0) + { + dotnet tool run xstyler -c .\settings.xamlstyler -f $files + } + else + { + Write-Output "No XAML Files found to style..." + } +} +else +{ + Write-Output "Checking all files (passively)" + $files = Get-ChildItem *.xaml -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch "(\\obj\\)|(\\bin\\)" } + + if ($files.count -gt 0) + { + dotnet tool run xstyler -p -c .\settings.xamlstyler -f $files + + if ($lastExitCode -eq 1) + { + Write-Error 'XAML Styling is incorrect, please run `ApplyXamlStyling.ps1 -Main` locally.' + } + + # Return XAML Styler Status + exit $lastExitCode + } + else + { + exit 0 + } +} diff --git a/XamlStudio.Toolkit.UnitTests/XmlToXamlTreeTests.cs b/XamlStudio.Toolkit.UnitTests/XmlToXamlTreeTests.cs index f3d2031..dd49350 100644 --- a/XamlStudio.Toolkit.UnitTests/XmlToXamlTreeTests.cs +++ b/XamlStudio.Toolkit.UnitTests/XmlToXamlTreeTests.cs @@ -299,7 +299,9 @@ await EnqueueAsync(async () => }); } + // TODO: https://github.com/dotnet/XAMLStudio/issues/63 [TestMethod] + [Ignore] public async Task NamespacedControl_XmlToXamlTest() { await EnqueueAsync(async () => @@ -484,4 +486,4 @@ await EnqueueAsync(async () => await UnloadTestContentAsync(fwe); }); } -} \ No newline at end of file +} diff --git a/XamlStudio/Views/Document.xaml b/XamlStudio/Views/Document.xaml index c73d3e4..5ce35d3 100644 --- a/XamlStudio/Views/Document.xaml +++ b/XamlStudio/Views/Document.xaml @@ -60,7 +60,7 @@ - + @@ -109,7 +109,7 @@ - +