diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e32eb1a1c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: cpp - -git: - depth: 1000 - -env: - # Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds - DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - -matrix: - include: - - os: linux - dist: trusty - sudo: required - - os: osx - osx_image: xcode9.4 - -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update; - brew install openssl; - mkdir -p /usr/local/lib; - ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; - ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; - elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - sudo apt-get install libunwind8; - fi - -install: - - pushd scripts - - bash <(curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh) - - popd - -script: - - ulimit -n 4096 - - pwsh -File scripts/travis.ps1 diff --git a/.vsts-ci/azure-pipelines-ci.yml b/.vsts-ci/azure-pipelines-ci.yml new file mode 100644 index 000000000..e12ee8277 --- /dev/null +++ b/.vsts-ci/azure-pipelines-ci.yml @@ -0,0 +1,44 @@ +trigger: +- master +- legacy/1.x +variables: + # Don't download unneeded packages + - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE + value: 'true' + # Don't send telemetry + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: 'true' +jobs: +- job: Windows_powershell + pool: + vmImage: 'VS2017-Win2016' + steps: + - powershell: scripts/azurePipelinesBuild.ps1 + - task: PublishTestResults@2 + inputs: + testRunner: VSTest + testResultsFiles: '**/*.trx' + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + inputs: + ArtifactName: PowerShellEditorServices + PathtoPublish: '$(Build.ArtifactStagingDirectory)' + + +- job: Windows_pwsh + pool: + vmImage: 'VS2017-Win2016' + steps: + - template: templates/ci-general.yml + +- job: macOS + pool: + vmImage: 'macOS-10.13' + steps: + - template: templates/ci-general.yml + +- job: Linux + pool: + vmImage: 'Ubuntu-16.04' + steps: + - template: templates/ci-general.yml diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml new file mode 100644 index 000000000..328370aa3 --- /dev/null +++ b/.vsts-ci/templates/ci-general.yml @@ -0,0 +1,11 @@ +steps: + - pwsh: scripts/azurePipelinesBuild.ps1 + - task: PublishTestResults@2 + inputs: + testRunner: VSTest + testResultsFiles: '**/*.trx' + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + inputs: + ArtifactName: PowerShellEditorServices + PathtoPublish: '$(Build.ArtifactStagingDirectory)' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f68bb80f6..99fd971ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,14 +1,14 @@ # Contribution Guidelines -We welcome many kinds of community contributions to this project! Whether it's a feature implementation, -bug fix, or a good idea, please create an issue so that we can discuss it. It is not necessary to create an -issue before sending a pull request but it may speed up the process if we can discuss your idea before +We welcome many kinds of community contributions to this project! Whether it's a feature implementation, +bug fix, or a good idea, please create an issue so that we can discuss it. It is not necessary to create an +issue before sending a pull request but it may speed up the process if we can discuss your idea before you start implementing it. -Because this project exposes a couple different public APIs, we must be very mindful of any potential breaking -changes. Some contributions may not be accepted if they risk introducing breaking changes or if they +Because this project exposes a couple different public APIs, we must be very mindful of any potential breaking +changes. Some contributions may not be accepted if they risk introducing breaking changes or if they don't match the goals of the project. The core maintainer team has the right of final approval over -any contribution to this project. However, we are very happy to hear community feedback on any decision +any contribution to this project. However, we are very happy to hear community feedback on any decision so that we can ensure we are solving the right problems in the right way. **NOTE**: If you believe there is a security vulnerability, please see [Security Reporting](#security-reporting). @@ -31,7 +31,7 @@ Here's a high level list of guidelines to follow to ensure your code contributio - Follow established guidelines for commit hygiene - Write unit tests to validate new features and bug fixes - Ensure that the 'Release' build and unit tests pass locally -- Ensure that the AppVeyor build passes for your change +- Ensure that the Azure DevOps build passes for your change - Respond to all review feedback and final commit cleanup ### Practice Good Commit Hygiene @@ -44,46 +44,46 @@ so that your commits provide a good history of the changes you are making. To b Commit messages should be clearly written so that a person can look at the commit log and understand how and why a given change was made. Here is a great model commit message taken from a [blog post by Tim Pope](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html): - + Capitalized, short (50 chars or less) summary - + More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. - + Write your commit message in the imperative: "Fix bug" and not "Fixed bug" or "Fixes bug." This convention matches up with commit messages generated by commands like git merge and git revert. - + Further paragraphs come after blank lines. - + - Bullet points are okay, too - + - Typically a hyphen or asterisk is used for the bullet, followed by a single space, with blank lines in between, but conventions vary here - + - Use a hanging indent - + A change that fixes a known bug with an issue filed should use the proper syntax so that the [issue - is automatically closed](https://help.github.com/articles/closing-issues-via-commit-messages/) once + is automatically closed](https://help.github.com/articles/closing-issues-via-commit-messages/) once your change is merged. Here's an example of what such a commit message should look like: - + Fix #3: Catch NullReferenceException from DoThing - + This change adds a try/catch block to catch a NullReferenceException that gets thrown by DoThing [...] - **Squash your commits** - If you are introducing a new feature but have implemented it over multiple commits, - please [squash those commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) + If you are introducing a new feature but have implemented it over multiple commits, + please [squash those commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) into a single commit that contains all the changes in one place. This especially applies to any "oops" - commits where a file is forgotten or a typo is being fixed. Following this approach makes it a lot easier + commits where a file is forgotten or a typo is being fixed. Following this approach makes it a lot easier to pull those changes to other branches or roll back the change if necessary. - + - **Keep individual commits for larger changes** You can certainly maintain individual commits for different phases of a big change. For example, if @@ -96,10 +96,10 @@ so that your commits provide a good history of the changes you are making. To b If you're adding a new feature to the project, please make sure to include adequate [xUnit](http://xunit.github.io/) tests with your change. In this project, we have chosen write out unit tests in a way that uses the actual PowerShell environment rather than extensive interface mocking. This allows us to be sure that -our features will work in practice. +our features will work in practice. -We do both component-level and scenario-level testing depending on what code is being tested. We don't -expect contributors to test every possible edge case. Testing mainline scenarios and the most common +We do both component-level and scenario-level testing depending on what code is being tested. We don't +expect contributors to test every possible edge case. Testing mainline scenarios and the most common failure scenarios is often good enough. We are very happy to accept unit test contributions for any feature areas that are more error-prone than @@ -118,7 +118,7 @@ on this check so that our project will always have good generated documentation. - **Create your pull request** - Use the [typical process](https://help.github.com/articles/using-pull-requests/) to send a pull request + Use the [typical process](https://help.github.com/articles/using-pull-requests/) to send a pull request from your fork of the project. In your pull request message, please give a high-level summary of the changes that you have made so that reviewers understand the intent of the changes. You should receive initial comments within a day or two, but please feel free to ping if things are taking longer than @@ -126,7 +126,7 @@ on this check so that our project will always have good generated documentation. - **The build and unit tests must run green** - When you submit your pull request, our automated build system on AppVeyor will attempt to run a + When you submit your pull request, our automated build system on Azure DevOps will attempt to run a Release build of your changes and then run all unit tests against the build. If you notice that any of your unit tests have failed, please fix them by creating a new commit and then pushing it to your branch. If you see that some unrelated test has failed, try re-running the build for your @@ -137,15 +137,15 @@ on this check so that our project will always have good generated documentation. If the reviewers ask you to make changes, make them as a new commit to your branch and push them so that they are made available for a final review pass. Do not rebase the fixes just yet so that the - commit hash changes don't upset GitHub's pull request UI. - + commit hash changes don't upset GitHub's pull request UI. + - **If necessary, do a final rebase** Once your final changes have been accepted, we may ask you to do a final rebase to have your commits so that they follow our commit guidelines. If specific guidance is given, please follow it when - rebasing your commits. Once you do your final push and we see the AppVeyor build pass, we will + rebasing your commits. Once you do your final push and we see the Azure DevOps build pass, we will merge your changes! - + ### Security Reporting If you believe that there is a security vulnerability in the PowerShell extension for VSCode, diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index d21f3f73b..9991125b5 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -18,7 +18,7 @@ param( #Requires -Modules @{ModuleName="InvokeBuild";ModuleVersion="3.2.1"} -$script:IsCIBuild = $env:APPVEYOR -ne $null +$script:IsCIBuild = $env:TF_BUILD -ne $null $script:IsUnix = $PSVersionTable.PSEdition -and $PSVersionTable.PSEdition -eq "Core" -and !$IsWindows $script:TargetPlatform = "netstandard2.0" $script:TargetFrameworksParam = "/p:TargetFrameworks=`"$script:TargetPlatform`"" @@ -264,8 +264,11 @@ task GetProductVersion -Before PackageNuGet, PackageModule, UploadArtifacts { $script:BuildNumber = 9999 $script:VersionSuffix = $props.Project.PropertyGroup.VersionSuffix - if ($env:APPVEYOR) { - $script:BuildNumber = $env:APPVEYOR_BUILD_NUMBER + if ($env:TF_BUILD) { + # SYSTEM_PHASENAME is the Job name. + # Job names can only include `_` but that's not a valid character for versions. + $jobname = $env:SYSTEM_PHASENAME -replace '_', '' + $script:BuildNumber = "$jobname-$env:BUILD_BUILDNUMBER" } if ($script:VersionSuffix -ne $null) { @@ -285,12 +288,7 @@ task CreateBuildInfo -Before Build { $buildOrigin = "" # Set build info fields on build platforms - if ($env:APPVEYOR) - { - $buildVersion = $env:APPVEYOR_BUILD_VERSION - $buildOrigin = if ($env:CI) { "AppVeyor CI" } else { "AppVeyor" } - } - elseif ($env:TF_BUILD) + if ($env:TF_BUILD) { $psd1Path = [System.IO.Path]::Combine($PSScriptRoot, "module", "PowerShellEditorServices", "PowerShellEditorServices.psd1") $buildVersion = (Import-PowerShellDataFile -LiteralPath $psd1Path).Version @@ -331,24 +329,6 @@ task Build { exec { & $script:dotnetExe build -c $Configuration .\src\PowerShellEditorServices.VSCode\PowerShellEditorServices.VSCode.csproj $script:TargetFrameworksParam } } -function UploadTestLogs { - if ($script:IsCIBuild) { - $testLogsPath = "$PSScriptRoot/test/PowerShellEditorServices.Test.Host/bin/$Configuration/net452/logs" - $testLogsZipPath = "$PSScriptRoot/TestLogs.zip" - - if (Test-Path $testLogsPath) { - [System.IO.Compression.ZipFile]::CreateFromDirectory( - $testLogsPath, - $testLogsZipPath) - - Push-AppveyorArtifact $testLogsZipPath - } - else { - Write-Host "`n### WARNING: Test logs could not be found!`n" -ForegroundColor Yellow - } - } -} - function DotNetTestFilter { # Reference https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests if ($TestFilter) { @("--filter",$TestFilter) } else { "" } @@ -360,11 +340,11 @@ task TestServer { Set-Location .\test\PowerShellEditorServices.Test\ if (-not $script:IsUnix) { - exec { & $script:dotnetExe test -f $script:TestRuntime.Desktop (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:TestRuntime.Desktop (DotNetTestFilter) } } Invoke-WithCreateDefaultHook -NewModulePath $script:PSCoreModulePath { - exec { & $script:dotnetExe test -f $script:TestRuntime.Core (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:TestRuntime.Core (DotNetTestFilter) } } } @@ -372,11 +352,11 @@ task TestProtocol { Set-Location .\test\PowerShellEditorServices.Test.Protocol\ if (-not $script:IsUnix) { - exec { & $script:dotnetExe test -f $script:TestRuntime.Desktop (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:TestRuntime.Desktop (DotNetTestFilter) } } Invoke-WithCreateDefaultHook { - exec { & $script:dotnetExe test -f $script:TestRuntime.Core (DotNetTestFilter) } + exec { & $script:dotnetExe test --logger trx -f $script:TestRuntime.Core (DotNetTestFilter) } } } @@ -392,15 +372,6 @@ task TestHost { exec { & $script:dotnetExe test -f $script:TestRuntime.Core (DotNetTestFilter) } } -task CITest ?Test, { - # This task is used to ensure we have a chance to upload - # test logs as a CI artifact when the tests fail - if (error Test) { - UploadTestLogs - Write-Error "Failing build due to test failure." - } -} - task LayoutModule -After Build { # Copy Third Party Notices.txt to module folder Copy-Item -Force -Path "$PSScriptRoot\Third Party Notices.txt" -Destination $PSScriptRoot\module\PowerShellEditorServices @@ -519,14 +490,9 @@ task PackageModule { $false) } -task UploadArtifacts -If ($script:IsCIBuild) { - if ($env:APPVEYOR) { - Push-AppveyorArtifact .\src\PowerShellEditorServices\bin\$Configuration\Microsoft.PowerShell.EditorServices.$($script:FullVersion).nupkg - Push-AppveyorArtifact .\src\PowerShellEditorServices.Protocol\bin\$Configuration\Microsoft.PowerShell.EditorServices.Protocol.$($script:FullVersion).nupkg - Push-AppveyorArtifact .\src\PowerShellEditorServices.Host\bin\$Configuration\Microsoft.PowerShell.EditorServices.Host.$($script:FullVersion).nupkg - Push-AppveyorArtifact .\PowerShellEditorServices-$($script:FullVersion).zip - } +task UploadArtifacts -If ($null -ne $env:TF_BUILD) { + Copy-Item -Path .\PowerShellEditorServices-$($script:FullVersion).zip -Destination $env:BUILD_ARTIFACTSTAGINGDIRECTORY } # The default task is to run the entire CI build -task . GetProductVersion, Clean, Build, CITest, BuildCmdletHelp, PackageNuGet, PackageModule, UploadArtifacts +task . GetProductVersion, Clean, Build, Test, BuildCmdletHelp, PackageNuGet, PackageModule, UploadArtifacts diff --git a/README.md b/README.md index fcd67b0f8..b0dfe8431 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # PowerShell Editor Services +[![Build Status](https://powershell.visualstudio.com/PowerShellEditorServices/_apis/build/status/PowerShellEditorServices-ci?branchName=master)](https://powershell.visualstudio.com/PowerShellEditorServices/_build/latest?definitionId=50&branchName=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/fb9129c327dc4f459ad2fd167d9a574f)](https://app.codacy.com/app/TylerLeonhardt/PowerShellEditorServices?utm_source=github.com&utm_medium=referral&utm_content=PowerShell/PowerShellEditorServices&utm_campaign=Badge_Grade_Dashboard) [![Join the chat at https://gitter.im/PowerShell/PowerShellEditorServices](https://badges.gitter.im/PowerShell/PowerShellEditorServices.svg)](https://gitter.im/PowerShell/PowerShellEditorServices?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -35,12 +36,6 @@ and communicate with it over named pipes (or Unix domain sockets on macOS & Linu and [Debug Adapter Protocol](https://github.com/Microsoft/vscode-debugadapter-node/blob/master/protocol/src/debugProtocol.ts). Detailed usage documentation for this module is coming soon! -## Build Status - -| AppVeyor (Windows) | Travis CI (Linux / macOS) | -|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| -| [![Build status](https://ci.appveyor.com/api/projects/status/85tyhckawwxoiim2/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/powershelleditorservices/branch/master) | [![Build Status](https://travis-ci.org/PowerShell/PowerShellEditorServices.svg?branch=master)](https://travis-ci.org/PowerShell/PowerShellEditorServices) | - ## Documentation Check out our **[documentation site](http://powershell.github.io/PowerShellEditorServices)** for information about diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 992e234f6..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: '2.0.0-{build}' -image: Visual Studio 2017 -clone_depth: 10 -skip_tags: true - -environment: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true # Don't download unneeded packages - DOTNET_CLI_TELEMETRY_OPTOUT: true # Don't send telemetry - -install: - - ps: | - Get-Module PowerShellGet,PackageManagement | Remove-Module -Force -Verbose - powershell -Command { Install-Module -Name PowershellGet -MinimumVersion 1.6 -force -confirm:$false -verbose } - powershell -Command { Install-Module -Name PackageManagement -MinimumVersion 1.1.7.0 -Force -Confirm:$false -Verbose } - Import-Module -Name PowerShellGet -MinimumVersion 1.6 -Force - Import-Module -Name PackageManagement -MinimumVersion 1.1.7.0 -Force - Install-PackageProvider -Name NuGet -Force | Out-Null - Import-PackageProvider NuGet -Force | Out-Null - Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null - Install-Module InvokeBuild -MaximumVersion 5.1.0 -Scope CurrentUser -Force | Out-Null - Install-Module platyPS -RequiredVersion 0.9.0 -Scope CurrentUser -Force | Out-Null - -build_script: - - ps: Invoke-Build -Configuration Release - -# The build script takes care of the tests -test: off diff --git a/scripts/azurePipelinesBuild.ps1 b/scripts/azurePipelinesBuild.ps1 new file mode 100644 index 000000000..ab31ed358 --- /dev/null +++ b/scripts/azurePipelinesBuild.ps1 @@ -0,0 +1,17 @@ +$ErrorActionPreference = 'Stop' + +Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null +if ($IsWindows -or $PSVersionTable.PSVersion.Major -lt 6) { + # We rely on PowerShellGet's -AllowPrerelease which is in PowerShellGet 1.6 so we need to update PowerShellGet. + Get-Module PowerShellGet,PackageManagement | Remove-Module -Force -Verbose + powershell -Command { Install-Module -Name PowerShellGet -MinimumVersion 1.6 -Force -Confirm:$false -Verbose } + powershell -Command { Install-Module -Name PackageManagement -MinimumVersion 1.1.7.0 -Force -Confirm:$false -Verbose } + Import-Module -Name PowerShellGet -MinimumVersion 1.6 -Force + Import-Module -Name PackageManagement -MinimumVersion 1.1.7.0 -Force +} + +# Needed for build and docs gen. +Install-Module InvokeBuild -MaximumVersion 5.1.0 -Scope CurrentUser +Install-Module PlatyPS -RequiredVersion 0.9.0 -Scope CurrentUser + +Invoke-Build -Configuration Release diff --git a/scripts/travis.ps1 b/scripts/travis.ps1 deleted file mode 100644 index abcb12fe2..000000000 --- a/scripts/travis.ps1 +++ /dev/null @@ -1,10 +0,0 @@ -$ErrorActionPreference = 'Stop' - -# Install InvokeBuild -Install-Module InvokeBuild -MaximumVersion 5.1.0 -Scope CurrentUser -Force -Install-Module PlatyPS -RequiredVersion 0.9.0 -Scope CurrentUser -Force - - -# Build the code and perform tests -Import-module InvokeBuild -Invoke-Build -Configuration Release diff --git a/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs b/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs index cb9203ca1..cfa965b65 100644 --- a/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs +++ b/test/PowerShellEditorServices.Test/Session/WorkspaceTests.cs @@ -17,6 +17,12 @@ public class WorkspaceTests { private static readonly Version PowerShellVersion = new Version("5.0"); + private static readonly Lazy s_lazyDriveLetter = new Lazy(() => Path.GetFullPath("\\").Substring(0, 1)); + + public static string CurrentDriveLetter => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? s_lazyDriveLetter.Value + : string.Empty; + [Fact] public void CanResolveWorkspaceRelativePath() { @@ -103,12 +109,12 @@ public static IEnumerable PathsToResolve new object[] { "file:///C%3A/banana/", @"C:\banana\" }, new object[] { "file:///C%3A/banana/ex.ps1", @"C:\banana\ex.ps1" }, new object[] { "file:///E%3A/Path/to/awful%23path", @"E:\Path\to\awful#path" }, - new object[] { "file:///path/with/no/drive", @"C:\path\with\no\drive" }, - new object[] { "file:///path/wi[th]/squ[are/brackets/", @"C:\path\wi[th]\squ[are\brackets\" }, - new object[] { "file:///Carrots/A%5Ere/Good/", @"C:\Carrots\A^re\Good\" }, - new object[] { "file:///Users/barnaby/%E8%84%9A%E6%9C%AC/Reduce-Directory", @"C:\Users\barnaby\脚本\Reduce-Directory" }, + new object[] { "file:///path/with/no/drive", $@"{CurrentDriveLetter}:\path\with\no\drive" }, + new object[] { "file:///path/wi[th]/squ[are/brackets/", $@"{CurrentDriveLetter}:\path\wi[th]\squ[are\brackets\" }, + new object[] { "file:///Carrots/A%5Ere/Good/", $@"{CurrentDriveLetter}:\Carrots\A^re\Good\" }, + new object[] { "file:///Users/barnaby/%E8%84%9A%E6%9C%AC/Reduce-Directory", $@"{CurrentDriveLetter}:\Users\barnaby\脚本\Reduce-Directory" }, new object[] { "file:///C%3A/Program%20Files%20%28x86%29/PowerShell/6/pwsh.exe", @"C:\Program Files (x86)\PowerShell\6\pwsh.exe" }, - new object[] { "file:///home/maxim/test%20folder/%D0%9F%D0%B0%D0%BF%D0%BA%D0%B0/helloworld.ps1", @"C:\home\maxim\test folder\Папка\helloworld.ps1" } + new object[] { "file:///home/maxim/test%20folder/%D0%9F%D0%B0%D0%BF%D0%BA%D0%B0/helloworld.ps1", $@"{CurrentDriveLetter}:\home\maxim\test folder\Папка\helloworld.ps1" } }; private static object[][] s_unixPathsToResolve = new object[][]