From 18c3732959866fadc3a8985feb93275a0fd6bc29 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 21 Jul 2021 14:22:05 -0700 Subject: [PATCH 01/11] Fix bug in `ReleaseTools` with `Confirm` in CI --- tools/ReleaseTools.psm1 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/ReleaseTools.psm1 b/tools/ReleaseTools.psm1 index b3719dd2a1..36c605e60c 100644 --- a/tools/ReleaseTools.psm1 +++ b/tools/ReleaseTools.psm1 @@ -368,13 +368,12 @@ function New-ReleasePR { $Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName $Params = @{ - Head = $Branch - Base = "master" - Draft = $true - Title = "Release ``v$Version``" - Body = "Automated PR for new release!" - WhatIf = $WhatIfPreference - Confirm = $ConfirmPreference + Head = $Branch + Base = "master" + Draft = $true + Title = "Release ``v$Version``" + Body = "Automated PR for new release!" + # TODO: Fix passing Confirm/WhatIf (again) } $PR = $Repo | New-GitHubPullRequest @Params @@ -417,8 +416,7 @@ function New-DraftRelease { PreRelease = [bool]$Version.PreReleaseLabel OwnerName = "PowerShell" RepositoryName = $RepositoryName - WhatIf = $WhatIfPreference - Confirm = $ConfirmPreference + # TODO: Fix passing Confirm/WhatIf (again) } $Release = New-GitHubRelease @ReleaseParams From b3353c0e22ca426d2a6bc5754e726d2f950d8204 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Fri, 23 Jul 2021 12:00:38 -0700 Subject: [PATCH 02/11] Replace `ResolveEditorServicesPath` task with `Get-EditorServicesPath` function --- vscode-powershell.build.ps1 | 55 +++++++++++-------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) diff --git a/vscode-powershell.build.ps1 b/vscode-powershell.build.ps1 index 143a54a299..fb6e0aa9a3 100644 --- a/vscode-powershell.build.ps1 +++ b/vscode-powershell.build.ps1 @@ -12,31 +12,15 @@ $script:PackageJson = Get-Content -Raw $PSScriptRoot/package.json | ConvertFrom- $script:IsPreviewExtension = $script:PackageJson.name -like "*preview*" -or $script:PackageJson.displayName -like "*preview*" Write-Host "`n### Extension Version: $($script:PackageJson.version) Extension Name: $($script:PackageJson.name)`n" -ForegroundColor Green -#region Utility tasks - -# TODO: This needs to be a function, not a task. -task ResolveEditorServicesPath -Before CleanEditorServices, BuildEditorServices, TestEditorServices, Package { - - $script:psesRepoPath = ` - if ($EditorServicesRepoPath) { - $EditorServicesRepoPath - } - else { - "$PSScriptRoot/../PowerShellEditorServices/" - } - - if (!(Test-Path "$script:psesRepoPath/PowerShellEditorServices.build.ps1")) { - # Clear the path so that it won't be used - Write-Warning "`nThe PowerShellEditorServices repo cannot be found at path $script:psesRepoPath`n" - $script:psesRepoPath = $null - } - else { - $script:psesRepoPath = Resolve-Path $script:psesRepoPath - $script:psesBuildScriptPath = Resolve-Path "$script:psesRepoPath/PowerShellEditorServices.build.ps1" +function Get-EditorServicesPath { + $psesRepoPath = if ($EditorServicesRepoPath) { + $EditorServicesRepoPath + } else { + "$PSScriptRoot/../PowerShellEditorServices/" } + return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" } -#endregion #region Restore tasks task Restore RestoreNodeModules -If { -not (Test-Path "$PSScriptRoot/node_modules") } @@ -61,11 +45,9 @@ task Clean { Remove-Item -Force -Recurse node_modules -ErrorAction Ignore } -task CleanEditorServices { - if ($script:psesBuildScriptPath) { - Write-Host "`n### Cleaning PowerShellEditorServices`n" -ForegroundColor Green - Invoke-Build Clean $script:psesBuildScriptPath - } +task CleanEditorServices -If (Get-EditorServicesPath) { + Write-Host "`n### Cleaning PowerShellEditorServices`n" -ForegroundColor Green + Invoke-Build Clean (Get-EditorServicesPath) } task CleanAll CleanEditorServices, Clean @@ -78,12 +60,9 @@ task Build Restore, { exec { & npm run compile } } -task BuildEditorServices { - # If the PSES codebase is co-located, build it first - if ($script:psesBuildScriptPath) { - Write-Host "`n### Building PowerShellEditorServices`n" -ForegroundColor Green - Invoke-Build Build $script:psesBuildScriptPath - } +task BuildEditorServices -If (Get-EditorServicesPath) { + Write-Host "`n### Building PowerShellEditorServices`n" -ForegroundColor Green + Invoke-Build Build (Get-EditorServicesPath) } task BuildAll BuildEditorServices, Build @@ -100,11 +79,9 @@ task Test Build, { exec { & npm run test } } -task TestEditorServices { - if ($script:psesBuildScriptPath) { - Write-Host "`n### Testing PowerShellEditorServices`n" -ForegroundColor Green - Invoke-Build Test $script:psesBuildScriptPath - } +task TestEditorServices -If (Get-EditorServicesPath) { + Write-Host "`n### Testing PowerShellEditorServices`n" -ForegroundColor Green + Invoke-Build Test (Get-EditorServicesPath) } task TestAll TestEditorServices, Test @@ -130,7 +107,7 @@ task UpdateReadme -If { $script:IsPreviewExtension } { } task Package UpdateReadme, { - if ($script:psesBuildScriptPath -or $env:TF_BUILD) { + if (Get-EditorServicesPath -or $env:TF_BUILD) { Write-Host "`n### Copying PowerShellEditorServices module files" -ForegroundColor Green Copy-Item -Recurse -Force ..\PowerShellEditorServices\module\* .\modules } else { From 23e9a2f59c0432de9ec21887b89709906cc238e1 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Tue, 13 Jul 2021 13:19:33 -0700 Subject: [PATCH 03/11] Setup to use `release` branches for ADO This will let us use the pipeline trigger because we can set the default branch for manual/scheduled/pipeline-triggered builds to `release` (but cannot set it to a variable branch, like `release/vX.Y.Z`). --- .vsts-ci/azure-pipelines-release.yml | 13 +++---------- docs/development.md | 24 +++++++++++------------- tools/ReleaseTools.psm1 | 28 +++++++++++----------------- 3 files changed, 25 insertions(+), 40 deletions(-) diff --git a/.vsts-ci/azure-pipelines-release.yml b/.vsts-ci/azure-pipelines-release.yml index e71f8b2555..3420fc1a53 100644 --- a/.vsts-ci/azure-pipelines-release.yml +++ b/.vsts-ci/azure-pipelines-release.yml @@ -6,10 +6,7 @@ variables: - name: DOTNET_CLI_TELEMETRY_OPTOUT value: 'true' -trigger: - branches: - include: - - release/* +trigger: none resources: repositories: @@ -20,12 +17,8 @@ resources: pipelines: - pipeline: PowerShellEditorServices source: PowerShellEditorServices - trigger: - branches: - include: - - release/* - tags: - - v* + trigger: true + jobs: - job: 'ReleaseBuild' diff --git a/docs/development.md b/docs/development.md index 25acdd7308..1960249d75 100644 --- a/docs/development.md +++ b/docs/development.md @@ -67,24 +67,23 @@ Microsoft. The comments are manual steps. Import-Module ./tools/ReleaseTools.psm1 Update-Changelog -RepositoryName PowerShellEditorServices -Version Update-Changelog -RepositoryName vscode-powershell -Version -# Amend changelog as necessary -# Download and test assets (assert correct PSES is included) -New-DraftRelease -RepositoryName PowerShellEditorServices -Assets "PowerShellEditorServices.zip" -New-DraftRelease -RepositoryName vscode-powershell -Assets "powershell-YYYY.M.X.vsix", "Install-VSCode.ps1" +# Amend changelog as necessary, open PR +# Push release branches to ADO +# Permit both pipelines to draft GitHub releases +# Download and test assets # Check telemetry for stability before releasing # Publish draft releases and merge (don't squash!) branches -vsce publish --packagePath ./PowerShell-.vsix -# Update Install-VSCode.ps1 on gallery -Publish-Script -Path ./Install-VSCode.ps1 -NuGetApiKey (Get-Secret "PowerShell Gallery API Key" -AsPlainText) +# Permit vscode-extension pipeline to publish to marketplace ``` ### Versioning -For both our repositories we use Git tags in the form `vX.Y.Z` to mark the -releases in the codebase. We use the GitHub Release feature to create these -tags. Branches are used in the process of creating a release, e.g. -`release/vX.Y.Z`, but are deleted after the release is completed (and merged -into `master`). +For both our repositories we use Git tags in the form `vX.Y.Z` to mark the releases in the +codebase. We use the GitHub Release feature to create these tags. The ephemeral branch +`release` is used in the process of creating a release for each repository, primarily for +the Pull Requests and for Azure DevOps triggers. Once the release PRs are merged, the +branch is deleted until used again to prepare the next release. This branch _does not_ +mark any specific release, that is the point of the tags. For PowerShellEditor Services, we simply follow semantic versioning, e.g. `vX.Y.Z`. We do not release previews frequently because this dependency is not @@ -130,4 +129,3 @@ use the same code which includes dependencies). * `Update-Changelog` should verify the version is in the correct format * `Update-Changelog` could be faster by not downloading _every_ PR -* A `Publish-Binaries` function could be written to push the binaries out diff --git a/tools/ReleaseTools.psm1 b/tools/ReleaseTools.psm1 index 36c605e60c..6b00ea6396 100644 --- a/tools/ReleaseTools.psm1 +++ b/tools/ReleaseTools.psm1 @@ -136,26 +136,21 @@ function Get-FirstChangelog { <# .SYNOPSIS - Creates and checks out `release/v` if not already on it. + Creates and checks out `release` if not already on it. #> function Update-Branch { [CmdletBinding(SupportsShouldProcess)] - param( - [Parameter(Mandatory)] - [string]$Version - ) $Branch = git branch --show-current - $NewBranch = "release/v$Version" - if ($Branch -ne $NewBranch) { - if ($PSCmdlet.ShouldProcess($NewBranch, "git checkout -b")) { - git checkout -b $NewBranch + if ($Branch -ne "release") { + if ($PSCmdlet.ShouldProcess("release", "git checkout -b")) { + git checkout -b "release" } } } <# .SYNOPSIS - Gets current version from changelog as [semver]. + Gets current version from changelog as `[semver]`. #> function Get-Version { param( @@ -176,10 +171,9 @@ function Get-Version { .SYNOPSIS Updates the CHANGELOG file with PRs merged since the last release. .DESCRIPTION - Uses the local Git repositories but does not pull, so ensure HEAD is where - you want it. Creates a new branch at 'release/$Version' if not already - checked out. Handles any merge option for PRs, but is a little slow as it - queries all PRs. + Uses the local Git repositories but does not pull, so ensure HEAD is where you + want it. Creates the branch `release` if not already checked out. Handles any + merge option for PRs, but is a little slow as it queries all PRs. #> function Update-Changelog { [CmdletBinding(SupportsShouldProcess)] @@ -238,7 +232,7 @@ function Update-Changelog { $CurrentChangelog[2..$CurrentChangelog.Length] ) | Set-Content -Encoding utf8NoBOM -Path $ChangelogFile - Update-Branch -Version $Version.Substring(1) # Has "v" prefix + Update-Branch if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) { git add $ChangelogFile @@ -328,7 +322,7 @@ function Update-Version { } } - Update-Branch -Version $Version + Update-Branch if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) { git commit -m "Bump version to ``v$Version``" @@ -409,7 +403,7 @@ function New-DraftRelease { $ReleaseParams = @{ # NOTE: We rely on GitHub to create the tag at that branch. Tag = "v$Version" - Committish = "release/v$Version" + Committish = "release" Name = "v$Version" Body = $ChangeLog Draft = $true From 1e933f18414ef5fc1e222975e2dd302ca195ba37 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Fri, 23 Jul 2021 13:35:47 -0700 Subject: [PATCH 04/11] Add `setupReleaseTools.ps1` script This installs the necessary modules and authenticates using a given GitHub token so that the Azure pipelines can use our `ReleaseTools` module to publish to GitHub. --- tools/setupReleaseTools.ps1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tools/setupReleaseTools.ps1 diff --git a/tools/setupReleaseTools.ps1 b/tools/setupReleaseTools.ps1 new file mode 100644 index 0000000000..6a57a9fc6c --- /dev/null +++ b/tools/setupReleaseTools.ps1 @@ -0,0 +1,17 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +param( + [Parameter(Mandatory)] + [string]$Token +) + +Write-Host "Install and import PowerShell modules" +Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null +Install-Module -Name PowerShellForGitHub -Scope CurrentUser -Force +Import-Module $PSScriptRoot/ReleaseTools.psm1 + +Write-Host "Setup authentication" +Set-GitHubConfiguration -SuppressTelemetryReminder +$password = ConvertTo-SecureString -String $Token -AsPlainText -Force +Set-GitHubAuthentication -Credential (New-Object System.Management.Automation.PSCredential ("token", $password)) From 23029506d56f59ea8c138f76ec905651e72a87d9 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Fri, 23 Jul 2021 13:39:26 -0700 Subject: [PATCH 05/11] Small cleanups --- .vsts-ci/azure-pipelines-ci.yml | 14 ++++++++------ .vsts-ci/azure-pipelines-release.yml | 2 ++ .vsts-ci/templates/ci-general.yml | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.vsts-ci/azure-pipelines-ci.yml b/.vsts-ci/azure-pipelines-ci.yml index 73e761d389..a96aa6f4f2 100644 --- a/.vsts-ci/azure-pipelines-ci.yml +++ b/.vsts-ci/azure-pipelines-ci.yml @@ -9,26 +9,28 @@ variables: value: 'true' trigger: - batch: true branches: include: - master jobs: -- job: Windows +- job: Win2019 + displayName: Windows Server 2019 pool: - vmImage: 'windows-2019' + vmImage: windows-2019 steps: - template: templates/ci-general.yml - job: macOS + displayName: macOS 10.15 pool: - vmImage: 'macOS-10.15' + vmImage: macOS-10.15 steps: - template: templates/ci-general.yml -- job: Linux +- job: Ubuntu + displayName: Ubuntu 20.04 pool: - vmImage: 'Ubuntu-20.04' + vmImage: Ubuntu-20.04 steps: - template: templates/ci-general.yml diff --git a/.vsts-ci/azure-pipelines-release.yml b/.vsts-ci/azure-pipelines-release.yml index 3420fc1a53..46086c2efe 100644 --- a/.vsts-ci/azure-pipelines-release.yml +++ b/.vsts-ci/azure-pipelines-release.yml @@ -1,3 +1,5 @@ +name: Release-$(Build.SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.rr) + variables: # Don't download unneeded packages - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml index 80daf4a81a..f27765328e 100644 --- a/.vsts-ci/templates/ci-general.yml +++ b/.vsts-ci/templates/ci-general.yml @@ -15,7 +15,7 @@ steps: displayName: Install PowerShell Daily - pwsh: '$PSVersionTable' - displayName: Display PowerShell version information + displayName: PowerShell version - pwsh: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))" displayName: Set Build Name for Non-PR @@ -32,6 +32,7 @@ steps: - pwsh: Invoke-Build - task: PublishTestResults@2 + displayName: Publish test results inputs: testRunner: JUnit testResultsFiles: '**/test-results.xml' From c6928b052fc9f3eef4386fe98cd7e72884977de9 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Fri, 23 Jul 2021 13:39:49 -0700 Subject: [PATCH 06/11] Remove PowerShell daily from CI This CI has to test the extension, not the daily build. We shouldn't conflate the two. --- .vsts-ci/templates/ci-general.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml index f27765328e..dd76297ea5 100644 --- a/.vsts-ci/templates/ci-general.yml +++ b/.vsts-ci/templates/ci-general.yml @@ -1,19 +1,4 @@ steps: - # Setup - - powershell: | - Write-Host "Installing PowerShell Daily..." - - # Use `AGENT_TEMPDIRECTORY` to make sure the downloaded PowerShell is cleaned up. - $powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell' - Invoke-WebRequest -Uri https://aka.ms/install-powershell.ps1 -OutFile ./install-powershell.ps1 - - ./install-powershell.ps1 -Destination $powerShellPath -Daily - - # Using `prependpath` to update the PATH just for this build. - Write-Host "##vso[task.prependpath]$powerShellPath" - continueOnError: true - displayName: Install PowerShell Daily - - pwsh: '$PSVersionTable' displayName: PowerShell version From cb63102f71cd9a3449329e2be380ae9d9a2d103f Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Tue, 27 Jul 2021 11:23:11 -0700 Subject: [PATCH 07/11] Fix side effect logic in `ReleaseTools` module This uses a new function `Use-Repository` that executes the given script with the given repository as the current working directory, replacing all the previously side effect driven logic, or at least, making it more explicit. This was frankly easier than dealing with the Azure Pipeline that clones the repository under a different name (specifically `s` if its the only repo, that is, it's not named `vscode-powershell` in the release stage, so the module broke). --- tools/ReleaseTools.psm1 | 205 +++++++++++++++++++++--------------- vscode-powershell.build.ps1 | 4 +- 2 files changed, 122 insertions(+), 87 deletions(-) diff --git a/tools/ReleaseTools.psm1 b/tools/ReleaseTools.psm1 index 6b00ea6396..d882d3a2c4 100644 --- a/tools/ReleaseTools.psm1 +++ b/tools/ReleaseTools.psm1 @@ -14,11 +14,41 @@ class RepoNames: IValidateSetValuesGenerator { $ChangelogFile = "CHANGELOG.md" +<# +.SYNOPSIS + Given the repository name, execute the script in its directory. +#> +function Use-Repository { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [ValidateSet([RepoNames])] + [string]$RepositoryName, + + [Parameter(Mandatory)] + [scriptblock]$Script + ) + try { + switch ($RepositoryName) { + "vscode-powershell" { + Push-Location -Path "$PSScriptRoot/../" + } + "PowerShellEditorServices" { + Push-Location -Path "$PSScriptRoot/../../PowerShellEditorServices" + } + } + & $Script + } finally { + Pop-Location + } +} + <# .SYNOPSIS Given a collection of PRs, generates a bulleted list. #> function Get-Bullets { + [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet([RepoNames])] @@ -124,7 +154,9 @@ function Get-FirstChangelog { [ValidateSet([RepoNames])] [string]$RepositoryName ) - $Changelog = Get-Content -Path "$PSScriptRoot/../../$RepositoryName/$ChangelogFile" + $Changelog = Use-Repository -RepositoryName $RepositoryName -Script { + Get-Content -Path $ChangelogFile + } # NOTE: The space after the header marker is important! Otherwise ### matches. $Header = $Changelog.Where({$_.StartsWith("## ")}, "First") $Changelog.Where( @@ -140,10 +172,17 @@ function Get-FirstChangelog { #> function Update-Branch { [CmdletBinding(SupportsShouldProcess)] - $Branch = git branch --show-current - if ($Branch -ne "release") { - if ($PSCmdlet.ShouldProcess("release", "git checkout -b")) { - git checkout -b "release" + param( + [Parameter(Mandatory)] + [ValidateSet([RepoNames])] + [string]$RepositoryName + ) + Use-Repository -RepositoryName $RepositoryName -Script { + $Branch = git branch --show-current + if ($Branch -ne "release") { + if ($PSCmdlet.ShouldProcess("release", "git checkout -b")) { + git checkout -b "release" + } } } } @@ -187,12 +226,12 @@ function Update-Changelog { [ValidateScript({ $_.StartsWith("v") })] [string]$Version ) - # NOTE: This a side effect neccesary for Git operations to work. - Push-Location -Path "$PSScriptRoot/../../$RepositoryName" # Get the repo object, latest release, and commits since its tag. $Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName - $Commits = git rev-list "v$(Get-Version -RepositoryName $RepositoryName)..." + $Commits = Use-Repository -RepositoryName $RepositoryName -Script { + git rev-list "v$(Get-Version -RepositoryName $RepositoryName)..." + } # NOTE: This is a slow API as it gets all PRs, and then filters. $Bullets = $Repo | Get-GitHubPullRequest -State All | @@ -220,28 +259,27 @@ function Update-Changelog { } } - $CurrentChangelog = Get-Content -Path $ChangelogFile - - @( - $CurrentChangelog[0..1] - "## $Version" - "### $([datetime]::Now.ToString('dddd, MMMM dd, yyyy'))" - "" - $NewSection - "" - $CurrentChangelog[2..$CurrentChangelog.Length] - ) | Set-Content -Encoding utf8NoBOM -Path $ChangelogFile - - Update-Branch - - if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) { - git add $ChangelogFile - git commit -m "Update CHANGELOG for ``$Version``" + Update-Branch -RepositoryName $RepositoryName + + Use-Repository -RepositoryName $RepositoryName -Script { + $CurrentChangelog = Get-Content -Path $ChangelogFile + @( + $CurrentChangelog[0..1] + "## $Version" + "### $([datetime]::Now.ToString('dddd, MMMM dd, yyyy'))" + "" + $NewSection + "" + $CurrentChangelog[2..$CurrentChangelog.Length] + ) | Set-Content -Encoding utf8NoBOM -Path $ChangelogFile + + if ($PSCmdlet.ShouldProcess("$RepositoryName/$ChangelogFile", "git commit")) { + git add $ChangelogFile + git commit -m "Update CHANGELOG for ``$Version``" + } } Update-Version -RepositoryName $RepositoryName - - Pop-Location } <# @@ -274,63 +312,62 @@ function Update-Version { [ValidateSet([RepoNames])] [string]$RepositoryName ) - # NOTE: This a side effect neccesary for Git operations to work. - Push-Location -Path "$PSScriptRoot/../../$RepositoryName" - $Version = Get-Version -RepositoryName $RepositoryName $v = "$($Version.Major).$($Version.Minor).$($Version.Patch)" + + Update-Branch -RepositoryName $RepositoryName + # TODO: Maybe cleanup the replacement logic. - switch ($RepositoryName) { - "vscode-powershell" { - $d = "Develop PowerShell modules, commands and scripts in Visual Studio Code!" - if ($Version.PreReleaseLabel) { - $name = "powershell-preview" - $displayName = "PowerShell Preview" - $preview = "true" - $description = "(Preview) $d" - } else { - $name = "powershell" - $displayName = "PowerShell" - $preview = "false" - $description = $d + Use-Repository -RepositoryName $RepositoryName -Script { + switch ($RepositoryName) { + "vscode-powershell" { + $d = "Develop PowerShell modules, commands and scripts in Visual Studio Code!" + if ($Version.PreReleaseLabel) { + $name = "powershell-preview" + $displayName = "PowerShell Preview" + $preview = "true" + $description = "(Preview) $d" + } else { + $name = "powershell" + $displayName = "PowerShell" + $preview = "false" + $description = $d + } + + $path = "package.json" + $f = Get-Content -Path $path + # NOTE: The prefix regex match two spaces exactly to avoid matching + # nested objects in the file. + $f = $f -replace '^(? "name":\s+")(.+)(?",)$', "`${prefix}${name}`${suffix}" + $f = $f -replace '^(? "displayName":\s+")(.+)(?",)$', "`${prefix}${displayName}`${suffix}" + $f = $f -replace '^(? "version":\s+")(.+)(?",)$', "`${prefix}${v}`${suffix}" + $f = $f -replace '^(? "preview":\s+)(.+)(?,)$', "`${prefix}${preview}`${suffix}" + $f = $f -replace '^(? "description":\s+")(.+)(?",)$', "`${prefix}${description}`${suffix}" + $f | Set-Content -Path $path + git add $path + } + "PowerShellEditorServices" { + $path = "PowerShellEditorServices.Common.props" + $f = Get-Content -Path $path + $f = $f -replace '^(?\s+)(.+)(?)$', "`${prefix}${v}`${suffix}" + $f = $f -replace '^(?\s+)(.*)(?)$', "`${prefix}$($Version.PreReleaseLabel)`${suffix}" + $f | Set-Content -Path $path + git add $path + + $path = "module/PowerShellEditorServices/PowerShellEditorServices.psd1" + $f = Get-Content -Path $path + $f = $f -replace "^(?ModuleVersion = ')(.+)(?')`$", "`${prefix}${v}`${suffix}" + $f | Set-Content -Path $path + git add $path } - $path = "package.json" - $f = Get-Content -Path $path - # NOTE: The prefix regex match two spaces exactly to avoid matching - # nested objects in the file. - $f = $f -replace '^(? "name":\s+")(.+)(?",)$', "`${prefix}${name}`${suffix}" - $f = $f -replace '^(? "displayName":\s+")(.+)(?",)$', "`${prefix}${displayName}`${suffix}" - $f = $f -replace '^(? "version":\s+")(.+)(?",)$', "`${prefix}${v}`${suffix}" - $f = $f -replace '^(? "preview":\s+)(.+)(?,)$', "`${prefix}${preview}`${suffix}" - $f = $f -replace '^(? "description":\s+")(.+)(?",)$', "`${prefix}${description}`${suffix}" - $f | Set-Content -Path $path - git add $path - } - "PowerShellEditorServices" { - $path = "PowerShellEditorServices.Common.props" - $f = Get-Content -Path $path - $f = $f -replace '^(?\s+)(.+)(?)$', "`${prefix}${v}`${suffix}" - $f = $f -replace '^(?\s+)(.*)(?)$', "`${prefix}$($Version.PreReleaseLabel)`${suffix}" - $f | Set-Content -Path $path - git add $path - - $path = "module/PowerShellEditorServices/PowerShellEditorServices.psd1" - $f = Get-Content -Path $path - $f = $f -replace "^(?ModuleVersion = ')(.+)(?')`$", "`${prefix}${v}`${suffix}" - $f | Set-Content -Path $path - git add $path } - } - - Update-Branch - if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) { - git commit -m "Bump version to ``v$Version``" - } # TODO: Git reset to unstage + if ($PSCmdlet.ShouldProcess("$RepositoryName/v$Version", "git commit")) { + git commit -m "Bump version to ``v$Version``" + } # TODO: Git reset to unstage + } New-ReleasePR -RepositoryName $RepositoryName - - Pop-Location } <# @@ -346,17 +383,15 @@ function New-ReleasePR { [ValidateSet([RepoNames])] [string]$RepositoryName ) - # NOTE: This a side effect neccesary for Git operations to work. - Push-Location -Path "$PSScriptRoot/../../$RepositoryName" - $Version = Get-Version -RepositoryName $RepositoryName $Branch = "release/v$Version" - Update-Branch -Version $Version - - if ($PSCmdlet.ShouldProcess("$RepositoryName/$Branch", "git push")) { - Write-Host "Pushing branch ``$Branch``..." - git push origin $Branch + Update-Branch -RepositoryName $RepositoryName + Use-Repository -RepositoryName $RepositoryName -Script { + if ($PSCmdlet.ShouldProcess("$RepositoryName/$Branch", "git push")) { + Write-Host "Pushing branch ``$Branch``..." + git push origin $Branch + } } $Repo = Get-GitHubRepository -OwnerName PowerShell -RepositoryName $RepositoryName @@ -376,8 +411,6 @@ function New-ReleasePR { # NOTE: The API is weird. According to GitHub, all PRs are Issues, so this # works, but the module doesn't support it as easily as it could. $Repo | Add-GitHubIssueLabel -Issue $PR.PullRequestNumber -LabelName "Ignore" - - Pop-Location } <# diff --git a/vscode-powershell.build.ps1 b/vscode-powershell.build.ps1 index fb6e0aa9a3..9607770d3b 100644 --- a/vscode-powershell.build.ps1 +++ b/vscode-powershell.build.ps1 @@ -18,7 +18,9 @@ function Get-EditorServicesPath { } else { "$PSScriptRoot/../PowerShellEditorServices/" } - return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" + # NOTE: The ErrorActionPreference for both Invoke-Build and Azure DevOps + # scripts is Stop, but we want to continue and return false here. + return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" -ErrorAction Continue } #region Restore tasks From 5d764183720fdb94ccb7826fa8dbcbe25a687ab1 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 28 Jul 2021 13:20:08 -0700 Subject: [PATCH 08/11] Improve build script Restoration of modules including PowerShellEditorServices was made automatic upon invocation of the `Build` task. This replaced complicated logic in the package task to restore PSES in CI. --- vscode-powershell.build.ps1 | 60 ++++++++++++------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/vscode-powershell.build.ps1 b/vscode-powershell.build.ps1 index 9607770d3b..5b7b8cac5c 100644 --- a/vscode-powershell.build.ps1 +++ b/vscode-powershell.build.ps1 @@ -23,28 +23,22 @@ function Get-EditorServicesPath { return Resolve-Path "$psesRepoPath/PowerShellEditorServices.build.ps1" -ErrorAction Continue } -#region Restore tasks - -task Restore RestoreNodeModules -If { -not (Test-Path "$PSScriptRoot/node_modules") } - -task RestoreNodeModules { - +task Restore -If { !(Test-Path "$PSScriptRoot/node_modules") } { Write-Host "`n### Restoring vscode-powershell dependencies`n" -ForegroundColor Green - # When in a CI build use the --loglevel=error parameter so that # package install warnings don't cause PowerShell to throw up $logLevelParam = if ($env:TF_BUILD) { "--loglevel=error" } else { "" } exec { & npm install $logLevelParam } } -#endregion + #region Clean tasks task Clean { Write-Host "`n### Cleaning vscode-powershell`n" -ForegroundColor Green - Remove-Item .\modules\* -Exclude "README.md" -Recurse -Force -ErrorAction Ignore - Remove-Item .\out -Recurse -Force -ErrorAction Ignore - Remove-Item -Force -Recurse node_modules -ErrorAction Ignore + Remove-Item ./modules -Exclude "README.md" -Recurse -Force -ErrorAction Ignore + Remove-Item ./out -Recurse -Force -ErrorAction Ignore + Remove-Item ./node_modules -Recurse -Force -ErrorAction Ignore } task CleanEditorServices -If (Get-EditorServicesPath) { @@ -57,26 +51,27 @@ task CleanAll CleanEditorServices, Clean #endregion #region Build tasks -task Build Restore, { - Write-Host "`n### Building vscode-powershell" -ForegroundColor Green - exec { & npm run compile } -} - task BuildEditorServices -If (Get-EditorServicesPath) { Write-Host "`n### Building PowerShellEditorServices`n" -ForegroundColor Green Invoke-Build Build (Get-EditorServicesPath) } +task CopyEditorServices -If { !(Test-Path ./modules/PowerShellEditorServices) -and (Get-EditorServicesPath) } BuildEditorServices, { + Write-Host "`n### Copying PowerShellEditorServices module files" -ForegroundColor Green + Copy-Item -Recurse -Force "$(Split-Path (Get-EditorServicesPath))/module/*" ./modules +} + +task Build CopyEditorServices, Restore, { + Write-Host "`n### Building vscode-powershell" -ForegroundColor Green + exec { & npm run compile } +} + task BuildAll BuildEditorServices, Build #endregion #region Test tasks -task Test Build, { - if ($env:TF_BUILD -and $global:IsLinux) { - Write-Warning "Skipping extension tests in Linux CI because vscode does not support it." - return - } +task Test -If (!($env:TF_BUILD -and $global:IsLinux)) Build, { Write-Host "`n### Running extension tests" -ForegroundColor Green exec { & npm run test } } @@ -109,28 +104,11 @@ task UpdateReadme -If { $script:IsPreviewExtension } { } task Package UpdateReadme, { - if (Get-EditorServicesPath -or $env:TF_BUILD) { - Write-Host "`n### Copying PowerShellEditorServices module files" -ForegroundColor Green - Copy-Item -Recurse -Force ..\PowerShellEditorServices\module\* .\modules - } else { - throw "Unable to find PowerShell EditorServices" - } - - $packageName = "$($script:PackageJson.name)-$($script:PackageJson.version).vsix" - Write-Host "`n### Packaging $packageName`n" -ForegroundColor Green + assert { Test-Path ./modules/PowerShellEditorServices } + Write-Host "`n### Packaging $($script:PackageJson.name)-$($script:PackageJson.version).vsix`n" -ForegroundColor Green exec { & node ./node_modules/vsce/out/vsce package --no-gitHubIssueLinking } - - if ($env:TF_BUILD) { - $artifactsPath = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY/vscode-powershell/" - "./$packageName", "./scripts/Install-VSCode.ps1" | ForEach-Object { - Copy-Item -Verbose -Recurse $_ $artifactsPath - } - } } #endregion -# The set of tasks for a release -task Release Clean, Build, Package -# The default task is to run the entire CI build -task . CleanAll, BuildAll, Test, Package +task . Build, Test, Package From 660ab455632e34ef653daa56f235e166f0fba9aa Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 28 Jul 2021 13:24:54 -0700 Subject: [PATCH 09/11] Cleanup miscellaneous build Mostly we moved the Rich Code Navigation Indexer task. --- .vsts-ci/misc-analysis.yml | 39 +++++++++++++++++++++++-------- .vsts-ci/templates/ci-general.yml | 11 --------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/.vsts-ci/misc-analysis.yml b/.vsts-ci/misc-analysis.yml index 0832d62eb0..388993c01c 100644 --- a/.vsts-ci/misc-analysis.yml +++ b/.vsts-ci/misc-analysis.yml @@ -1,21 +1,40 @@ name: PR-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)$(Rev:.rr) + trigger: - # Batch merge builds together while a merge build is running - batch: true branches: include: - master - - legacy/1.x pr: - branches: - include: - - master - - legacy/1.x +- master resources: -- repo: self - clean: true + repositories: + - repository: ComplianceRepo + type: github + endpoint: GitHub + name: PowerShell/compliance jobs: -- template: templates/credscan.yml +- job: Compliance + pool: + vmImage: windows-latest + steps: + - checkout: self + - checkout: ComplianceRepo + - template: ci-compliance.yml@ComplianceRepo +# NOTE: This enables our project to work with Visual Studio's Rich Navigation: +# https://visualstudio.microsoft.com/services/rich-code-navigation/ +- job: RichCodeNav + pool: + vmImage: windows-latest + steps: + # TODO: Move to GitHub Action + - task: RichCodeNavIndexer@0 + continueOnError: true + inputs: + serviceConnection: rich-nav + nugetServiceConnection: rich-nav-nuget + githubServiceConnection: PowerShell + languages: typescript,csharp + serviceEndpoint: https://prod.richnav.vsengsaas.visualstudio.com diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml index dd76297ea5..0deba86f4a 100644 --- a/.vsts-ci/templates/ci-general.yml +++ b/.vsts-ci/templates/ci-general.yml @@ -28,14 +28,3 @@ steps: ArtifactName: vscode-powershell PathtoPublish: '$(Build.ArtifactStagingDirectory)/vscode-powershell' - # Rich Navigation - - task: RichCodeNavIndexer@0 - # Note, for now, this is Windows only. - condition: and(succeededOrFailed(), eq(variables['Agent.OS'], 'Windows_NT')) - continueOnError: true - inputs: - serviceConnection: 'rich-nav' - nugetServiceConnection: 'rich-nav-nuget' - githubServiceConnection: 'PowerShell' - languages: 'typescript,csharp' - serviceEndpoint: 'https://prod.richnav.vsengsaas.visualstudio.com' From a987d4d78b3e776d1748f8903ebbe86b1814f0b7 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 28 Jul 2021 13:25:49 -0700 Subject: [PATCH 10/11] Make CI build template actually generic This now uses a repository resource or the triggering pipeline artifact to provide the PowerShellEditorServices sources (or bits). Coupled with the change to the build script, this means the template can be used to build for CI or for a release. We also moved to zipped pipeline artifacts as build artifacts have been deprecated, but we need to reduce the cost of the stored artifacts themselves. These are provided for developers to test and for the release pipeline to use. --- .vsts-ci/azure-pipelines-ci.yml | 8 ++++ .vsts-ci/templates/ci-general.yml | 71 +++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/.vsts-ci/azure-pipelines-ci.yml b/.vsts-ci/azure-pipelines-ci.yml index a96aa6f4f2..d53ec24773 100644 --- a/.vsts-ci/azure-pipelines-ci.yml +++ b/.vsts-ci/azure-pipelines-ci.yml @@ -13,6 +13,14 @@ trigger: include: - master +resources: + repositories: + - repository: PowerShellEditorServices + type: github + endpoint: GitHub + name: PowerShell/PowerShellEditorServices + ref: master + jobs: - job: Win2019 displayName: Windows Server 2019 diff --git a/.vsts-ci/templates/ci-general.yml b/.vsts-ci/templates/ci-general.yml index 0deba86f4a..668369ba00 100644 --- a/.vsts-ci/templates/ci-general.yml +++ b/.vsts-ci/templates/ci-general.yml @@ -1,30 +1,57 @@ +parameters: + - name: usePipelineArtifact + type: boolean + default: false + steps: - - pwsh: '$PSVersionTable' +- pwsh: $PSVersionTable displayName: PowerShell version - - pwsh: Write-Host "##vso[build.updatebuildnumber]$env:BUILD_SOURCEBRANCHNAME-$env:BUILD_SOURCEVERSION-$((get-date).ToString("yyyyMMddhhmmss"))" - displayName: Set Build Name for Non-PR - condition: ne(variables['Build.Reason'], 'PullRequest') +- checkout: self - # TODO: Use a submodule or some such so we can actually track a version here. - - pwsh: | - git clone https://github.com/PowerShell/PowerShellEditorServices.git ../PowerShellEditorServices - Install-Module InvokeBuild -Scope CurrentUser -Force - Install-Module PlatyPS -Scope CurrentUser -Force - New-Item -ItemType Directory $(Build.ArtifactStagingDirectory)/vscode-powershell +# NOTE: We either checkout the Git repo for PowerShellEditorServices, or we +# download a pre-built artifact from the triggering pipeline and extract it to +# the modules folder. In this way we do not accidentally build a release of the +# server from this pipeline. +- checkout: PowerShellEditorServices + condition: not(${{ parameters.usePipelineArtifact }}) - # Build - - pwsh: Invoke-Build +- task: DownloadPipelineArtifact@2 + condition: ${{ parameters.usePipelineArtifact }} + displayName: Download PowerShellEditorServices + inputs: + source: specific + project: PowerShellEditorServices + pipeline: 36 + preferTriggeringPipeline: true + allowPartiallySucceededBuilds: true + artifact: PowerShellEditorServices - - task: PublishTestResults@2 - displayName: Publish test results - inputs: - testRunner: JUnit - testResultsFiles: '**/test-results.xml' - condition: succeededOrFailed() +- task: ExtractFiles@1 + condition: ${{ parameters.usePipelineArtifact }} + displayName: Extract PowerShellEditorServices module + inputs: + archiveFilePatterns: $(Pipeline.Workspace)/PowerShellEditorServices.zip + destinationFolder: $(Build.SourcesDirectory)/vscode-powershell/modules + +- pwsh: | + Install-Module InvokeBuild -Scope CurrentUser -Force + Invoke-Build + Write-Host "##vso[task.setvariable variable=vsixPath]$(Resolve-Path powershell-*.vsix)" + displayName: Build and test + workingDirectory: $(Build.SourcesDirectory)/vscode-powershell - - task: PublishBuildArtifacts@1 - inputs: - ArtifactName: vscode-powershell - PathtoPublish: '$(Build.ArtifactStagingDirectory)/vscode-powershell' +- publish: $(vsixPath) + artifact: vscode-powershell-vsix-$(System.JobId) + displayName: Publish extension artifact +- publish: $(Build.SourcesDirectory)/vscode-powershell/scripts/Install-VSCode.ps1 + artifact: vscode-powershell-unsigned-script-$(System.JobId) + displayName: Publish unsigned script artifact + +- task: PublishTestResults@2 + displayName: Publish test results + inputs: + testRunner: JUnit + testResultsFiles: '**/test-results.xml' + condition: succeededOrFailed() From 35704b8474a3159b891c05dd8505c2209bc02d8f Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 28 Jul 2021 13:31:01 -0700 Subject: [PATCH 11/11] Pipeline-ify release process This sets up the Azure DevOps release pipeline to not only build, test, and sign the bits for a release (and to do so using signed PowerShellEditorServices bits), but to automatically create the GitHub draft release where it directly uploads the artifacts. After manual approval, it will automatically publish the extension and installation script to their respective registries (the Visual Studio Code marketplace and the PowerShell Gallery). Best of all, this process is kicked off automatically after a successful release build of PowerShellEditorServices. --- .vsts-ci/azure-pipelines-release.yml | 78 +++++++++++++++++++++----- .vsts-ci/templates/publish-github.yml | 11 ++++ .vsts-ci/templates/publish-markets.yml | 17 ++++++ .vsts-ci/templates/release-general.yml | 73 +++++++++--------------- 4 files changed, 117 insertions(+), 62 deletions(-) create mode 100644 .vsts-ci/templates/publish-github.yml create mode 100644 .vsts-ci/templates/publish-markets.yml diff --git a/.vsts-ci/azure-pipelines-release.yml b/.vsts-ci/azure-pipelines-release.yml index 46086c2efe..d8b104074e 100644 --- a/.vsts-ci/azure-pipelines-release.yml +++ b/.vsts-ci/azure-pipelines-release.yml @@ -14,21 +14,71 @@ resources: repositories: - repository: ComplianceRepo type: github - endpoint: ComplianceGHRepo + endpoint: GitHub name: PowerShell/Compliance + + - repository: PowerShellEditorServices + type: git + name: PowerShellEditorServices + ref: release + pipelines: - pipeline: PowerShellEditorServices source: PowerShellEditorServices - trigger: true - - -jobs: -- job: 'ReleaseBuild' - displayName: 'Build release' - pool: - name: '1ES' - demands: ImageOverride -equals MMS2019 - variables: - - group: ESRP - steps: - - template: templates/release-general.yml + trigger: + branches: + - release + +stages: +- stage: Build + displayName: Build the release + jobs: + - job: Build + pool: + vmImage: windows-2019 + steps: + - template: templates/ci-general.yml + parameters: + usePipelineArtifact: true + +- stage: Sign + displayName: Sign the release + jobs: + - job: Sign + pool: + name: 1ES + demands: ImageOverride -equals MMS2019 + variables: + - group: ESRP + steps: + - template: templates/release-general.yml + +- stage: PublishGitHub + displayName: Publish the draft release + jobs: + - deployment: Publish + environment: vscode-powershell-github + pool: + vmImage: ubuntu-latest + variables: + - group: Publish + strategy: + runOnce: + deploy: + steps: + - template: templates/publish-github.yml + +- stage: PublishMarkets + displayName: Publish to marketplace and gallery + jobs: + - deployment: Publish + environment: vscode-powershell-markets + pool: + vmImage: ubuntu-latest + variables: + - group: Publish + strategy: + runOnce: + deploy: + steps: + - template: templates/publish-markets.yml diff --git a/.vsts-ci/templates/publish-github.yml b/.vsts-ci/templates/publish-github.yml new file mode 100644 index 0000000000..c2c17feeda --- /dev/null +++ b/.vsts-ci/templates/publish-github.yml @@ -0,0 +1,11 @@ +steps: +- checkout: self + +- download: current + artifact: vscode-powershell + displayName: Download signed artifacts + +- pwsh: | + $(Build.SourcesDirectory)/tools/setupReleaseTools.ps1 -Token $(GitHubToken) + New-DraftRelease -RepositoryName vscode-powershell -Assets $(Pipeline.Workspace)/vscode-powershell/powershell-*.vsix,$(Pipeline.Workspace)/vscode-powershell/Install-VSCode.ps1 + displayName: Drafting a GitHub Release diff --git a/.vsts-ci/templates/publish-markets.yml b/.vsts-ci/templates/publish-markets.yml new file mode 100644 index 0000000000..dcc6366f44 --- /dev/null +++ b/.vsts-ci/templates/publish-markets.yml @@ -0,0 +1,17 @@ +steps: +- checkout: self + +- download: current + artifact: vscode-powershell + displayName: Download signed artifacts + +- pwsh: | + npm install -g vsce + vsce publish --packagePath $(Pipeline.Workspace)/powershell-*.vsix --pat $(VsceToken) + displayName: Publishing VSIX to VS Code Marketplace + +# NOTE: We rarely update this script, so we can ignore errors from the gallery +# caused by us trying to re-publish an updated script. +- pwsh: | + Publish-Script -Path $(Pipeline.Workspace)/Install-VSCode.ps1 -ErrorAction Continue -NuGetApiKey $(GalleryToken) + displayName: Publishing Install-VSCode.ps1 to PowerShell Gallery diff --git a/.vsts-ci/templates/release-general.yml b/.vsts-ci/templates/release-general.yml index 47220e3dc3..a90a467a28 100644 --- a/.vsts-ci/templates/release-general.yml +++ b/.vsts-ci/templates/release-general.yml @@ -1,70 +1,47 @@ steps: -- checkout: self - -- pwsh: | - Get-ChildItem -Path env: - displayName: Capture environment - condition: succeededOrFailed() - -- task: DownloadPipelineArtifact@2 - displayName: 'Download Artifacts from PowerShellEditorServices' - inputs: - source: specific - project: 'PowerShellEditorServices' - pipeline: 36 - preferTriggeringPipeline: true - allowPartiallySucceededBuilds: true - artifact: 'PowerShellEditorServices' - path: '$(Build.SourcesDirectory)/PowerShellEditorServices/module/' - -- pwsh: | - New-Item -ItemType Directory $(Build.ArtifactStagingDirectory)/vscode-powershell - Install-Module InvokeBuild -Force - Invoke-Build Release - workingDirectory: '$(Build.SourcesDirectory)/vscode-powershell' - -- task: PublishTestResults@2 - inputs: - testRunner: JUnit - testResultsFiles: '**/test-results.xml' - condition: succeededOrFailed() +- download: current + displayName: Download pipeline artifacts - checkout: ComplianceRepo - template: EsrpSign.yml@ComplianceRepo parameters: - buildOutputPath: '$(Build.ArtifactStagingDirectory)/vscode-powershell' - signOutputPath: '$(Build.ArtifactStagingDirectory)/Signed' - alwaysCopy: true # So publishing works - certificateId: 'CP-230012' # Authenticode certificate - useMinimatch: true # This enables the use of globbing + buildOutputPath: $(Pipeline.Workspace)/vscode-powershell-unsigned-script-* + signOutputPath: $(Pipeline.Workspace)/signed + alwaysCopy: true + certificateId: CP-230012 # Authenticode certificate shouldSign: true # We always want to sign # NOTE: Code AKA *.vsix files are not signed - pattern: | - Install-VSCode.ps1 + pattern: Install-VSCode.ps1 + +# NOTE: Because the scan template doesn't copy (unlike the sign template), we do +# it ourselves so that we can publish one finished artifact. +- pwsh: Copy-Item -Path $(Pipeline.Workspace)/vscode-powershell-vsix-*/*.vsix -Destination $(Pipeline.Workspace)/signed -Verbose + displayName: Copy extension to signed folder - template: EsrpScan.yml@ComplianceRepo parameters: - scanPath: $(Build.ArtifactStagingDirectory)/Signed - pattern: | - *.vsix + scanPath: $(Pipeline.Workspace)/signed + pattern: powershell-*.vsix -- publish: $(Build.ArtifactStagingDirectory)/Signed - artifact: vscode-powershell - displayName: 'Publish signed (and unsigned) artifacts' +- checkout: self - template: script-module-compliance.yml@ComplianceRepo parameters: # component-governance - sourceScanPath: '$(Build.SourcesDirectory)/vscode-powershell' + sourceScanPath: $(Build.SourcesDirectory)/vscode-powershell # credscan - suppressionsFile: '$(Build.SourcesDirectory)/vscode-powershell/tools/credScan/suppress.json' + suppressionsFile: $(Build.SourcesDirectory)/vscode-powershell/tools/credScan/suppress.json # TermCheck AKA PoliCheck - targetArgument: '$(Build.SourcesDirectory)/vscode-powershell' - optionsUEPATH: '$(Build.SourcesDirectory)/vscode-powershell/tools/terms/UserExclusions.xml' + targetArgument: $(Build.SourcesDirectory)/vscode-powershell + optionsUEPATH: $(Build.SourcesDirectory)/vscode-powershell/tools/terms/UserExclusions.xml optionsRulesDBPath: '' - optionsFTPath: '$(Build.SourcesDirectory)/vscode-powershell/tools/terms/FileTypeSet.xml' + optionsFTPath: $(Build.SourcesDirectory)/vscode-powershell/tools/terms/FileTypeSet.xml # tsa-upload - codeBaseName: 'PowerShell_PowerShellEditorServices_20210201' + codeBaseName: PowerShell_PowerShellEditorServices_20210201 # We don't use any Windows APIs directly, so we don't need API scan APIScan: false + +- publish: $(Pipeline.Workspace)/signed + artifact: vscode-powershell + displayName: Publish signed artifacts