From dfa7a4e046f1ca84afcfc45c1dfdfaffc68f6b36 Mon Sep 17 00:00:00 2001 From: Heath Stewart Date: Thu, 3 Jan 2019 17:53:46 -0800 Subject: [PATCH] Migrate PR build to Azure Pipelines --- .vsts-ci.yml | 180 +++++------------------------ CONTRIBUTING.md | 49 ++++---- README.md | 3 +- appveyor.yml | 90 --------------- azure-pipelines.yml | 24 ++++ build/build.yml | 148 ++++++++++++++++++++++++ docker/Debug.dockerfile | 40 +++++++ docker/Dockerfile | 33 +++--- docker/appveyor/Dockerfile | 6 - docker/appveyor/docker-compose.yml | 12 -- docker/docker-compose.debug.yml | 16 +++ docker/docker-compose.yml | 6 +- tools/Publish-Release.ps1 | 105 ----------------- tools/test.ps1 | 47 +++----- 14 files changed, 320 insertions(+), 439 deletions(-) delete mode 100644 appveyor.yml create mode 100644 azure-pipelines.yml create mode 100644 build/build.yml create mode 100644 docker/Debug.dockerfile delete mode 100644 docker/appveyor/Dockerfile delete mode 100644 docker/appveyor/docker-compose.yml create mode 100644 docker/docker-compose.debug.yml delete mode 100644 tools/Publish-Release.ps1 diff --git a/.vsts-ci.yml b/.vsts-ci.yml index 1276849..315de35 100644 --- a/.vsts-ci.yml +++ b/.vsts-ci.yml @@ -2,160 +2,34 @@ # Licensed under the MIT license. See LICENSE.txt in the project root for license information. trigger: + batch: true branches: include: - master - paths: - exclude: - - appveyor.yml -phases: -- phase: Build - queue: - name: VSEng-MicroBuildVS2017 - demands: - - msbuild - - visualstudio - - vstest - parallel: 2 - matrix: - debug: - Configuration: Debug - SignType: Test - release: - Configuration: Release - - variables: - Platform: Any CPU - Solution: '*.sln' - - steps: - - task: NuGetToolInstaller@0 - displayName: Install nuget - inputs: - versionSpec: '4.4.1' - - - task: NuGetCommand@2 - displayName: Restore nuget packages - inputs: - restoreSolution: $(Solution) - - - task: MicroBuildSigningPlugin@1 - displayName: Install MicroBuild signing plugin - inputs: - esrpSigning: true - signType: $(SignType) - - - powershell: | - $ErrorActionPreference = 'Stop' - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force - Install-Module -Name platyPS -Repository PSGallery -SkipPublisherCheck -Force - displayName: Install PowerShell modules - - - powershell: | - New-ExternalHelp -Path docs\VSSetup -OutputPath "src\VSSetup.PowerShell\bin\${env:CONFIGURATION}" -Force - displayName: Compile documentation - env: - CONFIGURATION: $(Configuration) - workingDirectory: $(Build.SourcesDirectory) - - - task: VSBuild@1 - displayName: Build solution - inputs: - solution: $(Solution) - configuration: $(Configuration) - platform: $(Platform) - msbuildArgs: /p:RunCodeAnalysis=true /p:TreatWarningsAsErrors=true "/flp:Verbosity=Diagnostic;LogFile=$(Build.ArtifactStagingDirectory)\logs\build.log" - maximumCpuCount: true - - - task: VSTest@2 - displayName: Test solution - inputs: - testAssemblyVer2: | - **\$(Configuration)\*test*.dll - !**\obj\** - configuration: $(Configuration) - platform: $(Platform) - codeCoverageEnabled: true - runInParallel: true - - - powershell: | - If (-Not (Test-Path -Path $env:OUTDIR -PathType Container)) { $null = New-Item -Path $env:OUTDIR -Type Directory } - Compress-Archive -Path LICENSE.txt, "${env:SRCDIR}\*.dll", "${env:SRCDIR}\*.dll-Help.xml", "${env:SRCDIR}\about_*.help.txt", "${env:SRCDIR}\VSSetup.*" -DestinationPath "${env:OUTDIR}\VSSetup.zip" - displayName: Archive output - env: - CONFIGURATION: $(Configuration) - OUTDIR: $(Build.BinariesDirectory)\bin\$(Configuration) - SRCDIR: src\VSSetup.PowerShell\bin\$(Configuration) - workingDirectory: $(Build.SourcesDirectory) - - - task: NuGetCommand@2 - displayName: Package output - inputs: - command: pack - basePath: $(Build.SourcesDirectory) - packDestination: $(Build.BinariesDirectory)\bin\$(Configuration) - packagesToPack: pkg\VSSetup\VSSetup.nuspec - configuration: $(Configuration) - versioningScheme: byEnvVar - versionEnvVar: GitBuildVersionSimple - includeSymbols: true - buildProperties: CommitId=$(Build.SourceVersion) - - - task: VSBuild@1 - displayName: Sign packages - condition: and(succeeded(), eq(variables['Configuration'], 'Release')) - inputs: - solution: pkg\VSSetup\VSSetup.signproj - configuration: $(Configuration) - platform: $(Platform) - msbuildArgs: /p:OutDir=$(Build.BinariesDirectory)\bin\$(Configuration) "/flp:Verbosity=Diagnostic;LogFile=$(Build.ArtifactStagingDirectory)\logs\sign.log" - - - task: MicroBuildCodesignVerify@1 - displayName: Validate packages - condition: and(succeeded(), eq(variables['Configuration'], 'Release')) - inputs: - ExcludeSNVerify: true - TargetFolder: $(Build.BinariesDirectory)\bin\$(Configuration) - WhiteListPathForCerts: build\nosign.txt - - - task: CopyFiles@2 - displayName: Copy output - inputs: - SourceFolder: $(Build.SourcesDirectory)\src - Contents: '**\bin\$(Configuration)\**' - TargetFolder: $(Build.ArtifactStagingDirectory)\drop\src - - - task: CopyFiles@2 - displayName: Copy packages - inputs: - SourceFolder: $(Build.BinariesDirectory) - Contents: bin\$(Configuration)\** - TargetFolder: $(Build.ArtifactStagingDirectory)\drop - - - task: CopyFiles@2 - displayName: Copy tools - inputs: - SourceFolder: $(Build.SourcesDirectory) - Contents: tools\** - TargetFolder: $(Build.ArtifactStagingDirectory)\drop - - - task: PublishBuildArtifacts@1 - displayName: Publish drop - inputs: - ArtifactName: drop - PathtoPublish: $(Build.ArtifactStagingDirectory)\drop - - - task: PublishBuildArtifacts@1 - displayName: Publish logs - condition: succeededOrFailed() - continueOnError: true - inputs: - ArtifactName: logs - PathtoPublish: $(Build.ArtifactStagingDirectory)\logs - - - task: MicroBuildCleanup@1 - displayName: Clean up - condition: succeededOrFailed() - -# vim: set ai et st=2 sts=2 sw=2: +pr: none + +queue: + name: VSEng-MicroBuildVS2017 + timeoutInMinutes: 120 + demands: + - msbuild + - visualstudio + - vstest + +steps: +- task: ms-vseng.MicroBuildTasks.30666190-6959-11e5-9f96-f56098202fef.MicroBuildSigningPlugin@1 + displayName: Install MicroBuild signing plugin + inputs: + esrpSigning: true + signType: $(SignType) + +- template: build/build.yml + parameters: + BuildConfiguration: $(BuildConfiguration) + BuildPlatform: $(BuildPlatform) + Sign: true + +- task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1 + displayName: Clean up + condition: succeededOrFailed() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12d681b..875fa48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,12 +7,6 @@ This project uses the following software. Newer versions may work but backward c * [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs.aspx) -### Optional - -Some projects require optional software to open or otherwise use in Visual Studio. They are not required to build the solution using MSBuild. - -* [NuProj Package Project](https://marketplace.visualstudio.com/items?itemName=NuProjTeam.NuGetPackageProject) - ## Coding This project uses a Git flow model releasing from the `master` branch with development based on and stabilize in the `develop` branch. You can view current build status in the [README](README.md) document. @@ -49,34 +43,43 @@ nuget install xunit.runner.console -outputdirectory packages packages\xunit.runner.console.\tools\xunit.runner.console test\VSSetup.PowerShell.Test\bin\Debug\Microsoft.VisualStudio.Setup.PowerShell.Test.dll ``` -If your machine supports it, you can install [Docker for Windows][docker], switch to Windows containers, and test in isolated containers for runtime behavior. You can run unit tests and integration tests together. +If your machine supports it, you can install [Docker for Windows][docker], switch to Windows containers, and test in isolated containers for runtime behavior. You can run functional tests and runtime tests together. ```batch tools\test.cmd ``` -For a faster development process, you can run `docker-compose run test` from the _docker_ directory to start an interactive PowerShell session in a container running the Visual Studio Remote Debugger. The build output and test scripts are mounted into the container. If you rebuild or modify the tests the container is automatically updated. You can also start the container detached and run tests faster without having to restart the container. +You can also run tests directly with `docker-compose`: ```batch -cd docker -docker-compose up -d - -REM Repeat following command as often as desired. -docker-compose exec test powershell.exe -c invoke-pester c:\tests -enableexit - -docker-compose stop +docker-compose -f docker\docker-compose.yml run test ``` ### Debugging -You can run `docker-compose up -d` from the _docker_ directory to start an interactive shell for exploratory testing. If no other commands are passed when starting the container, the Visual Studio Remote Debugger will launch by default. Remote debugging services are discoverable on your private network. - -1. Click *Debug -> Attach to Process* -2. Change *Transport* to "Remote (no authentication)" -3. Click *Find* -4. Click *Select* on the container (host name will be the container name) -5. Select "powershell" under *Available Processes* -6. Click *Attach* +You can use the following steps to start an environment for exploratory testing or to run and debug tests. The Visual Studio Remote Debugger will launch by default and should be discoverable on your private network. + +1. Run: + ```batch + docker-compose -f docker\docker-compose.yml -f docker\docker-compose.debug.yml up -d + + REM Start an interactive shell + docker-compose -f docker\docker-compose.yml -f docker\docker-compose.debug.yml exec test powershell.exe + ``` +2. Click *Debug -> Attach to Process* +3. Change *Transport* to "Remote (no authentication)" +4. Click *Find* +5. Click *Select* on the container (host name will be the container name) +6. Select "powershell" under *Available Processes* +7. Click *Attach* +8. Run any commands you like in the interactive shell, or run all tests: + ```powershell + Invoke-Pester C:\Tests -EnableExit + ``` +9. When finished, run: + ```batch + docker-compose -f docker\docker-compose.yml -f docker\docker-compose.debug.yml down + ``` If you know the host name (by default, the container name) or IP address (depending on your network configuration for the container), you can type it into the *Qualifier* directory along with port 4022, e.g. "172.22.0.1:4022". diff --git a/README.md b/README.md index f5613f4..7e0a06a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ Visual Studio Setup PowerShell Module ===================================== -[![build status: master](https://ci.appveyor.com/api/projects/status/4c1feyut6rvmw1dk/branch/master?svg=true)](https://ci.appveyor.com/project/VisualStudioSetup/vssetup-powershell/branch/master) +![build status: master](https://devdiv.visualstudio.com/DevDiv/_apis/build/status/Setup/Setup-VSSetup.PowerShell-CI?branchName=master&label=master) +[![build status: develop](https://dev.azure.com/azure-public/vssetup/_apis/build/status/Microsoft.vssetup.powershell?branchName=develop&label=develop)](https://dev.azure.com/azure-public/vssetup/_build/latest?definitionId=23?branchName=develop) [![github release](https://img.shields.io/github/release/Microsoft/VSSetup.PowerShell.svg?logo=github)](https://github.com/Microsoft/VSSetup.PowerShell/releases/latest) [![github releases: all](https://img.shields.io/github/downloads/Microsoft/VSSetup.PowerShell/total.svg?logo=github&label=github)](https://github.com/Microsoft/VSSetup.PowerShell/releases) [![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/VSSetup.svg)](https://powershellgallery.com/packages/VSSetup) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 0a1c846..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (C) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. See LICENSE.txt in the project root for license information. - -configuration: - - Debug - - Release - -image: Visual Studio 2017 - -environment: - RunCodeAnalysis: true - TreatWarningsAsErrors: true - -branches: - only: - - master - - develop - -skip_tags: true - -notifications: - - provider: GitHubPullRequest - on_build_success: true - on_build_failure: true - -cache: - - packages -> **\packages.config - -install: - - ps: | - $ErrorActionPreference = 'Stop' - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force - Install-Module -Name platyPS -Repository PSGallery -SkipPublisherCheck -Force - -before_build: - - nuget restore - - ps: New-ExternalHelp -Path $env:APPVEYOR_BUILD_FOLDER\docs\VSSetup -OutputPath $env:APPVEYOR_BUILD_FOLDER\src\VSSetup.PowerShell\bin\$env:CONFIGURATION -Force - -build: - parallel: true - -after_build: - - 7z a bin\%CONFIGURATION%\VSSetup.zip %APPVEYOR_BUILD_FOLDER%\LICENSE.txt - - 7z a bin\%CONFIGURATION%\VSSetup.zip %APPVEYOR_BUILD_FOLDER%\src\VSSetup.PowerShell\bin\%CONFIGURATION%\*.dll - - 7z a bin\%CONFIGURATION%\VSSetup.zip %APPVEYOR_BUILD_FOLDER%\src\VSSetup.PowerShell\bin\%CONFIGURATION%\*.dll-Help.xml - - 7z a bin\%CONFIGURATION%\VSSetup.zip %APPVEYOR_BUILD_FOLDER%\src\VSSetup.PowerShell\bin\%CONFIGURATION%\about_*.help.txt - - 7z a bin\%CONFIGURATION%\VSSetup.zip %APPVEYOR_BUILD_FOLDER%\src\VSSetup.PowerShell\bin\%CONFIGURATION%\VSSetup.* - - nuget pack -BasePath "%APPVEYOR_BUILD_FOLDER%" -OutputDirectory "bin\%CONFIGURATION%" -Version "%GitBuildVersionSimple%" -Properties "Configuration=%CONFIGURATION%;CommitId=%APPVEYOR_REPO_COMMIT%" pkg\VSSetup\VSSetup.nuspec - -test_script: - - tools\test.cmd -v - -artifacts: - - path: bin\$(configuration)\VSSetup.zip - name: VSSetup - - - path: bin\$(configuration)\*.nupkg - name: package - -deploy: - - provider: GitHub - description: 'Prerelease of version $(appveyor_build_version)' - prerelease: true - auth_token: - secure: OQYrPN9oRtZHmy6BthAD7WrNdNMIhjOj5J+1YO96vnYnAhQ3ZRTGg0naaAlUsvpW - artifact: VSSetup - on: - branch: develop - configuration: Release - - - provider: NuGet - server: https://powershellgallery.com - api_key: - secure: zlSsf1CjcEIqOM58eGv9sOJmGL24l9sFfE+GxftIiD3bJwJKNnlwbfe1/H81TQQD - artifact: package - skip_symbols: true - on: - branch: develop - configuration: Release - - - provider: NuGet - server: https://nuget.smbsrc.net/ - api_key: - secure: d8ZqLghGiOFGr7Bu1x69hHKaopNtHRCmex72n6n7Ul80enJWM65tw9c1wlnXw4yP - artifact: /.*\.symbols\.nupkg/ - on: - branch: develop - configuration: Release - -# vim: set ai et st=2 sts=2 sw=2: diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..ea703f8 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,24 @@ +# Copyright (C) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. See LICENSE.txt in the project root for license information. + +trigger: + batch: true + branches: + include: + - develop + +pr: + branches: + include: + - master + - develop + +pool: + vmImage: vs2017-win2016 + +steps: +- template: build/build.yml + parameters: + BuildConfiguration: $(BuildConfiguration) + BuildPlatform: $(BuildPlatform) + Docker: true diff --git a/build/build.yml b/build/build.yml new file mode 100644 index 0000000..9d76763 --- /dev/null +++ b/build/build.yml @@ -0,0 +1,148 @@ +# Copyright (C) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. See LICENSE.txt in the project root for license information. + +parameters: + BuildConfiguration: Release + BuildPlatform: Any CPU + Docker: false + Sign: false + +steps: +- task: NuGetToolInstaller@0 + displayName: Install nuget + inputs: + versionSpec: '4.4.1' + +- task: NuGetCommand@2 + displayName: Restore nuget packages + +- powershell: | + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force + Install-Module -Name platyPS -Repository PSGallery -SkipPublisherCheck -Force + displayName: Install PowerShell modules + +- powershell: | + New-ExternalHelp -Path docs\VSSetup -OutputPath "src\VSSetup.PowerShell\bin\${env:CONFIGURATION}" -Force + displayName: Compile documentation + env: + CONFIGURATION: ${{ parameters.BuildConfiguration }} + workingDirectory: $(Build.SourcesDirectory) + +- task: VSBuild@1 + displayName: Build solution + inputs: + configuration: ${{ parameters.BuildConfiguration }} + platform: ${{ parameters.BuildPlatform }} + msbuildArgs: /p:RunCodeAnalysis=true /p:TreatWarningsAsErrors=true "/flp:Verbosity=Diagnostic;LogFile=$(Build.ArtifactStagingDirectory)\logs\build.log" + maximumCpuCount: true + +- task: VSTest@2 + displayName: Functional tests + inputs: + testAssemblyVer2: | + **\${{ parameters.BuildConfiguration }}\*test*.dll + !**\obj\** + configuration: ${{ parameters.BuildConfiguration }} + platform: ${{ parameters.BuildPlatform }} + codeCoverageEnabled: true + runInParallel: true + +- ${{ if eq(parameters.Docker, 'true') }}: + # Make sure service images are rebuilt if Dockerfiles changed. + - task: DockerCompose@0 + displayName: Build images + inputs: + dockerComposeFile: docker/docker-compose.yml + action: Build services + env: + CONFIGURATION: ${{ parameters.BuildConfiguration }} + + - task: DockerCompose@0 + displayName: Runtime tests + inputs: + dockerComposeFile: docker/docker-compose.yml + action: Run a specific service + serviceName: test + containerCommand: -Command Invoke-Pester C:\Tests -EnableExit -OutputFile C:\Tests\Results.xml -OutputFormat NUnitXml + detached: false + env: + CONFIGURATION: ${{ parameters.BuildConfiguration }} + + - task: PublishTestResults@2 + displayName: Publish test results + inputs: + buildConfiguration: ${{ parameters.BuildConfiguration }} + buildPlatform: ${{ parameters.BuildPlatform }} + testRunTitle: Runtime tests (${{ parameters.BuildConfiguration }}|${{ parameters.BuildPlatform }}) + testResultsFormat: NUnit + testResultsFiles: '**\*Results.xml' + searchFolder: $(Build.SourcesDirectory)\docker\Tests + mergeTestResults: true + condition: succeededOrFailed() + +- powershell: | + If (-Not (Test-Path -Path $env:OUTDIR -PathType Container)) { $null = New-Item -Path $env:OUTDIR -Type Directory } + Compress-Archive -Path LICENSE.txt, "${env:SRCDIR}\*.dll", "${env:SRCDIR}\*.dll-Help.xml", "${env:SRCDIR}\about_*.help.txt", "${env:SRCDIR}\VSSetup.*" -DestinationPath "${env:OUTDIR}\VSSetup.zip" + displayName: Archive output + env: + CONFIGURATION: ${{ parameters.BuildConfiguration }} + OUTDIR: $(Build.BinariesDirectory)\bin\${{ parameters.BuildConfiguration }} + SRCDIR: src\VSSetup.PowerShell\bin\${{ parameters.BuildConfiguration }} + workingDirectory: $(Build.SourcesDirectory) + +- task: NuGetCommand@2 + displayName: Package output + inputs: + command: pack + basePath: $(Build.SourcesDirectory) + packDestination: $(Build.BinariesDirectory)\bin\${{ parameters.BuildConfiguration }} + packagesToPack: pkg\VSSetup\VSSetup.nuspec + configuration: ${{ parameters.BuildConfiguration }} + versioningScheme: byEnvVar + versionEnvVar: GitBuildVersionSimple + includeSymbols: true + buildProperties: CommitId=$(Build.SourceVersion) + +- ${{ if eq(parameters.Sign, 'true') }}: + - task: VSBuild@1 + displayName: Sign packages + inputs: + solution: pkg\VSSetup\VSSetup.signproj + configuration: ${{ parameters.BuildConfiguration }} + platform: ${{ parameters.BuildPlatform }} + msbuildArgs: /p:OutDir=$(Build.BinariesDirectory)\bin\${{ parameters.BuildConfiguration }} "/flp:Verbosity=Diagnostic;LogFile=$(Build.ArtifactStagingDirectory)\logs\sign.log" + + - task: MicroBuildCodesignVerify@1 + displayName: Validate packages + inputs: + ExcludeSNVerify: true + TargetFolder: $(Build.BinariesDirectory)\bin\${{ parameters.BuildConfiguration }} + WhiteListPathForCerts: build\nosign.txt + +- task: CopyFiles@2 + displayName: Copy output + inputs: + SourceFolder: $(Build.SourcesDirectory)\src + Contents: '**\bin\${{ parameters.BuildConfiguration }}\**' + TargetFolder: $(Build.ArtifactStagingDirectory)\drop\src + +- task: CopyFiles@2 + displayName: Copy packages + inputs: + SourceFolder: $(Build.BinariesDirectory) + Contents: bin\${{ parameters.BuildConfiguration }}\** + TargetFolder: $(Build.ArtifactStagingDirectory)\drop + +- task: PublishBuildArtifacts@1 + displayName: Publish drop + inputs: + ArtifactName: drop + PathtoPublish: $(Build.ArtifactStagingDirectory)\drop + +- task: PublishBuildArtifacts@1 + displayName: Publish logs + condition: succeededOrFailed() + continueOnError: true + inputs: + ArtifactName: logs + PathtoPublish: $(Build.ArtifactStagingDirectory)\logs diff --git a/docker/Debug.dockerfile b/docker/Debug.dockerfile new file mode 100644 index 0000000..879208d --- /dev/null +++ b/docker/Debug.dockerfile @@ -0,0 +1,40 @@ +#escape=` + +# Copyright (C) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. See LICENSE.txt in the project root for license information. + +# Based on latest image cached by Azure Pipelines: https://docs.microsoft.com/azure/devops/pipelines/agents/hosted#software +FROM microsoft/windowsservercore@sha256:c60a7376f5147e40b65c51fce34ac17710742f97e91b5c3a71e1667e671112f1 +SHELL ["powershell.exe", "-ExecutionPolicy", "Bypass", "-Command"] + +ENV INSTALLER_VERSION=1.14.190.31519 ` + INSTALLER_URI=https://download.visualstudio.microsoft.com/download/pr/100516681/d68d54e233c956ff79799fdf63753c54/Microsoft.VisualStudio.Setup.Configuration.msi ` + INSTALLER_HASH=8917aa7b4116e574856d43e8e62862c1d6f25512be54917f2ef95f9cac103810 + +# Download and register the query API +RUN $ErrorActionPreference = 'Stop' ; ` + $VerbosePreference = 'Continue' ; ` + $null = New-Item C:\TEMP -ItemType Directory -ea SilentlyContinue; ` + Invoke-WebRequest -Uri $env:INSTALLER_URI -OutFile C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi; ` + if ((Get-FileHash -Path C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi -Algorithm SHA256).Hash -ne $env:INSTALLER_HASH) { throw 'Download hash does not match' }; ` + Start-Process -Wait -FilePath C:\Windows\System32\msiexec.exe -ArgumentList '/i C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi /qn /l*vx C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.log' + +ENTRYPOINT ["powershell.exe", "-ExecutionPolicy", "Bypass"] +CMD ["-NoExit"] + +# Download and install Remote Debugger +RUN $ErrorActionPreference = 'Stop' ; ` + $ProgressPreference = 'SilentlyContinue' ; ` + $VerbosePreference = 'Continue' ; ` + New-Item -Path C:\Downloads -Type Directory | Out-Null ; ` + Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/?LinkId=746570&clcid=0x409' -OutFile C:\Downloads\vs_remotetools.exe ; ` + Start-Process -Wait -FilePath C:\Downloads\vs_remotetools.exe -ArgumentList '-q' ; ` + Remove-Item -Path C:\Downloads\vs_remotetools.exe + +# Configure Remote Debugger +EXPOSE 3702 4022 4023 +RUN $ErrorActionPreference = 'Stop' ; ` + $VerbosePreference = 'Continue' ; ` + Start-Process -Wait -FilePath 'C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe' -ArgumentList '/prepcomputer', '/private', '/quiet' + +HEALTHCHECK --interval=10s CMD ["powershell.exe", "-ExecutionPolicy", "Bypass", "-Command", "&{ if (Get-Process msvsmon) { exit 0 } else { exit 1 } }"] diff --git a/docker/Dockerfile b/docker/Dockerfile index f4cc1f5..1ee4de1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,24 +1,23 @@ +#escape=` + # Copyright (C) Microsoft Corporation. All rights reserved. # Licensed under the MIT license. See LICENSE.txt in the project root for license information. -FROM heaths/vssetup:latest +# Based on latest image cached by Azure Pipelines: https://docs.microsoft.com/azure/devops/pipelines/agents/hosted#software +FROM microsoft/windowsservercore@sha256:c60a7376f5147e40b65c51fce34ac17710742f97e91b5c3a71e1667e671112f1 SHELL ["powershell.exe", "-ExecutionPolicy", "Bypass", "-Command"] -# Download and install Remote Debugger -RUN $ErrorActionPreference = 'Stop' ; \ - $ProgressPreference = 'SilentlyContinue' ; \ - $VerbosePreference = 'Continue' ; \ - New-Item -Path C:\Downloads -Type Directory | Out-Null ; \ - Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/?LinkId=746570&clcid=0x409' -OutFile C:\Downloads\vs_remotetools.exe ; \ - Start-Process -Wait -FilePath C:\Downloads\vs_remotetools.exe -ArgumentList '-q' ; \ - Remove-Item -Path C:\Downloads\vs_remotetools.exe +ENV INSTALLER_VERSION=1.14.190.31519 ` + INSTALLER_URI=https://download.visualstudio.microsoft.com/download/pr/100516681/d68d54e233c956ff79799fdf63753c54/Microsoft.VisualStudio.Setup.Configuration.msi ` + INSTALLER_HASH=8917aa7b4116e574856d43e8e62862c1d6f25512be54917f2ef95f9cac103810 -# Configure Remote Debugger -EXPOSE 3702 4022 4023 -RUN $ErrorActionPreference = 'Stop' ; \ - $VerbosePreference = 'Continue' ; \ - Start-Process -Wait -FilePath 'C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe' -ArgumentList '/prepcomputer', '/private', '/quiet' +# Download and register the query API +RUN $ErrorActionPreference = 'Stop' ; ` + $VerbosePreference = 'Continue' ; ` + $null = New-Item C:\TEMP -ItemType Directory -ea SilentlyContinue; ` + Invoke-WebRequest -Uri $env:INSTALLER_URI -OutFile C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi; ` + if ((Get-FileHash -Path C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi -Algorithm SHA256).Hash -ne $env:INSTALLER_HASH) { throw 'Download hash does not match' }; ` + Start-Process -Wait -FilePath C:\Windows\System32\msiexec.exe -ArgumentList '/i C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.msi /qn /l*vx C:\TEMP\Microsoft.VisualStudio.Setup.Configuration.log' -# Start Remote Debugger if no other command is passed to PowerShell -ENTRYPOINT ["powershell.exe", "-ExecutionPolicy", "Unrestricted"] -CMD ["-NoExit", "-Command", "& 'C:\\Program Files\\Microsoft Visual Studio 15.0\\Common7\\IDE\\Remote Debugger\\x64\\msvsmon.exe' /silent /noauth /anyuser"] +ENTRYPOINT ["powershell.exe", "-ExecutionPolicy", "Bypass"] +CMD ["-NoExit"] diff --git a/docker/appveyor/Dockerfile b/docker/appveyor/Dockerfile deleted file mode 100644 index f70860e..0000000 --- a/docker/appveyor/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. See LICENSE.txt in the project root for license information. - -# Would prefer to only use "image" in docker-compose.yml, but AppVeyor version of docker-compose fails -# stating that a "Dockerfile" in the current directory does not exist. -FROM heaths/vssetup:latest diff --git a/docker/appveyor/docker-compose.yml b/docker/appveyor/docker-compose.yml deleted file mode 100644 index 8fc7b17..0000000 --- a/docker/appveyor/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (C) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. See LICENSE.txt in the project root for license information. - -version: "2.1" -services: - test: - # Need to override build context since AppVeyor version of docker-compose fails with just "image". - build: . - extends: - file: ../docker-compose.yml - service: test - command: -c Invoke-Pester C:\Tests -EnableExit -OutputFile C:\Tests\Results.xml -OutputFormat NUnitXml diff --git a/docker/docker-compose.debug.yml b/docker/docker-compose.debug.yml new file mode 100644 index 0000000..8912e14 --- /dev/null +++ b/docker/docker-compose.debug.yml @@ -0,0 +1,16 @@ +# Copyright (C) Microsoft Corporation. All rights reserved. +# Licensed under the MIT license. See LICENSE.txt in the project root for license information. + +version: "2.1" +services: + test: + image: microsoft/vssetup:debug + build: + context: . + dockerfile: Debug.dockerfile + network_mode: nat + expose: + - "3702/udp" + - "4022-4023" + command: > + -Command "&'C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe' /silent /noauth /anyuser" diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c035dac..81f5197 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -14,7 +14,5 @@ services: - C:/VS/Enterprise - C:/BuildTools - C:/VS/Preview - network_mode: nat - expose: - - "3702/udp" - - "4022-4023" + network_mode: none + command: -Command Invoke-Pester C:\Tests -EnableExit diff --git a/tools/Publish-Release.ps1 b/tools/Publish-Release.ps1 deleted file mode 100644 index a4b2b5d..0000000 --- a/tools/Publish-Release.ps1 +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (C) Microsoft Corporation. All rights reserved. -# Licensed under the MIT license. See LICENSE.txt in the project root for license information. - -[CmdletBinding()] -param ( - [Parameter(Mandatory = $true)] - [string] $Token, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [string] $Owner = 'Microsoft', - - [Parameter(Mandatory = $true)] - [string] $Repository, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [string] $Tag = $env:BUILD_BUILDNUMBER, - - [Parameter()] - [string] $Commit = $env:BUILD_SOURCEVERSION, - - [Parameter()] - [string] $Name, - - [Parameter()] - [string] $Description, - - [Parameter()] - [switch] $Draft, - - [Parameter()] - [switch] $Prerelease, - - [Parameter(Mandatory = $true)] - [string] $Path, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [string] $ContentType = 'application/octet-stream', - - [Parameter()] - [string] $ContentName, - - [Parameter()] - [string] $ContentLabel -) - -$ErrorActionPreference = 'Stop' - -if (-not $Tag) { - throw '$Tag is required (default value not available)' -} - -$uri = "https://api.github.com/repos/$Owner/$Repository/releases" -$values = @{ - tag_name = $Tag - draft = $Draft.ToBool() - prerelease = $Prerelease.ToBool() -} - -if ($Commit) { - $values.target_commitish = $Commit -} - -if ($Name) { - $values.name = $Name -} else { - $values.name = $Tag -} - -if ($Description) { - $values.body = $Description -} - -$request = ConvertTo-Json $values -$headers = @{ - Authorization = "token $Token" - Accept = 'application/vnd.github.v3+json' -} - -# Make sure TLS 1.2 is supported now that GitHub requires it. -[System.Net.ServicePointManager]::SecurityProtocol += 'Tls12' - -$release = Invoke-RestMethod -Uri $uri -Method Post -Body $request -Headers $headers -$upload_url = $release.upload_url -replace '\{\?.*$', '' - -Write-Verbose "Release '$($release.id)' created; upload URI: $upload_url" - -$Path = Resolve-Path $Path | Convert-Path - -$headers.Add('Content-Type', $ContentType) -if (-not $ContentName) { - $ContentName = [System.IO.Path]::GetFileName($Path) -} - -$uri = $upload_url + "?name=$ContentName" -if ($ContentLabel) { - $uri += "&label=$ContentLabel" -} - -$asset = Invoke-RestMethod -Uri $uri -Method Post -InFile $Path -Headers $headers -if ($asset.state -eq 'uploaded') { - Write-Verbose "Successfully uploaded: $($asset.browser_download_url)" -} diff --git a/tools/test.ps1 b/tools/test.ps1 index 5726d92..6b7ea58 100644 --- a/tools/test.ps1 +++ b/tools/test.ps1 @@ -12,8 +12,11 @@ param ( [string] $Platform = $env:PLATFORM, [Parameter()] - [ValidateSet('Unit', 'Integration')] - [string[]] $Type = @('Unit', 'Integration') + [ValidateSet('Unit', 'Integration', 'Functional', 'Runtime')] + [string[]] $Type = @('Functional', 'Runtime'), + + [Parameter()] + [switch] $Download ) if (-not $Configuration) { @@ -26,7 +29,7 @@ if (-not $Platform) { [bool] $Failed = $false -if ($Type -contains 'Unit') +if ($Type -contains 'Unit' -or $Type -contains 'Functional') { # Find vstest.console.exe. $cmd = get-command vstest.console.exe -ea SilentlyContinue | select-object -expand Path @@ -51,12 +54,6 @@ if ($Type -contains 'Unit') exit 1 } - # Set up logger for AppVeyor. - $logger = if ($env:APPVEYOR -eq 'true') { - write-verbose 'Using AppVeyor logger when running in an AppVeyor build.' - '/logger:appveyor' - } - # Discover test assemblies for the current configuration. $assemblies = get-childitem test -include *.test.dll -recurse | where-object { $_.fullname -match "\\bin\\$Configuration\\" @@ -74,16 +71,17 @@ if ($Type -contains 'Unit') } } -if ($Type -contains 'Integration') +if ($Type -contains 'Integration' -or $Type -contains 'Runtime') { - # Run docker integration tests. - if (get-command docker-compose -ea SilentlyContinue) { - [string] $path = if ($env:APPVEYOR -eq 'true') { - $no_tty = '-T' - resolve-path "$PSScriptRoot\..\docker\appveyor\docker-compose.yml" - } else { - resolve-path "$PSScriptRoot\..\docker\docker-compose.yml" - } + # Run docker runtime tests. + $cmd = (get-command docker-compose -ea SilentlyContinue).Path + if (-not $cmd -and $Download) { + invoke-webrequest 'https://github.com/docker/compose/releases/download/1.11.2/docker-compose-Windows-x86_64.exe' -outfile "${env:TEMP}\docker-compose.exe" + $cmd = "${env:TEMP}\docker-compose.exe" + } + + if ($cmd) { + [string] $path = resolve-path "$PSScriptRoot\..\docker\docker-compose.yml" $verbose = if ($VerbosePreference -eq 'Continue') { '--verbose' @@ -98,7 +96,7 @@ if ($Type -contains 'Integration') write-verbose "Running tests in '$path'" try { - docker-compose -f "$path" $verbose run $no_tty --rm test -c Invoke-Pester C:\Tests -EnableExit -OutputFile C:\Tests\Results.xml -OutputFormat NUnitXml + & $cmd -f "$path" $verbose run --rm test if (-not $?) { $Failed = $true } @@ -106,15 +104,8 @@ if ($Type -contains 'Integration') $env:CONFIGURATION = $OldConfiguration $env:PLATFORM = $OldPlatform } - - if ($env:APPVEYOR_JOB_ID) { - [string] $path = resolve-path "$PSScriptRoot\..\docker\Tests\Results.xml" - $url = "https://ci.appveyor.com/api/testresults/nunit/${env:APPVEYOR_JOB_ID}" - - write-verbose "Uploading '$path' to '$url'" - $wc = new-object System.Net.WebClient - $wc.UploadFile($url, $path) - } + } else { + write-warning 'Failed to find docker-compose; integration tests will not be performed.' } if ($Failed) {