winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ecbe61d178eea870b8e80d9cef124983a80f0526
parent f6e27a48c32c4ccdc58f5f938c5bca5c54cef2dc
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Thu,  1 Aug 2024 16:41:11 -0700

Split testing into separate pipeline job (#4675)

## Change
The goal of this change is to separate the tests from the build. Then,
in the event of a spurious test failure, one needs only re-run the
failed job rather than the entire build.

---------

Co-authored-by: Flor Chacón <14323496+florelis@users.noreply.github.com>
Diffstat:
Mazure-pipelines.yml | 423+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/LocalhostWebServer/Program.cs | 11++++++++---
Msrc/LocalhostWebServer/Run-LocalhostWebServer.ps1 | 16++++++++++++----
Msrc/LocalhostWebServer/Startup.cs | 2++
Msrc/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs | 18++++++++++++------
Mtemplates/e2e-test.template.yml | 92++++++++++++++++++++++++++++++++++++++++----------------------------------------
6 files changed, 310 insertions(+), 252 deletions(-)

diff --git a/azure-pipelines.yml b/azure-pipelines.yml @@ -38,6 +38,8 @@ jobs: arguments: '-OutVar' workingDirectory: 'src' +# Build job creates artifacts for use in test jobs + - job: 'Build' timeoutInMinutes: 120 dependsOn: 'GetReleaseTag' @@ -49,10 +51,12 @@ jobs: buildConfiguration: 'Release' buildPlatform: 'x86' testBuildConfiguration: 'TestRelease' + artifactIdentifier: 'x86release' x64_release: buildConfiguration: 'Release' buildPlatform: 'x64' testBuildConfiguration: 'TestRelease' + artifactIdentifier: 'x64release' variables: BuildVer: $[counter(dependencies.GetReleaseTag.outputs['GetTag.tag'], 1)] @@ -130,22 +134,234 @@ jobs: /p:AppxBundle=Always /p:UapAppxPackageBuildMode=SideloadOnly' + - task: MSBuild@1 + displayName: Build MSIX Test Installer File + inputs: + platform: '$(buildPlatform)' + solution: 'src\AppInstallerTestMsixInstaller\AppInstallerTestMsixInstaller.wapproj' + configuration: '$(buildConfiguration)' + msbuildArguments: '/p:AppxPackageOutput="$(Build.ArtifactStagingDirectory)\AppInstallerTestMsixInstaller.msix" + /p:AppxBundle=Never + /p:UapAppxPackageBuildMode=SideLoadOnly + /p:AppxPackageSigningEnabled=false' + - task: CopyFiles@2 - displayName: 'Copy Symbols to artifacts folder' + displayName: 'Copy specific build artifacts' inputs: Contents: | $(buildOutDir)\WindowsPackageManager\WindowsPackageManager.pdb - $(buildOutDir)\Microsoft.Management.Configuration\Microsoft.Management.Configuration.pdb + $(buildOutDir)\WinGetUtil\WinGetUtil.dll + $(buildOutDir)\WinGetUtil\WinGetUtil.pdb TargetFolder: '$(artifactsDir)' - condition: succeededOrFailed() + + - task: PowerShell@2 + displayName: Create Package Layout + inputs: + filePath: 'src\AppInstallerCLIPackage\Execute-AppxRecipe.ps1' + arguments: '-AppxRecipePath AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration)\AppInstallerCLIPackage.build.appxrecipe -LayoutPath $(packageLayoutDir) -Force -Verbose' + workingDirectory: 'src' + + - task: CopyFiles@2 + displayName: 'Copy Dev Package (Loose Files)' + inputs: + SourceFolder: '$(packageLayoutDir)' + TargetFolder: '$(artifactsDir)\DevPackage' + + - task: CopyFiles@2 + displayName: 'Copy Dev Packages' + inputs: + SourceFolder: '$(appxPackageDir)' + TargetFolder: '$(artifactsDir)\AppxPackages' + + - task: CopyFiles@2 + displayName: 'Copy native binaries for Microsoft.WinGet.Client (net6)' + inputs: + SourceFolder: $(buildOutDir) + Contents: | + Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.dll + Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd + WindowsPackageManager\WindowsPackageManager.dll + UndockedRegFreeWinRT\winrtact.dll + TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Client\net6.0-windows10.0.22000.0\SharedDependencies\$(BuildPlatform) + flattenFolders: true + + - task: CopyFiles@2 + displayName: 'Copy native binaries for Microsoft.WinGet.Client (net48)' + inputs: + SourceFolder: $(buildOutDir) + Contents: | + Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.dll + Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd + WindowsPackageManager\WindowsPackageManager.dll + UndockedRegFreeWinRT\winrtact.dll + TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Client\net48\SharedDependencies\$(BuildPlatform) + flattenFolders: true + + - task: CopyFiles@2 + displayName: 'Copy native binaries for Microsoft.WinGet.Configuration' + inputs: + SourceFolder: $(buildOutDir) + Contents: | + Microsoft.Management.Configuration\Microsoft.Management.Configuration.dll + TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Configuration\SharedDependencies\$(BuildPlatform) + flattenFolders: true + + - task: CopyFiles@2 + displayName: 'Copy managed binaries for Microsoft.WinGet.Configuration in arch specific' + inputs: + SourceFolder: $(buildOutDirAnyCpu) + Contents: | + Microsoft.Management.Configuration.Projection\net6.0-windows10.0.22000.0\Microsoft.Management.Configuration.Projection.dll + TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Configuration\SharedDependencies\$(BuildPlatform) + flattenFolders: true + + - task: CopyFiles@2 + displayName: 'Copy PowerShell AnyCPU Module Files' + inputs: + SourceFolder: '$(buildOutDirAnyCpu)\PowerShell' + TargetFolder: '$(artifactsDir)\PowerShell' + + - task: CopyFiles@2 + displayName: 'Copy binaries' + inputs: + SourceFolder: '$(buildOutDir)' + TargetFolder: '$(artifactsDir)' + Contents: | + AppInstallerCLIE2ETests\** + AppInstallerCLITests\** + Microsoft.Management.Configuration\** + Microsoft.Management.Configuration.UnitTests\** + Microsoft.Management.Configuration.OutOfProc\** + + - task: CopyFiles@2 + displayName: 'Copy Files: WinGetUtilInterop.UnitTests' + inputs: + SourceFolder: '$(Build.SourcesDirectory)\src\WinGetUtilInterop.UnitTests\bin\$(buildPlatform)\$(BuildConfiguration)\net6.0' + TargetFolder: '$(artifactsDir)\WinGetUtilInterop.UnitTests\' + CleanTargetFolder: true + OverWrite: true + + - task: CopyFiles@2 + displayName: 'Copy WinGetUtil to WinGetUtilInterop.UnitTests folder' + inputs: + Contents: | + $(buildOutDir)\WinGetUtil\WinGetUtil.dll + TargetFolder: '$(artifactsDir)\WinGetUtilInterop.UnitTests\' + flattenFolders: true + + - task: CopyFiles@2 + displayName: 'Copy LocalhostWebServer to E2ETests' + inputs: + SourceFolder: '$(buildOutDir)\LocalhostWebServer' + TargetFolder: '$(artifactsDir)\E2ETests\LocalhostWebServer' + + # Invoke E2E setup to generate the TestLocalIndex; could optimize out some of its steps if needed + - template: templates/e2e-setup.yml + parameters: + sourceDir: $(Build.SourcesDirectory) + localhostWebServerArgs: '-BuildRoot $(artifactsDir)\E2ETests\LocalhostWebServer -StaticFileRoot $(Agent.TempDirectory)\TestLocalIndex -LocalSourceJson $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\localsource.json -TestDataPath $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData -SourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer -ExitBeforeRun' + + - task: CopyFiles@2 + displayName: 'Copy TestLocalIndex' + inputs: + SourceFolder: '$(Agent.TempDirectory)\TestLocalIndex' + TargetFolder: '$(artifactsDir)\E2ETests\TestLocalIndex' + + - task: CopyFiles@2 + displayName: 'Copy TestData' + inputs: + SourceFolder: '$(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\' + TargetFolder: '$(artifactsDir)\E2ETests\TestData' + + - task: CopyFiles@2 + displayName: 'Copy Dev Package Dependencies' + inputs: + SourceFolder: '$(appxPackageDir)\AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform)\' + TargetFolder: '$(artifactsDir)\E2ETests\DevPackageDependencies' + + - task: CopyFiles@2 + displayName: 'Copy test scripts to artifacts' + inputs: + Contents: | + $(Build.SourcesDirectory)\src\PowerShell\scripts\Execute-WinGetTests.ps1 + $(Build.SourcesDirectory)\src\PowerShell\tests\** + $(Build.SourcesDirectory)\src\LocalhostWebServer\Run-LocalhostWebServer.ps1 + TargetFolder: '$(artifactsDir)\E2ETests\Scripts' + flattenFolders: true + + - task: PublishPipelineArtifact@1 + displayName: Publish Pipeline Artifacts + inputs: + targetPath: '$(artifactsDir)' + artifact: 'Build.$(artifactIdentifier)' + + - task: ComponentGovernanceComponentDetection@0 + displayName: Component Governance + inputs: + scanType: 'Register' + verbosity: 'Verbose' + alertWarningLevel: 'High' + + # Run BimSkim for all the binaries + - task: BinSkim@4 + displayName: 'Run BinSkim ' + inputs: + arguments: 'analyze + "$(buildOutDir)\AppInstallerCLI\winget.exe" + "$(buildOutDir)\WinGetUtil\WinGetUtil.dll" + "$(buildOutDir)\WindowsPackageManager\WindowsPackageManager.dll" + "$(buildOutDir)\Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.InProc.dll" + "$(Build.SourcesDirectory)\src\WinGetUtilInterop\bin\WinGetUtil*Interop.dll" + "$(buildOutDir)\UndockedRegFreeWinRT\winrtact.dll" + "$(buildOutDir)\Microsoft.WinGet.Client.Cmdlets\Microsoft.WinGet.Client*.dll" + "$(buildOutDir)\ConfigurationRemotingServer\ConfigurationRemoting*Server.dll" + "$(buildOutDir)\ConfigurationRemotingServer\ConfigurationRemoting*Server.exe" + "$(buildOutDir)\ConfigurationRemotingServer\Microsoft.Management.Configuration*.dll" + "$(buildOutDir)\Microsoft.Management.Configuration\Microsoft.Management.Configuration*.dll" + "$(buildOutDir)\Microsoft.Management.Configuration.OutOfProc\Microsoft.Management.Configuration*.dll" + --config default --recurse' + + - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3 + displayName: 'Publish Security Analysis Logs' + +# Test job runs tests using build artifacts + +- job: 'Test' + timeoutInMinutes: 120 + dependsOn: 'Build' + condition: succeeded('Build') + + strategy: + matrix: + x86_release: + buildConfiguration: 'Release' + buildPlatform: 'x86' + testBuildConfiguration: 'TestRelease' + artifactIdentifier: 'x86release' + x64_release: + buildConfiguration: 'Release' + buildPlatform: 'x64' + testBuildConfiguration: 'TestRelease' + artifactIdentifier: 'x64release' + + variables: + buildOutDir: $(Pipeline.Workspace)\Build.$(artifactIdentifier) + artifactsDir: $(Build.ArtifactStagingDirectory) + packageLayoutDir: $(Pipeline.Workspace)\Build.$(artifactIdentifier)\DevPackage + + steps: + - task: DownloadPipelineArtifact@2 + displayName: 'Download Build Artifacts' + inputs: + artifact: 'Build.$(artifactIdentifier)' + path: '$(buildOutDir)' - task: PowerShell@2 displayName: Install Tests Dependencies inputs: targetType: 'inline' script: | - Get-ChildItem AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform) -Filter *.appx | %{ Add-AppxPackage $_.FullName } - workingDirectory: $(appxPackageDir) + Get-ChildItem $(buildOutDir)\E2ETests\DevPackageDependencies -Filter *.appx | %{ Add-AppxPackage $_.FullName } - task: VisualStudioTestPlatformInstaller@1 displayName: Prepare VSTest for E2E Tests @@ -167,14 +383,6 @@ jobs: condition: succeededOrFailed() - task: PowerShell@2 - displayName: Create Package Layout - inputs: - filePath: 'src\AppInstallerCLIPackage\Execute-AppxRecipe.ps1' - arguments: '-AppxRecipePath AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration)\AppInstallerCLIPackage.build.appxrecipe -LayoutPath $(packageLayoutDir) -Force -Verbose' - workingDirectory: 'src' - condition: succeededOrFailed() - - - task: PowerShell@2 displayName: Run Unit Tests Packaged inputs: filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1' @@ -190,18 +398,6 @@ jobs: failTaskOnFailedTests: true condition: succeededOrFailed() - - task: MSBuild@1 - displayName: Build MSIX Test Installer File - inputs: - platform: '$(buildPlatform)' - solution: 'src\AppInstallerTestMsixInstaller\AppInstallerTestMsixInstaller.wapproj' - configuration: '$(buildConfiguration)' - msbuildArguments: '/p:AppxPackageOutput="$(Build.ArtifactStagingDirectory)\AppInstallerTestMsixInstaller.msix" - /p:AppxBundle=Never - /p:UapAppxPackageBuildMode=SideLoadOnly - /p:AppxPackageSigningEnabled=false' - condition: succeededOrFailed() - - task: PowerShell@2 displayName: 'Set program files directory' inputs: @@ -218,7 +414,7 @@ jobs: - task: CopyFiles@2 displayName: 'Copy resources.pri to dotnet directory' inputs: - SourceFolder: '$(buildOutDir)\AppInstallerCLI' + SourceFolder: '$(buildOutDir)\DevPackage' TargetFolder: '$(platformProgramFiles)\dotnet' Contents: resources.pri condition: succeededOrFailed() @@ -227,7 +423,7 @@ jobs: - task: CopyFiles@2 displayName: 'Copy winmd to dotnet directory' inputs: - SourceFolder: '$(buildOutDir)\Microsoft.Management.Deployment' + SourceFolder: '$(buildOutDir)\DevPackage' TargetFolder: '$(platformProgramFiles)\dotnet' Contents: Microsoft.Management.Deployment.winmd condition: succeededOrFailed() @@ -235,7 +431,7 @@ jobs: - template: templates/e2e-setup.yml parameters: sourceDir: $(Build.SourcesDirectory) - localhostWebServerArgs: '-BuildRoot $(buildOutDir)\LocalhostWebServer -StaticFileRoot $(Agent.TempDirectory)\TestLocalIndex -LocalSourceJson $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\localsource.json -TestDataPath $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData -SourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer' + localhostWebServerArgs: '-BuildRoot $(buildOutDir)\E2ETests\LocalhostWebServer -StaticFileRoot $(buildOutDir)\E2ETests\TestLocalIndex -SourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer' - template: templates/e2e-test.template.yml parameters: @@ -259,64 +455,7 @@ jobs: displayName: 'Copy E2E Tests Package Log to artifacts folder' inputs: SourceFolder: '$(temp)\E2ETestLogs' - TargetFolder: '$(artifactsDir)\E2ETests\PackagedLog' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy E2E Test Source' - inputs: - SourceFolder: '$(Agent.TempDirectory)\TestLocalIndex' - TargetFolder: '$(artifactsDir)\E2ETests\TestLocalIndex' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy TestData' - inputs: - SourceFolder: '$(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\' - TargetFolder: '$(artifactsDir)\E2ETests\TestData' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy LocalhostWebServer' - inputs: - SourceFolder: '$(buildOutDir)\LocalhostWebServer' - TargetFolder: '$(artifactsDir)\E2ETests\LocalhostWebServer' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy Dev Package Dependencies' - inputs: - SourceFolder: '$(appxPackageDir)\AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform)\' - TargetFolder: '$(artifactsDir)\E2ETests\DevPackageDependencies' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy test scripts to artifacts' - inputs: - Contents: | - $(Build.SourcesDirectory)\src\PowerShell\scripts\Execute-WinGetTests.ps1 - $(Build.SourcesDirectory)\src\PowerShell\tests\** - $(Build.SourcesDirectory)\src\LocalhostWebServer\Run-LocalhostWebServer.ps1 - TargetFolder: '$(artifactsDir)\E2ETests\Scripts' - flattenFolders: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy Files: WinGetUtilInterop.UnitTests' - inputs: - SourceFolder: '$(Build.SourcesDirectory)\src\WinGetUtilInterop.UnitTests\bin\$(buildPlatform)\$(BuildConfiguration)\net6.0' - TargetFolder: '$(Build.ArtifactStagingDirectory)\WinGetUtilInterop.UnitTests\' - CleanTargetFolder: true - OverWrite: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy WinGetUtil to WinGetUtilInterop.UnitTests folder' - inputs: - Contents: | - $(buildOutDir)\WinGetUtil\WinGetUtil.dll - TargetFolder: '$(Build.ArtifactStagingDirectory)\WinGetUtilInterop.UnitTests\' - flattenFolders: true + TargetFolder: '$(artifactsDir)\PackagedLog' condition: succeededOrFailed() - task: VSTest@2 @@ -324,7 +463,7 @@ jobs: inputs: testSelector: 'testAssemblies' testAssemblyVer2: 'WinGetUtilInterop.UnitTests.dll' - searchFolder: '$(Build.ArtifactStagingDirectory)\WinGetUtilInterop.UnitTests' + searchFolder: '$(buildOutDir)\WinGetUtilInterop.UnitTests' codeCoverageEnabled: true platform: '$(buildPlatform)' configuration: '$(BuildConfiguration)' @@ -372,121 +511,19 @@ jobs: arguments: '-TargetLocation $(artifactsDir)\ConfigOOPTestsLog' condition: succeededOrFailed() - - task: CopyFiles@2 - displayName: 'Copy Util to artifacts folder' - inputs: - Contents: | - $(buildOutDir)\WinGetUtil\WinGetUtil.dll - $(buildOutDir)\WinGetUtil\WinGetUtil.pdb - TargetFolder: '$(artifactsDir)' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy native binaries for Microsoft.WinGet.Client' - inputs: - SourceFolder: $(buildOutDir) - Contents: | - Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.dll - Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd - WindowsPackageManager\WindowsPackageManager.dll - UndockedRegFreeWinRT\winrtact.dll - TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Client\net6.0-windows10.0.22000.0\SharedDependencies\$(BuildPlatform) - flattenFolders: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy native binaries for Microsoft.WinGet.Client' - inputs: - SourceFolder: $(buildOutDir) - Contents: | - Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.dll - Microsoft.Management.Deployment\Microsoft.Management.Deployment.winmd - WindowsPackageManager\WindowsPackageManager.dll - UndockedRegFreeWinRT\winrtact.dll - TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Client\net48\SharedDependencies\$(BuildPlatform) - flattenFolders: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy native binaries for Microsoft.WinGet.Configuration' - inputs: - SourceFolder: $(buildOutDir) - Contents: | - Microsoft.Management.Configuration\Microsoft.Management.Configuration.dll - TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Configuration\SharedDependencies\$(BuildPlatform) - flattenFolders: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy managed binaries for Microsoft.WinGet.Configuration in arch specific' - inputs: - SourceFolder: $(buildOutDirAnyCpu) - Contents: | - Microsoft.Management.Configuration.Projection\net6.0-windows10.0.22000.0\Microsoft.Management.Configuration.Projection.dll - TargetFolder: $(buildOutDirAnyCpu)\PowerShell\Microsoft.WinGet.Configuration\SharedDependencies\$(BuildPlatform) - flattenFolders: true - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy PowerShell AnyCPU Module Files' - inputs: - SourceFolder: '$(buildOutDirAnyCpu)\PowerShell' - TargetFolder: '$(artifactsDir)\PowerShell' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy Dev Package (Loose Files)' - inputs: - SourceFolder: '$(packageLayoutDir)' - TargetFolder: '$(artifactsDir)\DevPackage' - condition: succeededOrFailed() - - - task: CopyFiles@2 - displayName: 'Copy Dev Packages' - inputs: - SourceFolder: '$(appxPackageDir)' - TargetFolder: '$(artifactsDir)\AppxPackages' - condition: succeededOrFailed() - - task: PublishPipelineArtifact@1 displayName: Publish Pipeline Artifacts inputs: targetPath: '$(artifactsDir)' + artifact: 'Test.$(artifactIdentifier).$(System.JobAttempt)' condition: succeededOrFailed() - - task: ComponentGovernanceComponentDetection@0 - displayName: Component Governance - inputs: - scanType: 'Register' - verbosity: 'Verbose' - alertWarningLevel: 'High' - - # Run BimSkim for all the binaries - - task: BinSkim@4 - displayName: 'Run BinSkim ' - inputs: - arguments: 'analyze - "$(buildOutDir)\AppInstallerCLI\winget.exe" - "$(buildOutDir)\WinGetUtil\WinGetUtil.dll" - "$(buildOutDir)\WindowsPackageManager\WindowsPackageManager.dll" - "$(buildOutDir)\Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.InProc.dll" - "$(Build.SourcesDirectory)\src\WinGetUtilInterop\bin\WinGetUtil*Interop.dll" - "$(buildOutDir)\UndockedRegFreeWinRT\winrtact.dll" - "$(buildOutDir)\Microsoft.WinGet.Client.Cmdlets\Microsoft.WinGet.Client*.dll" - "$(buildOutDir)\ConfigurationRemotingServer\ConfigurationRemoting*Server.dll" - "$(buildOutDir)\ConfigurationRemotingServer\ConfigurationRemoting*Server.exe" - "$(buildOutDir)\ConfigurationRemotingServer\Microsoft.Management.Configuration*.dll" - "$(buildOutDir)\Microsoft.Management.Configuration\Microsoft.Management.Configuration*.dll" - "$(buildOutDir)\Microsoft.Management.Configuration.OutOfProc\Microsoft.Management.Configuration*.dll" - --config default --recurse' - - - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@3 - displayName: 'Publish Security Analysis Logs' +# Build and test PowerShell module - job: 'BuildPowerShellModule' timeoutInMinutes: 120 dependsOn: 'Build' - condition: always() + condition: succeeded('Build') steps: - task: DownloadPipelineArtifact@2 @@ -518,7 +555,7 @@ jobs: inputs: targetType: 'inline' script: | - Get-ChildItem E2ETests\DevPackageDependencies -Filter *.appx | %{ Add-AppxPackage $_.FullName } + Get-ChildItem AppxPackages\AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\x64 -Filter *.appx | %{ Add-AppxPackage $_.FullName } workingDirectory: $(Pipeline.Workspace)\Build.x64release\ - template: templates/e2e-setup.yml diff --git a/src/LocalhostWebServer/Program.cs b/src/LocalhostWebServer/Program.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. namespace LocalhostWebServer @@ -35,6 +35,7 @@ namespace LocalhostWebServer Startup.OutCertFile = config.GetValue<string>("OutCertFile"); Startup.LocalSourceJson = config.GetValue<string>("LocalSourceJson"); Startup.TestDataPath = config.GetValue<string>("TestDataPath"); + Startup.ExitBeforeRun = config.GetValue<bool>("ExitBeforeRun"); if (string.IsNullOrEmpty(Startup.StaticFileRoot) || string.IsNullOrEmpty(Startup.CertPath)) @@ -127,6 +128,11 @@ namespace LocalhostWebServer CopyDirectoryRecursive(Startup.TestDataPath, testDataDirectory); } + if (Startup.ExitBeforeRun) + { + return; + } + CreateHostBuilder(args).Build().Run(); } @@ -169,4 +175,4 @@ namespace LocalhostWebServer } } } -}- \ No newline at end of file +} diff --git a/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 b/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 @@ -40,7 +40,10 @@ param( [string]$SourceCert, [Parameter()] - [string]$TestDataPath + [string]$TestDataPath, + + [Parameter()] + [switch]$ExitBeforeRun ) if (-not [System.String]::IsNullOrEmpty($sourceCert)) @@ -51,6 +54,12 @@ if (-not [System.String]::IsNullOrEmpty($sourceCert)) Push-Location $BuildRoot -Start-Process -FilePath "LocalhostWebServer.exe" -ArgumentList "StaticFileRoot=$StaticFileRoot CertPath=$CertPath CertPassword=$CertPassword OutCertFile=$OutCertFile LocalSourceJson=$LocalSourceJson TestDataPath=$TestDataPath" +$Local:process = Start-Process -FilePath "LocalhostWebServer.exe" -ArgumentList "StaticFileRoot=$StaticFileRoot CertPath=$CertPath CertPassword=$CertPassword OutCertFile=$OutCertFile LocalSourceJson=$LocalSourceJson TestDataPath=$TestDataPath ExitBeforeRun=$ExitBeforeRun" -PassThru + + +if ($ExitBeforeRun) +{ + Wait-Process -InputObject $Local:process +} -Pop-Location- \ No newline at end of file +Pop-Location diff --git a/src/LocalhostWebServer/Startup.cs b/src/LocalhostWebServer/Startup.cs @@ -29,6 +29,8 @@ namespace LocalhostWebServer public static string TestDataPath { get; set; } + public static bool ExitBeforeRun { get; set; } + public Startup(IConfiguration configuration) { Configuration = configuration; diff --git a/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs b/src/Microsoft.Management.Configuration.UnitTests/Fixtures/UnitTestFixture.cs @@ -40,16 +40,22 @@ namespace Microsoft.Management.Configuration.UnitTests.Fixtures throw new DirectoryNotFoundException(this.TestModulesPath); } - string? gitSearchPath = Path.GetDirectoryName(assemblyPath); + // Use the environment variable if present, which is how ADO pipelines will find it. + string? gitSearchPath = Environment.GetEnvironmentVariable("BUILD_SOURCESDIRECTORY"); - while (!string.IsNullOrEmpty(gitSearchPath)) + if (string.IsNullOrWhiteSpace(gitSearchPath)) { - if (Directory.Exists(Path.Combine(gitSearchPath, ".git"))) + gitSearchPath = Path.GetDirectoryName(assemblyPath); + + while (!string.IsNullOrEmpty(gitSearchPath)) { - break; - } + if (Directory.Exists(Path.Combine(gitSearchPath, ".git"))) + { + break; + } - gitSearchPath = Path.GetDirectoryName(gitSearchPath); + gitSearchPath = Path.GetDirectoryName(gitSearchPath); + } } this.GitRootPath = gitSearchPath ?? throw new DirectoryNotFoundException("git root path"); diff --git a/templates/e2e-test.template.yml b/templates/e2e-test.template.yml @@ -1,49 +1,49 @@ -parameters: -- name: title - type: string -- name: isPackaged - type: boolean -- name: filter - type: string -- name: experimentalFeatures +parameters: +- name: title type: string - default: 'none' - -steps: - - task: CmdLine@2 - displayName: Start COM trace for ${{ parameters.title }} - condition: and(succeededOrFailed(), eq(variables['System.debug'], true)) - inputs: - script: 'wpr -start $(Build.SourcesDirectory)\tools\COMTrace\ComTrace.wprp -filemode' - - - task: VSTest@2 - displayName: Run ${{ parameters.title }} - inputs: - testRunTitle: ${{ parameters.title }} - testSelector: 'testAssemblies' - testAssemblyVer2: '$(buildOutDir)\AppInstallerCLIE2ETests\AppInstallerCLIE2ETests.dll' - testFiltercriteria: ${{ parameters.filter }} - ${{ if eq(parameters.isPackaged, true) }}: - overrideTestrunParameters: '-PackagedContext true - -AICLIPackagePath $(packageLayoutDir) - -AICLIPath wingetdev.exe - -LooseFileRegistration true - -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex - -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client\Microsoft.WinGet.Client.psd1 - -LocalServerCertPath $(Agent.TempDirectory)\servercert.cer +- name: isPackaged + type: boolean +- name: filter + type: string +- name: experimentalFeatures + type: string + default: 'none' + +steps: + - task: CmdLine@2 + displayName: Start COM trace for ${{ parameters.title }} + condition: and(succeededOrFailed(), eq(variables['System.debug'], true)) + inputs: + script: 'wpr -start $(Build.SourcesDirectory)\tools\COMTrace\ComTrace.wprp -filemode' + + - task: VSTest@2 + displayName: Run ${{ parameters.title }} + inputs: + testRunTitle: ${{ parameters.title }} + testSelector: 'testAssemblies' + testAssemblyVer2: '$(buildOutDir)\AppInstallerCLIE2ETests\AppInstallerCLIE2ETests.dll' + testFiltercriteria: ${{ parameters.filter }} + ${{ if eq(parameters.isPackaged, true) }}: + overrideTestrunParameters: '-PackagedContext true + -AICLIPackagePath $(packageLayoutDir) + -AICLIPath wingetdev.exe + -LooseFileRegistration true + -StaticFileRootPath $(buildOutDir)\E2ETests\TestLocalIndex + -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client\Microsoft.WinGet.Client.psd1 + -LocalServerCertPath $(Agent.TempDirectory)\servercert.cer -SkipTestSource true - -ForcedExperimentalFeatures ${{ parameters.experimentalFeatures }}' - ${{ else }}: - overrideTestrunParameters: '-PackagedContext false - -AICLIPath $(packageLayoutDir)\AppInstallerCLI\winget.exe - -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex - -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client\Microsoft.WinGet.Client.psd1 - -LocalServerCertPath $(Agent.TempDirectory)\servercert.cer + -ForcedExperimentalFeatures ${{ parameters.experimentalFeatures }}' + ${{ else }}: + overrideTestrunParameters: '-PackagedContext false + -AICLIPath $(packageLayoutDir)\AppInstallerCLI\winget.exe + -StaticFileRootPath $(buildOutDir)\E2ETests\TestLocalIndex + -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client\Microsoft.WinGet.Client.psd1 + -LocalServerCertPath $(Agent.TempDirectory)\servercert.cer -SkipTestSource true - -ForcedExperimentalFeatures ${{ parameters.experimentalFeatures }}' - - - task: CmdLine@2 - displayName: Complete COM trace for ${{ parameters.title }} - condition: and(succeededOrFailed(), eq(variables['System.debug'], true)) - inputs: - script: 'wpr -stop "$(artifactsDir)\ComTrace - ${{ parameters.title }}.etl"' + -ForcedExperimentalFeatures ${{ parameters.experimentalFeatures }}' + + - task: CmdLine@2 + displayName: Complete COM trace for ${{ parameters.title }} + condition: and(succeededOrFailed(), eq(variables['System.debug'], true)) + inputs: + script: 'wpr -stop "$(artifactsDir)\ComTrace - ${{ parameters.title }}.etl"'