diff --git a/Build/18.0/packages.config b/Build/18.0/packages.config
index 1c79198ef1..210c9385e2 100644
--- a/Build/18.0/packages.config
+++ b/Build/18.0/packages.config
@@ -1,7 +1,6 @@
-
@@ -83,4 +82,5 @@
+
diff --git a/Build/PreBuild.ps1 b/Build/PreBuild.ps1
index 2f7b908c2c..c16482782b 100644
--- a/Build/PreBuild.ps1
+++ b/Build/PreBuild.ps1
@@ -208,7 +208,7 @@ try {
if (-not $interactive) {
$arglist += "-NonInteractive"
}
- $nuget = Get-Command nuget.exe -EA 0
+ $nuget = Get-Command .\nuget.exe -EA 0
if (-not $nuget) {
$nuget = Get-Command .\nuget.exe
}
diff --git a/Build/azuredevops/test/uitest-integration-stage.yml b/Build/azuredevops/test/uitest-integration-stage.yml
new file mode 100644
index 0000000000..07372455b8
--- /dev/null
+++ b/Build/azuredevops/test/uitest-integration-stage.yml
@@ -0,0 +1,157 @@
+parameters:
+ - name: BinariesDirectory
+ type: string
+ default: '$(Drop)/binaries'
+ - name: CleanupProcesses
+ type: string
+ default: 'devenv, vshub, microsoft.vshub.server.httphost, python, ipy, microsoft.pythontools.analyzer, vstest.executionengine.x86, vstest.discoveryengine.x86'
+ - name: Drop
+ type: string
+ default: '$(System.ArtifactsDirectory)/$(DefinitionName)'
+ - name: TestFilterCriteria
+ type: string
+ default: 'Priority=0'
+ - name: UITestNames
+ type: string
+ default: ''
+
+steps:
+ - task: ExtractFiles@1
+ displayName: Extract files
+ condition: succeeded()
+ inputs:
+ archiveFilePatterns: '${{ parameters.Drop }}/TestData.zip'
+ destinationFolder: '${{ parameters.Drop }}/TestData'
+ cleanDestinationFolder: false
+ overwriteExistingFiles: false
+
+ - task: PowerShell@2
+ displayName: Cleanup
+ condition: succeeded()
+ continueOnError: true
+ timeoutInMinutes: 5
+ inputs:
+ targetType: inline
+ script: |
+ $names = @(
+ '${{ parameters.CleanupProcesses }}'
+ -split ',' |
+ ForEach-Object { $_.Trim() } |
+ Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
+ )
+ $running = Get-Process -Name $names -ErrorAction SilentlyContinue
+ while ($running) {
+ Write-Host 'Killing:'
+ $running
+ try {
+ $running | Stop-Process -Force
+ } catch {
+ }
+ Start-Sleep -Seconds 3
+ $running = Get-Process -Name $names -ErrorAction SilentlyContinue
+ }
+ errorActionPreference: stop
+ failOnStderr: true
+
+ - task: CopyFiles@2
+ displayName: Copy TestData into binaries
+ condition: succeeded()
+ continueOnError: true
+ inputs:
+ SourceFolder: '${{ parameters.Drop }}/TestData'
+ Contents: '**'
+ TargetFolder: '${{ parameters.BinariesDirectory }}/TestData'
+ CleanTargetFolder: 'true'
+ OverWrite: 'false'
+ flattenFolders: 'false'
+ preserveTimestamp: 'false'
+ retryCount: '0'
+
+ - task: CopyFiles@2
+ displayName: Copy runsettings to binary folder
+ condition: succeeded()
+ inputs:
+ SourceFolder: '${{ parameters.BinariesDirectory }}/TestData'
+ Contents: 'ptvs.runsettings'
+ TargetFolder: '${{ parameters.BinariesDirectory }}'
+ CleanTargetFolder: 'false'
+ OverWrite: 'false'
+ flattenFolders: 'false'
+ preserveTimestamp: 'false'
+ retryCount: '0'
+
+ - task: PowerShell@2
+ displayName: Skip Verification
+ condition: succeeded()
+ inputs:
+ targetType: inline
+ script: |
+ reg import "${{ parameters.BinariesDirectory }}\TestData\EnableSkipVerification.reg"
+ errorActionPreference: stop
+ failOnStderr: false
+
+ - task: VSTest@2
+ displayName: '[MultiConfiguration] Run UI Test ${{ parameters.UITestNames }}'
+ condition: succeeded()
+ continueOnError: true
+ inputs:
+ testSelector: testAssemblies
+ testAssemblyVer2: '${{ parameters.UITestNames }}UITestsRunner.dll'
+ tcmTestRun: '$(test.RunId)'
+ searchFolder: '${{ parameters.BinariesDirectory }}'
+ resultsFolder: '$(Agent.TempDirectory)/TestResults'
+ testFiltercriteria: '${{ parameters.TestFilterCriteria }}'
+ runOnlyImpactedTests: false
+ runAllTestsAfterXBuilds: 50
+ uiTests: true
+ vstestLocationMethod: version
+ vsTestVersion: latest
+ runSettingsFile: '${{ parameters.Drop }}\\ptvs.runsettings'
+ overrideTestrunParameters: '-TargetFrameworkVersion .NETFramework,Version=v4.7.2'
+ runInParallel: false
+ runTestsInIsolation: false
+ codeCoverageEnabled: true
+ distributionBatchType: basedOnExecutionTime
+ batchingBasedOnAgentsOption: autoBatchSize
+ customBatchSizeValue: 10
+ batchingBasedOnExecutionTimeOption: customTimeBatchSize
+ customRunTimePerBatchValue: 300
+ dontDistribute: false
+ testRunTitle: '${{ parameters.UITestNames }} UI Tests'
+ publishRunAttachments: true
+ failOnMinTestsNotRun: false
+ minimumExpectedTests: 1
+ diagnosticsEnabled: true
+ collectDumpOn: onAbortOnly
+ rerunFailedTests: true
+ rerunType: basedOnTestFailurePercentage
+ rerunFailedThreshold: 50
+ rerunFailedTestCasesMaxLimit: 5
+ rerunMaxAttempts: 2
+
+ - task: PowerShell@2
+ displayName: Cleanup
+ condition: succeeded()
+ timeoutInMinutes: 5
+ inputs:
+ targetType: inline
+ script: |
+ $names = @(
+ '${{ parameters.CleanupProcesses }}'
+ -split ',' |
+ ForEach-Object { $_.Trim() } |
+ Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
+ )
+ $running = Get-Process -Name $names -ErrorAction SilentlyContinue
+ while ($running) {
+ Write-Host 'Killing:'
+ $running
+ try {
+ $running | Stop-Process -Force
+ } catch {
+ }
+ Start-Sleep -Seconds 3
+ $running = Get-Process -Name $names -ErrorAction SilentlyContinue
+ }
+ errorActionPreference: stop
+ failOnStderr: true
diff --git a/Build/debugpy-version.txt b/Build/debugpy-version.txt
index e06e7a26c8..bbaa9e1622 100644
--- a/Build/debugpy-version.txt
+++ b/Build/debugpy-version.txt
@@ -1 +1 @@
-1.8.17
\ No newline at end of file
+1.8.18
\ No newline at end of file
diff --git a/Build/nuget.config b/Build/nuget.config
index 5dd8ead95c..b441bb20ef 100644
--- a/Build/nuget.config
+++ b/Build/nuget.config
@@ -3,9 +3,10 @@
-
+
-
+
+
diff --git a/Build/nuget.testdata.config b/Build/nuget.testdata.config
new file mode 100644
index 0000000000..6ffb9ce36d
--- /dev/null
+++ b/Build/nuget.testdata.config
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Microsoft;xunit;manuel.roemer;sharwell;jamesnk;aarnott;MarcoRossignoli;Thecentury;AndreyAkinshin;0xd4d;ericnewton76;jkeech;steve.dower
+
+
+
+
+
+
+
+
diff --git a/Build/packages.testdata.config b/Build/packages.testdata.config
new file mode 100644
index 0000000000..00494d7e05
--- /dev/null
+++ b/Build/packages.testdata.config
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/Build/templates/build.yml b/Build/templates/build.yml
index 9d755e9134..94e05dd21b 100644
--- a/Build/templates/build.yml
+++ b/Build/templates/build.yml
@@ -2,6 +2,9 @@ parameters:
- name: ptvsPackageVersion
type: string
default: $(Build.BuildNumber)
+- name: skipSigning
+ type: boolean
+ default: false
steps:
@@ -57,4 +60,5 @@ steps:
/p:BuildNumber=${{ parameters.ptvsPackageVersion }}
/p:BUILD_BINARIESDIRECTORY=$(Build.BinariesDirectory)
/p:BUILD_STAGINGDIRECTORY=$(Build.StagingDirectory)
+ /p:SkipSigning=${{ parameters.skipSigning }}
/bl:$(Build.SourcesDirectory)\logs\BuildInstaller.binlog'
diff --git a/Build/templates/publish_test_data.yml b/Build/templates/publish_test_data.yml
index cdd38b4847..462009249c 100644
--- a/Build/templates/publish_test_data.yml
+++ b/Build/templates/publish_test_data.yml
@@ -1,5 +1,43 @@
steps:
+ - task: NuGetToolInstaller@1
+ displayName: Install NuGet
+
+ - task: NuGetCommand@2
+ displayName: Restore runsettings build tasks
+ inputs:
+ command: restore
+ feedsToUse: config
+ restoreSolution: '$(Build.SourcesDirectory)/Build/packages.testdata.config'
+ restoreDirectory: '$(Build.SourcesDirectory)/packages'
+ nugetConfigPath: '$(Build.SourcesDirectory)/Build/nuget.testdata.config'
+
+ # Generate a runsettings file that points at the correct Test Store drop.
+ - task: MSBuild@1
+ displayName: 'Build PTVS.runsettingsproj'
+ inputs:
+ solution: '$(Build.SourcesDirectory)/Python/Tests/PTVS.runsettingsproj'
+ msbuildArguments: >
+ /p:PackagesPath=$(Build.SourcesDirectory)\packages
+ /p:TestStoreDropName=$(TestStoreDropName)
+
+ - task: PowerShell@2
+ displayName: 'Update default.runsettings from generated ptvs.runsettings'
+ inputs:
+ targetType: 'inline'
+ script: |
+ $ErrorActionPreference = 'Stop'
+
+ $source = "$(Build.SourcesDirectory)\Python\Tests\bin\RunSettings\ptvs.runsettings"
+ $dest = "$(Build.SourcesDirectory)\Python\Tests\TestData\ptvs.runsettings"
+
+ if (-not (Test-Path -LiteralPath $source)) {
+ throw "Expected generated runsettings file not found: $source"
+ }
+
+ Copy-Item -LiteralPath $source -Destination $dest -Force
+
+
# Compress just the test data
# Used in this release task to run tests: https://devdiv.visualstudio.com/DevDiv/_taskgroup/a7b18468-aab5-4be7-b718-02f85b0828c4
- task: ArchiveFiles@2
@@ -20,6 +58,13 @@ steps:
Contents: 'TestData.zip'
TargetFolder: '$(Build.ArtifactStagingDirectory)/TestDataFolder'
+ - task: CopyFiles@2
+ displayName: 'Copy ptvs.runsettings to subfolder'
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)/Python/Tests/TestData'
+ Contents: 'ptvs.runsettings'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/TestDataFolder'
+
# The Task 'PublishBuildArtifacts@1' has been converted to an output named 'Publish build artifact: TestData' in the templateContext section.
# The Task 'PublishBuildArtifacts@1' has been converted to an output named 'Publish build artifact: RunSettings' in the templateContext section.
\ No newline at end of file
diff --git a/Python/PythonTools.sln b/Python/PythonTools.sln
index 26958ebab1..4b69ac133e 100644
--- a/Python/PythonTools.sln
+++ b/Python/PythonTools.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.0.31211.46
+# Visual Studio Version 18
+VisualStudioVersion = 18.3.11227.31 main
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Product", "Product", "{C0C7AD6F-5E39-4D3F-A6B6-FD30713B0464}"
EndProject
@@ -16,6 +16,9 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities.UI", "..\Common\Tests\Utilities.UI\TestUtilities.UI.csproj", "{E8150EBC-6B62-40BF-BF91-1DC60149B530}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3D21C7AC-6F9D-448C-8356-44EAFB2D14FC}"
+ ProjectSection(SolutionItems) = preProject
+ Tests\PTVS.runsettingsproj = Tests\PTVS.runsettingsproj
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Attacher", "Product\Attacher\Attacher.csproj", "{666A22BB-0CB5-4C08-A20F-E17450DA6573}"
EndProject
diff --git a/Python/Setup/signlayout.proj b/Python/Setup/signlayout.proj
index 4f2f5ff6b6..23cf5cf63c 100644
--- a/Python/Setup/signlayout.proj
+++ b/Python/Setup/signlayout.proj
@@ -9,6 +9,10 @@
$(BinariesOutputPath)
$(BinariesOutputPath)
+
+ false
+
+ None
@@ -17,7 +21,7 @@
-
+
<_Languages Include="$(Languages)" />
+
@@ -84,7 +88,7 @@
-
+
@@ -96,17 +100,17 @@
-
+
-
+
-
+
<_BinariesInLayout Include="$(LayoutOutputPath)**\*.exe;$(LayoutOutputPath)**\*.dll" />
<_BinariesWithSignedSource Include="$(BinariesOutputPath)%(_BinariesInLayout.Filename)%(_BinariesInLayout.Extension)">
@@ -116,7 +120,7 @@
-
+
<_FilesInLayout Include="$(LayoutOutputPath)\Microsoft.PythonTools.Core\pylance\**\*.js" />
@@ -127,10 +131,10 @@
-
+ AfterTargets="SignFiles"
+ Condition="'$(SkipSigning)'!='true'">
diff --git a/Python/Tests/Core.UI/TestExplorerTests.cs b/Python/Tests/Core.UI/TestExplorerTests.cs
index a22c074950..4555d42885 100644
--- a/Python/Tests/Core.UI/TestExplorerTests.cs
+++ b/Python/Tests/Core.UI/TestExplorerTests.cs
@@ -65,7 +65,7 @@ public void RunAllUnittestProject(PythonVisualStudioApp app) {
var sln = app.CopyProjectForTest(@"TestData\TestExplorerUnittest.sln");
app.OpenProject(sln);
- RunAllTests(app, AllUnittests);
+ RunAllTests(app, AllUnittests, Path.GetFileNameWithoutExtension(sln));
}
public void RunAllUnittestWorkspace(PythonVisualStudioApp app) {
diff --git a/Python/Tests/PTVS.runsettingsproj b/Python/Tests/PTVS.runsettingsproj
new file mode 100644
index 0000000000..ff15a13040
--- /dev/null
+++ b/Python/Tests/PTVS.runsettingsproj
@@ -0,0 +1,37 @@
+
+
+
+ v4.6.1
+ ptvs
+ bin\RunSettings
+ .\TestResults
+ x86
+ 1
+ 3600000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Python/Tests/PythonToolsUITestsRunner/TestExplorerTests.cs b/Python/Tests/PythonToolsUITestsRunner/TestExplorerTests.cs
index de5292aeee..565c573553 100644
--- a/Python/Tests/PythonToolsUITestsRunner/TestExplorerTests.cs
+++ b/Python/Tests/PythonToolsUITestsRunner/TestExplorerTests.cs
@@ -75,12 +75,14 @@ public void DebugPytestWorkspace() {
_vs.RunTest(nameof(PythonToolsUITests.TestExplorerTests.DebugPytestWorkspace));
}
+ [Ignore]
[TestMethod, Priority(UITestPriority.P0)]
[TestCategory("Installed")]
public void DebugUnittestProject() {
_vs.RunTest(nameof(PythonToolsUITests.TestExplorerTests.DebugUnittestProject));
}
+ [Ignore]
[TestMethod, Priority(UITestPriority.P0)]
[TestCategory("Installed")]
public void DebugUnittestWorkspace() {
diff --git a/Python/Tests/Utilities.Python/PythonTestExplorer.cs b/Python/Tests/Utilities.Python/PythonTestExplorer.cs
index b55e810a8c..e48c40c3fe 100644
--- a/Python/Tests/Utilities.Python/PythonTestExplorer.cs
+++ b/Python/Tests/Utilities.Python/PythonTestExplorer.cs
@@ -14,18 +14,21 @@
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using System.Windows.Automation;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace TestUtilities.UI {
- public class PythonTestExplorer : AutomationWrapper {
+namespace TestUtilities.UI
+{
+ public class PythonTestExplorer : AutomationWrapper
+ {
private readonly VisualStudioApp _app;
private readonly AutomationWrapper _searchBar;
private PythonTestExplorerGridView _tests;
- private static class TestCommands {
+ private static class TestCommands
+ {
public const string GroupBy = "TestExplorer.GroupBy";
public const string RunAllTests = "TestExplorer.RunAllTests";
public const string CopyDetails = "TestExplorer.CopyDetails";
@@ -33,14 +36,18 @@ private static class TestCommands {
}
public PythonTestExplorer(VisualStudioApp app, AutomationElement element, AutomationWrapper searchBarTextBox)
- : base(element) {
+ : base(element)
+ {
_app = app;
_searchBar = searchBarTextBox ?? throw new ArgumentNullException(nameof(searchBarTextBox));
}
- public PythonTestExplorerGridView Tests {
- get {
- if (_tests == null) {
+ public PythonTestExplorerGridView Tests
+ {
+ get
+ {
+ if (_tests == null)
+ {
var el = this.Element.FindFirst(
TreeScope.Descendants,
new AndCondition(
@@ -54,7 +61,8 @@ public PythonTestExplorerGridView Tests {
)
)
);
- if (el != null) {
+ if (el != null)
+ {
_tests = new PythonTestExplorerGridView(el);
}
}
@@ -62,13 +70,15 @@ public PythonTestExplorerGridView Tests {
}
}
- public string GetTestDetailSummary() {
+ public string GetTestDetailSummary()
+ {
// Root is the Test Explorer tool window element you already have.
var summaryControl = Element.FindFirst(
TreeScope.Descendants,
new PropertyCondition(AutomationElement.ClassNameProperty, "SummaryControl")
);
- if (summaryControl == null) {
+ if (summaryControl == null)
+ {
return string.Empty;
}
@@ -77,17 +87,20 @@ public string GetTestDetailSummary() {
TreeScope.Descendants,
new PropertyCondition(AutomationElement.ClassNameProperty, "WpfTextView")
);
- if (textView == null) {
+ if (textView == null)
+ {
return string.Empty;
}
// Try TextPattern.
object p;
- if (textView.TryGetCurrentPattern(TextPattern.Pattern, out p)) {
+ if (textView.TryGetCurrentPattern(TextPattern.Pattern, out p))
+ {
return ((TextPattern)p).DocumentRange.GetText(int.MaxValue);
}
// Fallback ValuePattern.
- if (textView.TryGetCurrentPattern(ValuePattern.Pattern, out p)) {
+ if (textView.TryGetCurrentPattern(ValuePattern.Pattern, out p))
+ {
return ((ValuePattern)p).Current.Value;
}
@@ -95,16 +108,19 @@ public string GetTestDetailSummary() {
return textView.Current.Name ?? string.Empty;
}
- public string GetDetailsWithRetry() {
+ public string GetDetailsWithRetry()
+ {
string details = string.Empty;
- for (int i = 0; i < 5; i++) {
+ for (int i = 0; i < 5; i++)
+ {
var detailsTextBox = this.FindByName("Test Detail Summary");
AutomationWrapper.CheckNullElement(detailsTextBox, "Missing: Test Detail Summary");
// Copy to clipboard
details = GetTestDetailSummary();
- if (details.Contains("Source:")) {
+ if (details.Contains("Source:"))
+ {
return details;
}
@@ -117,65 +133,85 @@ public string GetDetailsWithRetry() {
///
/// Set the grouping to namespace.
///
- public void GroupByProjectNamespaceClass() {
- // TODO: figure out how to programmatically change this
- // it's now a popup window that appears on TestExplorer.GroupBy command
- // well, at least when you click on it with the mouse
- // It's not coming up when invoking the command programmatically
-
- //var groupCommand = _app.Dte.Commands.Item(TestCommands.GroupBy);
- //Assert.IsNotNull(groupCommand, "GroupBy command not found");
-
-
- //if (!groupCommand.IsAvailable) {
- // // Group command is not available when show hierarchy is on
- // //_app.ExecuteCommand(TestCommands.ToggleShowTestHierarchy);
- // _app.WaitForCommandAvailable(groupCommand, TimeSpan.FromSeconds(5));
- //}
-
- //_app.ExecuteCommand(TestCommands.GroupBy); // by class
-
- //Thread.Sleep(100);
+ public void GroupByProjectNamespaceClass()
+ {
+ // Try execute the GroupBy command to display grouping popup.
+ try
+ {
+ _app.Dte.ExecuteCommand(TestCommands.GroupBy);
+ }
+ catch
+ {
+ // Swallow if command not available; we'll still try to locate the option.
+ }
- //var element = _app.Element.FindFirst(TreeScope.Descendants, new AndCondition(
- // new PropertyCondition(
- // AutomationElement.NameProperty,
- // "Project, Namespace, Class"
- // ),
- // new PropertyCondition(
- // AutomationElement.ClassNameProperty,
- // "TextBlock"
- // )
- //));
- //Assert.IsNotNull(element);
+ // Allow UI to render the popup
+ Thread.Sleep(200);
+
+ // Attempt to find the "Project, Namespace, Class" option and invoke it.
+ AutomationElement element = null;
+ for (int i = 0; i < 5 && element == null; i++)
+ {
+ element = _app.Element.FindFirst(
+ TreeScope.Descendants,
+ new AndCondition(
+ new PropertyCondition(AutomationElement.NameProperty, "Project, Namespace, Class"),
+ new PropertyCondition(AutomationElement.ClassNameProperty, "TextBlock")
+ )
+ );
+ if (element == null)
+ {
+ Thread.Sleep(200);
+ }
+ }
- //var menuItem = element.CachedParent;
- //Assert.IsNotNull(menuItem);
+ if (element != null)
+ {
+ // Use TreeWalker to get parent; CachedParent may be null depending on cache policy
+ var menuItem = element.CachedParent;
+ if (menuItem == null)
+ {
+ var walker = TreeWalker.RawViewWalker;
+ menuItem = walker.GetParent(element);
+ }
- //menuItem.GetInvokePattern().Invoke();
+ if (menuItem != null)
+ {
+ var inv = menuItem.GetInvokePattern() ?? element.GetInvokePattern();
+ if (inv != null)
+ {
+ inv.Invoke();
+ }
+ }
+ }
WaitForTestsGrid();
}
- private void WaitForTestsGrid() {
+ private void WaitForTestsGrid()
+ {
// Wait for the test list to be created
int retry = 10;
- while (Tests == null) {
+ while (Tests == null)
+ {
Thread.Sleep(250);
retry--;
- if (retry == 0) {
+ if (retry == 0)
+ {
break;
}
}
Assert.IsNotNull(Tests, "Tests list is null");
}
- public void ClearSearchBar() {
+ public void ClearSearchBar()
+ {
_searchBar.SetValue("");
Thread.Sleep(1000);
}
- public AutomationElement WaitForItem(params string[] path) {
+ public AutomationElement WaitForItem(params string[] path)
+ {
// WaitForItem doesn't work well with offscreen items
// so we use the search bar to filter by function name to
// limit the items on screen and then expand all tree items.
@@ -183,7 +219,8 @@ public AutomationElement WaitForItem(params string[] path) {
// it multiple times with delay as a work around.
_searchBar.SetValue(path[path.Length - 1]);
- for (int i = 0; i < path.Length + 2; i++) {
+ for (int i = 0; i < path.Length + 2; i++)
+ {
Tests.ExpandAll();
}
@@ -193,7 +230,8 @@ public AutomationElement WaitForItem(params string[] path) {
///
/// Run all tests and wait for the command to be available again.
///
- public void RunAll(TimeSpan timeout) {
+ public void RunAll(TimeSpan timeout)
+ {
ClearSearchBar();
_app.Dte.ExecuteCommand(TestCommands.RunAllTests);
Thread.Sleep(100);
@@ -203,7 +241,8 @@ public void RunAll(TimeSpan timeout) {
///
/// Debug all tests and wait for the command to be available again.
///
- public void DebugAll() {
+ public void DebugAll()
+ {
_app.Dte.ExecuteCommand(TestCommands.DebugAllTests);
Thread.Sleep(100);
}
diff --git a/azure-pipelines-integration-tests.yml b/azure-pipelines-integration-tests.yml
index e4c805d11a..4757a046e6 100644
--- a/azure-pipelines-integration-tests.yml
+++ b/azure-pipelines-integration-tests.yml
@@ -2,7 +2,8 @@
trigger: none
pr: none
-# For more info about how this resources section works, see https://docs.microsoft.com/en-us/azure/devops/pipelines/process/resources?view=azure-devops&tabs=schema
+# The following steps describe how to create a DartLab pipeline that installs Visual Studio using a bootstrapper generated by the MicroBuild Build VS Bootstrapper task
+# in the component repo's MicroBuild: https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/45681/Component-Repository
resources:
pipelines:
@@ -10,7 +11,8 @@ resources:
# All PTVS build artifacts come from this pipeline and are referenced like this:
# $(Pipeline.Workspace)\ComponentBuildUnderTest\\
- pipeline: ComponentBuildUnderTest
- source: PTVS-Build-Dev17
+ project: DevDiv
+ source: Python\PTVS\PTVS-Build
branch: main # This is only used for manual/scheduled runs of this pipeline
trigger:
branches:
@@ -32,44 +34,41 @@ resources:
stages:
-- template: stages/visual-studio/single-runsettings.yml@DartLabTemplates
+- template: stages/cloudtest/visual-studio/single-runsettings.yml@DartLabTemplates
parameters:
displayName: Integration Tests
- variables:
- - name: VisualStudio.InstallationUnderTest.BootstrapperBranch
- value: main
- testLabPoolName: Azure-and-Web
- testMachineTotalCount: 1
+ owner: ptvs
+ testMachineLab: DDRITs-PR
# This assumes the PTVS build has published a build artifact called "RunSettings" that contains the default.runsettings file
- runSettingsURI: $(Pipeline.Workspace)\ComponentBuildUnderTest\RunSettings\default.runsettings
+ runSettingsURI: https://vsdrop.microsoft.com/file/v1/$(RunSettings.DropName);default.runsettings
visualStudioBootstrapperURI: $(VisualStudio.InstallationUnderTest.BootstrapperURL)
visualStudioSigning: Test
-
+ testMachineConfigurationJobVariables:
+ - name: VisualStudio.InstallationUnderTest.BootstrapperBranch
+ value: main
# These steps run on the machine that is creating the test machine configuration, which isn't the same
# as the machine running the actual tests
- preTestMachineConfigurationStepList:
-
+ preTestMachineConfigurationSteps:
+
- download: ComponentBuildUnderTest
artifact: MicroBuildOutputs
patterns: '**\BootstrapperInfo.json'
displayName: Download Bootstrapper Information
-
- - download: ComponentBuildUnderTest
- artifact: RunSettings
- patterns: '**\default.runsettings'
- displayName: Download RunSettings
-
+
- task: PowerShell@2
displayName: Set 'VisualStudio.InstallationUnderTest.BootstrapperURL'
inputs:
filePath: $(DartLab.Path)\Scripts\VisualStudio\Bootstrapper\Get-BootstrapperURL.ps1
- # This assumes the PTVS build has published a build artifact called "MicroBuildOutputs" that contains the generated BootstrapperInfo.json
arguments: -BootstrapperInfoJsonURI '$(Pipeline.Workspace)\ComponentBuildUnderTest\MicroBuildOutputs\BootstrapperInfo.json' -VSBranch '$(VisualStudio.InstallationUnderTest.BootstrapperBranch)' -OutVariableName 'VisualStudio.InstallationUnderTest.BootstrapperURL'
-
- # These steps run on the machine that is running the tests
- preDeployAndRunTestsStepList:
- download: ComponentBuildUnderTest
- artifact: RunSettings
- patterns: '**\default.runsettings'
- displayName: Download RunSettings
+ artifact: PTVS-TestData
+ patterns: '**\VSTSDrop.json'
+ displayName: Download drop Information
+
+ - template: \steps\powershell\execute-script.yml@DartLabTemplates
+ parameters:
+ displayName: Set 'RunSettings.DropName'
+ filePath: $(DartLab.Path)\Scripts\AzureDevOps\Artifacts\Drop\Get-DropName.ps1
+ arguments: -VSTSDropJsonURI '$(Pipeline.Workspace)\ComponentBuildUnderTest\PTVS-TestData\VSTSDrop.json' -OutVariableName 'RunSettings.DropName'
+
\ No newline at end of file
diff --git a/azure-pipelines-integration-testsgate.yml b/azure-pipelines-integration-testsgate.yml
new file mode 100644
index 0000000000..b6c17dc596
--- /dev/null
+++ b/azure-pipelines-integration-testsgate.yml
@@ -0,0 +1,211 @@
+# Don't trigger ci or pr builds
+trigger: none
+pr: none
+
+# The following steps describe how to create a DartLab pipeline that installs Visual Studio using a bootstrapper generated by the MicroBuild Build VS Bootstrapper task
+# in the component repo's MicroBuild: https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/45681/Component-Repository
+resources:
+
+ pipelines:
+
+ # All PTVS build artifacts come from this pipeline and are referenced like this:
+ # $(Pipeline.Workspace)\ComponentBuildUnderTest\\
+ - pipeline: ComponentBuildUnderTest
+ project: DevDiv
+ source: Python\PTVS\PTVS-Build
+
+ trigger:
+ branches:
+ include:
+ - main
+ - release/*
+
+ - pipeline: DartLab
+ project: DevDiv
+ source: DartLab
+ branch: main
+
+ repositories:
+
+ - repository: DartLabTemplates
+ type: git
+ name: DartLab.Templates
+ ref: refs/heads/main
+
+stages:
+
+- template: stages/cloudtest/visual-studio/single-runsettings.yml@DartLabTemplates
+ parameters:
+ displayName: Integration Tests
+ owner: ptvs
+ testMachineLab: DDRITs-PR
+ # This assumes the PTVS build has published a build artifact called "RunSettings" that contains the default.runsettings file
+ runSettingsURI: https://vsdrop.microsoft.com/file/v1/$(RunSettings.DropName);ptvs.runsettings
+ visualStudioBootstrapperURI: $(VisualStudio.InstallationUnderTest.BootstrapperURL)
+ visualStudioSigning: Test
+ testMachineConfigurationJobVariables:
+ - name: VisualStudio.InstallationUnderTest.BootstrapperBranch
+ value: main
+ # These steps run on the machine that is creating the test machine configuration, which isn't the same
+ # as the machine running the actual tests
+ preTestMachineConfigurationSteps:
+
+ - download: ComponentBuildUnderTest
+ artifact: MicroBuildOutputs
+ patterns: '**\BootstrapperInfo.json'
+ displayName: Download Bootstrapper Information
+
+ - task: PowerShell@2
+ displayName: Set 'VisualStudio.InstallationUnderTest.BootstrapperURL'
+ inputs:
+ filePath: $(DartLab.Path)\Scripts\VisualStudio\Bootstrapper\Get-BootstrapperURL.ps1
+ arguments: -BootstrapperInfoJsonURI '$(Pipeline.Workspace)\ComponentBuildUnderTest\MicroBuildOutputs\BootstrapperInfo.json' -VSBranch '$(VisualStudio.InstallationUnderTest.BootstrapperBranch)' -OutVariableName 'VisualStudio.InstallationUnderTest.BootstrapperURL'
+
+ - download: ComponentBuildUnderTest
+ artifact: PTVS-TestData
+ patterns: '**\*'
+ displayName: Download drop Information
+
+ - download: ComponentBuildUnderTest
+ artifact: TestDataFolder
+ patterns: '**\*'
+ displayName: Download TestDataFolder Information
+
+ - download: ComponentBuildUnderTest
+ artifact: Binaries
+ patterns: '**\*'
+ displayName: Download Binaries
+
+ - task: PowerShell@2
+ displayName: List downloaded files before setting 'RunSettings.DropName'
+ inputs:
+ targetType: inline
+ script: |
+ Write-Host "Pipeline.Workspace: $(Pipeline.Workspace)"
+ Write-Host "System.DefaultWorkingDirectory: $(System.DefaultWorkingDirectory)"
+
+ $componentRoot = Join-Path "$(Pipeline.Workspace)" "ComponentBuildUnderTest"
+
+ function Write-RecursiveListing {
+ param(
+ [Parameter(Mandatory = $true)][string]$RootPath,
+ [Parameter(Mandatory = $true)][string]$Title
+ )
+
+ Write-Host ""
+ Write-Host "==== $Title ===="
+ Write-Host "Root: $RootPath"
+
+ if (-not (Test-Path -LiteralPath $RootPath)) {
+ Write-Warning "Path not found: $RootPath"
+ return
+ }
+
+ Write-Host "Top-level entries:"
+ Get-ChildItem -LiteralPath $RootPath -Force |
+ Select-Object Name, FullName, Mode, Length, LastWriteTime |
+ Sort-Object FullName |
+ Format-Table -AutoSize
+
+ Write-Host ""
+ Write-Host "All files (recursive):"
+ $allFiles = Get-ChildItem -LiteralPath $RootPath -Recurse -Force -File -ErrorAction SilentlyContinue
+ if ($allFiles) {
+ $allFiles |
+ Select-Object FullName, Length, LastWriteTime |
+ Sort-Object FullName |
+ Format-Table -AutoSize
+ Write-Host "Total files: $($allFiles.Count)"
+ } else {
+ Write-Warning "No files found under: $RootPath"
+ }
+
+ Write-Host ""
+ Write-Host "All directories (recursive):"
+ $allDirs = Get-ChildItem -LiteralPath $RootPath -Recurse -Force -Directory -ErrorAction SilentlyContinue
+ if ($allDirs) {
+ $allDirs |
+ Select-Object FullName, LastWriteTime |
+ Sort-Object FullName |
+ Format-Table -AutoSize
+ Write-Host "Total directories: $($allDirs.Count)"
+ } else {
+ Write-Warning "No directories found under: $RootPath"
+ }
+ }
+
+ Write-RecursiveListing -RootPath $componentRoot -Title "Downloaded artifacts under ComponentBuildUnderTest"
+
+ Write-Host ""
+ Write-Host "Searching for VSTSDrop.json under: $componentRoot"
+ if (Test-Path -LiteralPath $componentRoot) {
+ $matches = Get-ChildItem -LiteralPath $componentRoot -Recurse -Force -File -Filter "VSTSDrop.json" -ErrorAction SilentlyContinue
+ if ($matches) {
+ $matches | Select-Object FullName, Length, LastWriteTime | Sort-Object FullName | Format-Table -AutoSize
+ } else {
+ Write-Warning "No VSTSDrop.json found under: $componentRoot"
+ }
+ } else {
+ Write-Warning "Path not found: $componentRoot"
+ }
+
+ - task: PowerShell@2
+ displayName: Find VSTSDrop.json path
+ inputs:
+ targetType: inline
+ script: |
+ $componentRoot = Join-Path "$(Pipeline.Workspace)" "ComponentBuildUnderTest"
+ Write-Host "Searching for VSTSDrop.json under: $componentRoot"
+ if (-not (Test-Path -LiteralPath $componentRoot)) {
+ throw "ComponentBuildUnderTest root not found: $componentRoot"
+ }
+
+ $matches = Get-ChildItem -LiteralPath $componentRoot -Recurse -Force -File -Filter "VSTSDrop.json" -ErrorAction SilentlyContinue
+ if (-not $matches) {
+ throw "No VSTSDrop.json found under: $componentRoot"
+ }
+
+ if ($matches.Count -gt 1) {
+ Write-Warning "Multiple VSTSDrop.json files found; selecting the most recent."
+ $matches | Select-Object FullName, Length, LastWriteTime | Sort-Object LastWriteTime -Descending | Format-Table -AutoSize
+ }
+
+ $selected = $matches | Sort-Object LastWriteTime -Descending | Select-Object -First 1
+ Write-Host "Selected VSTSDrop.json: $($selected.FullName)"
+ Write-Host "##vso[task.setvariable variable=VSTSDropJsonURI]$($selected.FullName)"
+
+
+ - template: Build/azuredevops/test/uitest-integration-stage.yml
+ parameters:
+ BinariesDirectory: $(Pipeline.Workspace)\ComponentBuildUnderTest\Binaries
+ Drop: $(Pipeline.Workspace)\ComponentBuildUnderTest\TestDataFolder
+ UITestNames: PythonTools
+
+ - template: \steps\powershell\execute-script.yml@DartLabTemplates
+ parameters:
+ displayName: Set 'RunSettings.DropName'
+ filePath: $(DartLab.Path)\Scripts\AzureDevOps\Artifacts\Drop\Get-DropName.ps1
+ arguments: -VSTSDropJsonURI '$(VSTSDropJsonURI)' -OutVariableName 'RunSettings.DropName'
+
+ - task: PowerShell@2
+ displayName: Debug arguments for 'Set RunSettings.DropName'
+ inputs:
+ targetType: inline
+ script: |
+ Write-Host "Resolved arguments for Get-DropName.ps1:"
+ Write-Host " -VSTSDropJsonURI '$($("VSTSDropJsonURI"))'"
+ Write-Host " -OutVariableName 'RunSettings.DropName'"
+ Write-Host ""
+ Write-Host "Raw argument string (as authored in YAML):"
+ Write-Host " -VSTSDropJsonURI '$(VSTSDropJsonURI)' -OutVariableName 'RunSettings.DropName'"
+ Write-Host ""
+ $path = "$(VSTSDropJsonURI)"
+ Write-Host "VSTSDropJsonURI points to: $path"
+ if ([string]::IsNullOrWhiteSpace($path)) {
+ Write-Warning "VSTSDropJsonURI is empty."
+ } elseif (Test-Path -LiteralPath $path) {
+ Write-Host "VSTSDropJsonURI exists on disk."
+ } else {
+ Write-Warning "VSTSDropJsonURI does not exist on disk (it may be a URI or incorrect path)."
+ }
+
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 2d7b2e49aa..b48fdf8d0e 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,47 +1,51 @@
-# This pipeline is used to build the PTVS product and installer.
+# This pipeline is used to build the PTVS product and installer.
# A seperate release pipeline is used to create insertion PR's into Visual Studio.
# The pipeline extends v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates from 1esPipelines repository defined in resources section.
parameters:
+ - name: pylanceVersion
+ displayName: Pylance Version
+ type: string
+ default: latest
+
+ - name: pylanceReleaseType
+ displayName: Pylance Release Type
+ type: string
+ default: stable
+ values:
+ - stable
+ - preview
+
+ - name: debugpyVersion
+ displayName: Debugpy Version
+ type: string
+ default: latest
-- name: pylanceVersion
- displayName: Pylance Version
- type: string
- default: latest
-
-- name: pylanceReleaseType
- displayName: Pylance Release Type
- type: string
- default: stable
- values:
- - stable
- - preview
-
-- name: debugpyVersion
- displayName: Debugpy Version
- type: string
- default: latest
-
-- name: PublishNugetPackageAsBuildArtifact
- displayName: Publish Nuget Package As Build Artifact
- type: boolean
- default: false
-
-# This is the version that the PTVS package currently being built will have.
-# If this value is set to 'currentBuildNumber' will default to $(Build.BuildNumber).
-# But this parameter can be used to overwrite the version number if needed.
-- name: ptvsPackageVersion
- displayName: PTVS Package Version
- type: string
- default: currentBuildNumber
-
-- name: skipGlassCache
- displayName: Skip Glass Cache
- type: boolean
- default: false
-
-# build number format
+ - name: PublishNugetPackageAsBuildArtifact
+ displayName: Publish Nuget Package As Build Artifact
+ type: boolean
+ default: false
+
+ # This is the version that the PTVS package currently being built will have.
+ # If this value is set to 'currentBuildNumber' will default to $(Build.BuildNumber).
+ # But this parameter can be used to overwrite the version number if needed.
+ - name: ptvsPackageVersion
+ displayName: PTVS Package Version
+ type: string
+ default: currentBuildNumber
+
+ - name: skipGlassCache
+ displayName: Skip Glass Cache
+ type: boolean
+ default: false
+
+ - name: skipSigning
+ displayName: Skip Signing
+ type: boolean
+ default: true
+
+# build number format
name: $(date:yy)$(DayOfYear)$(rev:.r)
# Trigger ci builds for commits into master and any release branches
@@ -53,7 +57,7 @@ trigger:
- release/*
paths:
exclude:
- - 'azure-pipelines-*.yml'
+ - "azure-pipelines-*.yml"
# Trigger pr builds for commits into master and any release branches
# Ignore changes to other yml files, since they are for different pipelines
@@ -65,19 +69,19 @@ pr:
- release/*
paths:
exclude:
- - 'azure-pipelines-*.yml'
+ - "azure-pipelines-*.yml"
drafts: false
# Trigger builds on a nightly schedule
# Always run, even if there are no PTVS changes, because we want the latest changes from all dependencies
# such as pylance, debugpy, and the latest VS int-preview bits pulled into our bootstrapper.
schedules:
-- cron: "0 8 * * *"
- displayName: Nightly build
- branches:
- include:
- - main
- always: true
+ - cron: "0 8 * * *"
+ displayName: Nightly build
+ branches:
+ include:
+ - main
+ always: true
# Build variables
# None of these are settable at build queue time. To do that, remove the variable from this list,
@@ -98,7 +102,7 @@ variables:
- name: TrackFileAccess
value: false
- name: Packaging.EnableSBOMSigning
- value: false # disabled for now because of known issue
+ value: false # disabled for now because of known issue
- name: SkipGlassCache
value: ${{ parameters.skipGlassCache }}
- name: PublishNugetPackageAsBuildArtifact
@@ -110,7 +114,7 @@ variables:
value: preview
${{ else }}:
value: ${{ parameters.pylanceReleaseType }}
-
+
# If the vs package version is not specified, use the build number
- name: ptvsPackageVersionVar
${{ if eq(parameters.ptvsPackageVersion, 'currentBuildNumber') }}:
@@ -118,6 +122,13 @@ variables:
${{ else }}:
value: ${{ parameters.ptvsPackageVersion }}
+ # Skip signing for PR builds by default, use parameter override for manual builds
+ - name: skipSigningVar
+ ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
+ value: true
+ ${{ else }}:
+ value: ${{ parameters.skipSigning }}
+
# Import variables from PTVS-Dev18 variable group
- group: PTVS-Dev17
@@ -125,144 +136,199 @@ variables:
# The ref of the repository is set to release tag which is intended to be used by most pipelines.
resources:
repositories:
- - repository: 1ESPipelineTemplates
- type: git
- name: 1ESPipelineTemplates/1ESPipelineTemplates
- ref: refs/tags/release
+ - repository: 1ESPipelineTemplates
+ type: git
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
+ ref: refs/tags/release
extends:
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
parameters:
- # The pool includes the name of your 1ES hosted pool and a VM image in that pool. Also, use os to
- # specify the image type. Here are the allowed values: windows, linux, or macOS. The default value is windows.
+ # The pool includes the name of your 1ES hosted pool and a VM image in that pool. Also, use os to
+ # specify the image type. Here are the allowed values: windows, linux, or macOS. The default value is windows.
# Hence, this property must be specified for linux and macOS.
pool:
- name: VSEngSS-MicroBuild2022-1ES
- os: windows
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
settings:
skipBuildTagsForGitHubPullRequests: true
stages:
- - stage: build
- displayName: Build
- jobs:
- - job: build
- # Set pipeline timeout to 2 hours (120 minutes)
- timeoutInMinutes: 120
+ - stage: build
displayName: Build
- # If the pipeline publishes artifacts, use `templateContext` to define the artifacts.
- # This will enable 1ES PT to run SDL analysis tools on the artifacts and then upload them.
- templateContext:
- # Disable code signing validation because we don't ship ANY of the artifacts that we publish.
- # The only released artifacts are uploaded via the 1ES.MicroBuildVstsDrop@1 below.
- sdl:
- codeSignValidation:
- enabled: false
- outputs:
- - output: pipelineArtifact
- displayName: 'Publish build artifact: binaries'
- targetPath: '$(Build.BinariesDirectory)/raw/binaries'
- artifactName: Binaries
- - output: pipelineArtifact
- displayName: 'Publish build artifact: raw'
- condition: failed()
- targetPath: '$(Build.BinariesDirectory)\raw'
- artifactName: raw
- - output: pipelineArtifact
- displayName: 'Publish build artifact: logs'
- condition: succeededOrFailed()
- targetPath: '$(Build.SourcesDirectory)\logs'
- artifactName: Logs
- - output: pipelineArtifact
- displayName: 'Publish build artifact: TestData'
- targetPath: '$(Build.ArtifactStagingDirectory)/TestDataFolder/TestData.zip'
- sbomBuildDropPath: '$(Build.ArtifactStagingDirectory)/TestDataFolder'
- artifactName: 'TestData'
- - output: pipelineArtifact
- displayName: 'Publish build artifact: RunSettings'
- targetPath: '$(Build.SourcesDirectory)/Python/Tests/TestData/default.runsettings'
- sbomBuildDropPath: '$(Build.SourcesDirectory)/Python/Tests/TestData'
- artifactName: 'RunSettings'
- - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
- - output: pipelineArtifact
- displayName: 'Publish build artifact: BoM'
- targetPath: '$(Build.BinariesDirectory)\layout'
- artifactName: SBOM
- - ${{ if or(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['PublishNugetPackageAsBuildArtifact'], true)) }}:
- - output: pipelineArtifact
- displayName: 'Publish build artifact: NuGet Package'
- targetPath: '$(Build.ArtifactStagingDirectory)\pkg'
- artifactName: pkg
-
- steps:
-
- # check out code clean from source control
- - checkout: self
- clean: true
-
- # Non-PR steps
- - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
-
- # add VSTarget build tag
- - powershell: 'Write-Host "##vso[build.addbuildtag]$env:VSTarget"'
- displayName: 'Add vstarget build tag'
-
- # install microbuild plugins used for swixproj/vsmanproj, signing, and localization
- - template: /Build/templates/install_microbuild_plugins.yml@self
-
- # Restore packages and install dependencies (pylance, debugpy)
- - template: /Build/templates/restore_packages.yml@self
- parameters:
- pylanceVersion: ${{ parameters.pylanceVersion }}
- pylanceReleaseType: ${{ variables.pylanceReleaseTypeVar }}
- debugpyVersion: ${{ parameters.debugpyVersion }}
-
- # Build and publish logs
- - template: /Build/templates/build.yml@self
- parameters:
- ptvsPackageVersion: ${{ variables.ptvsPackageVersionVar }}
-
- # Non-PR steps
- - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
-
- # Create VS bootstrapper for testing
- - template: Build/templates/create_vs_bootstrapper.yml@self
-
- # Upload vsts drop used by Visual Studio insertions
- # For more info, see https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs/microbuild-vsts-drop
- - task: 1ES.MicroBuildVstsDrop@1
- displayName: 'Upload vsts drop'
- inputs:
- dropFolder: '$(Build.StagingDirectory)\release'
- dropServiceUri: 'https://devdiv.artifacts.visualstudio.com/DefaultCollection'
- vsDropServiceUri: 'https://vsdrop.corp.microsoft.com/file/v1'
- accessToken: '$(System.AccessToken)'
- dropRetentionDays: 183
-
- # publish symbols
- - template: /Build/templates/publish_symbols.yml@self
-
- # Build and publish nuget package used by VS
- - template: /Build/templates/build_nuget_package.yml@self
- parameters:
- ptvsPackageVersion: ${{ variables.ptvsPackageVersionVar }}
-
- # MicroBuild cleanup
- - task: MicroBuildCleanup@1
- displayName: 'Execute cleanup tasks'
- condition: succeededOrFailed()
-
- # Publish test data
- - template: /Build/templates/publish_test_data.yml@self
-
- # Run tests on mixed mode debugger but only for PR builds
- # - ${{ if or(eq(variables['Build.Reason'], 'PullRequest'), eq(variables['SkipGlassCache'], true)) }}:
- # - job: test
- # displayName: Test
- # steps:
- # - template: /Build/templates/run_tests.yml@self
- # parameters:
- # skipGlassCache: ${{ parameters.skipGlassCache }}
-
-
-
-
+ jobs:
+ - job: build
+ # Set pipeline timeout to 2 hours (120 minutes)
+ timeoutInMinutes: 120
+ displayName: Build
+ variables:
+ BootloaderDropName: "Bootloader/$(System.TeamProject)/$(Build.BuildNumber)/$(Build.BuildId)"
+ # If the pipeline publishes artifacts, use `templateContext` to define the artifacts.
+ # This will enable 1ES PT to run SDL analysis tools on the artifacts and then upload them.
+ templateContext:
+ isProduction: false
+ # Disable code signing validation because we don't ship ANY of the artifacts that we publish.
+ # The only released artifacts are uploaded via the 1ES.MicroBuildVstsDrop@1 below.
+ sdl:
+ codeql:
+ # disable if not commit in main or release
+ ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')) }}:
+ enabled: true
+ ${{ else }}:
+ enabled: false
+ codeSignValidation:
+ enabled: false
+ sbom:
+ enabled: false # Disable global SBOM generation; we'll enable selectively per artifact output
+ outputs:
+ # - output: artifactsDrop # upload to artifact drop service for azure_pipelines_integration_tests.yml pipeline
+ # displayName: 'Upload MicroBuild to Artifact Services'
+ # sourcePath: $(Build.ArtifactStagingDirectory)\MicroBuild\Output
+ # dropServiceURI: https://devdiv.artifacts.visualstudio.com/DefaultCollection/
+ # dropMetadataContainerName: MicroBuildOutputs
+ # buildNumber: '$(BootloaderDropName)'
+ - output: pipelineArtifact
+ displayName: 📢 Publish MicroBuildOutputs
+ targetPath: $(Build.ArtifactStagingDirectory)\MicroBuild\Output
+ artifactName: MicroBuildOutputs
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: binaries"
+ targetPath: "$(Build.BinariesDirectory)/raw/binaries"
+ artifactName: Binaries
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: raw"
+ condition: failed()
+ targetPath: '$(Build.BinariesDirectory)\raw'
+ artifactName: raw
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: logs"
+ condition: succeededOrFailed()
+ targetPath: '$(Build.SourcesDirectory)\logs'
+ artifactName: Logs
+ - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: BoM"
+ targetPath: '$(Build.BinariesDirectory)\layout'
+ artifactName: SBOM
+ - ${{ if or(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['PublishNugetPackageAsBuildArtifact'], true)) }}:
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: NuGet Package"
+ targetPath: '$(Build.ArtifactStagingDirectory)\pkg'
+ artifactName: pkg
+
+ steps:
+ # check out code clean from source control
+ - checkout: self
+ clean: true
+ fetchDepth: 1
+ persistCredentials: true
+
+ # Non-PR steps
+ - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
+ # add VSTarget build tag
+ - powershell: 'Write-Host "##vso[build.addbuildtag]$env:VSTarget"'
+ displayName: "Add vstarget build tag"
+
+ # install microbuild plugins used for swixproj/vsmanproj, signing, and localization
+ - template: /Build/templates/install_microbuild_plugins.yml@self
+
+ # Restore packages and install dependencies (pylance, debugpy)
+ - template: /Build/templates/restore_packages.yml@self
+ parameters:
+ pylanceVersion: ${{ parameters.pylanceVersion }}
+ pylanceReleaseType: ${{ variables.pylanceReleaseTypeVar }}
+ debugpyVersion: ${{ parameters.debugpyVersion }}
+
+ # Build and publish logs
+ - template: /Build/templates/build.yml@self
+ parameters:
+ ptvsPackageVersion: ${{ variables.ptvsPackageVersionVar }}
+ skipSigning: ${{ variables.skipSigningVar }}
+
+ # Non-PR steps
+ # - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
+ # Create VS bootstrapper for testing
+ - template: Build/templates/create_vs_bootstrapper.yml@self
+
+ # Upload vsts drop used by Visual Studio insertions
+ # For more info, see https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs/microbuild-vsts-drop
+ - task: 1ES.MicroBuildVstsDrop@1
+ displayName: "Upload vsts drop"
+ inputs:
+ dropFolder: '$(Build.StagingDirectory)\release'
+ dropServiceUri: "https://devdiv.artifacts.visualstudio.com/DefaultCollection"
+ vsDropServiceUri: "https://vsdrop.corp.microsoft.com/file/v1"
+ accessToken: "$(System.AccessToken)"
+ dropRetentionDays: 183
+
+ # publish symbols
+ - template: /Build/templates/publish_symbols.yml@self
+
+ # Build and publish nuget package used by VS
+ - template: /Build/templates/build_nuget_package.yml@self
+ parameters:
+ ptvsPackageVersion: ${{ variables.ptvsPackageVersionVar }}
+
+ # MicroBuild cleanup
+ - task: MicroBuildCleanup@1
+ displayName: "Execute cleanup tasks"
+ condition: succeededOrFailed()
+
+ # Separate job for TestData generation - runs in parallel with build job
+ - job: testdata
+ displayName: Publish TestData
+ variables:
+ TestDataDropName: "devdiv/ptvs/tests/$(Build.BuildNumber)/$(Build.BuildId)"
+ TestStoreDropName: "$(TestDataDropName)"
+ templateContext:
+ isProduction: false
+ sdl:
+ codeSignValidation:
+ enabled: false
+ sbom:
+ enabled: false
+ outputs:
+ - output: pipelineArtifact
+ displayName: 📢 Publish PTVS-TestData
+ targetPath: $(Build.ArtifactStagingDirectory)/TestDataFolder/
+ artifactName: TestDataFolder
+ - output: artifactsDrop # upload to artifact drop service for azure_pipelines_integration_tests.yml pipeline
+ displayName: "Upload Test Data to Artifact Services"
+ sourcePath: $(Build.ArtifactStagingDirectory)/TestDataFolder
+ dropServiceURI: https://devdiv.artifacts.visualstudio.com/DefaultCollection/
+ buildNumber: "$(TestDataDropName)"
+ dropMetadataContainerName: PTVS-TestData
+ - output: pipelineArtifact
+ displayName: "Publish build artifact: TestData"
+ targetPath: "$(Build.ArtifactStagingDirectory)/TestDataFolder/TestData.zip"
+ artifactName: "TestData"
+ # - output: pipelineArtifact
+ # displayName: "Publish build artifact: RunSettings"
+ # targetPath: "$(Build.SourcesDirectory)/Python/Tests/TestData/default.runsettings"
+ # artifactName: "RunSettings"
+
+ steps:
+ # check out code clean from source control
+ - checkout: self
+ clean: true
+ fetchDepth: 1
+ persistCredentials: true
+
+ # Publish test data
+ - template: /Build/templates/publish_test_data.yml@self
+
+ # Copy runsettings to TestDataFolder for azure_pipelines_integration_tests.yml pipeline
+ # - task: CopyFiles@2
+ # displayName: "Copy runsettings to TestDataFolder"
+ # inputs:
+ # SourceFolder: "$(Build.SourcesDirectory)/Python/Tests/TestData"
+ # Contents: "DDRITs.runsettings"
+ # TargetFolder: "$(Build.ArtifactStagingDirectory)/TestDataFolder"
+
+ # Run tests on mixed mode debugger but only for PR builds
+ # - ${{ if or(eq(variables['Build.Reason'], 'PullRequest'), eq(variables['SkipGlassCache'], true)) }}:
+ # - job: test
+ # displayName: Test
+ # steps:
+ # - template: /Build/templates/run_tests.yml@self
+ # parameters:
+ # skipGlassCache: ${{ parameters.skipGlassCache }}
diff --git a/package.json b/package.json
index befda4439b..30b28f16c4 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,6 @@
"name": "ptvs",
"private": true,
"devDependencies": {
- "@pylance/pylance": "2025.9.1"
+ "@pylance/pylance": "2025.10.4"
}
}