From 269cf5afabedde27ad4b7dc8e6ee92b11050230a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 22 Aug 2025 13:54:37 -0700 Subject: [PATCH 1/5] Migrate to Deployment Model The timed task will cause the pipeline to fail. It may have a 'resume' feature we can check to see if it actually failed or not, but there is no way to pause the next task and 'pass' that 'resume' onto the next step, because the timed task is using a 'serverless' pool. This method is more complicated but a better e2e approach. This commit removes the line which does the publish so I can test that the deployment 'gate' in the environment actually works. --- pipeline-templates/package-vsix.yaml | 2 +- pipeline-templates/publish.yaml | 149 ++++++++++++++++++--------- 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/pipeline-templates/package-vsix.yaml b/pipeline-templates/package-vsix.yaml index 9adaf54abf..0d72722192 100644 --- a/pipeline-templates/package-vsix.yaml +++ b/pipeline-templates/package-vsix.yaml @@ -17,7 +17,7 @@ jobs: - output: pipelineArtifact displayName: '📂 Publish .VSIX' targetPath: '$(Build.ArtifactStagingDirectory)' - artifactName: '$(dir-name)' + artifactName: vscode-dotnet-install-tool steps: - template: install-node.yaml - bash: | diff --git a/pipeline-templates/publish.yaml b/pipeline-templates/publish.yaml index 3acebb9a82..9e7f399416 100644 --- a/pipeline-templates/publish.yaml +++ b/pipeline-templates/publish.yaml @@ -4,59 +4,108 @@ parameters: useOneEngineeringPool: '' jobs: - - job: waitForValidation - displayName: ☁️ Wait for release approval - pool: server - timeoutInMinutes: 4320 # job times out in 3 days - steps: - - task: ManualValidation@0 - timeoutInMinutes: 4320 + - deployment: PublishToMarketplace + templateContext: + type: releaseJob + isProduction: true inputs: - instructions: 'Please validate that the release build has been tested, and resume to publish a new version' - onTimeout: 'reject' - - job: Publish + - input: pipelineArtifact + artifactName: vscode-dotnet-install-tool + targetPath: '$(System.DefaultWorkingDirectory)' # This is the destination path. + listFiles: true pool: ${{ parameters.pool }} displayName: '🌐 Publish to Marketplace' + environment: 'vscode-dotnetcore-extension-releases' # This requires approval gates configured in Azure DevOps dependsOn: - - waitForValidation - ${{ parameters.pool.os }}_Package - steps: - - task: DownloadPipelineArtifact@2 - displayName: '⬇️ Download Packaged Extension' - inputs: - path: '$(System.ArtifactsDirectory)' - - template: install-node.yaml - - template: list-file-structure.yaml - - bash: | - VERSION=`node -p "require('./package.json').version"` - npm version $VERSION --allow-same-version - echo "##vso[task.setvariable variable=version;isOutput=true]$VERSION" - name: GetVersion - displayName: '❓ Get Version' - workingDirectory: 'vscode-dotnet-runtime-extension' - - task: AzureCLI@2 - displayName: '🚀 Publish to Marketplace' - inputs: - azureSubscription: 'VSCode Marketplace Publishing' - scriptType: "pscore" - scriptLocation: 'inlineScript' - workingDirectory: '$(System.ArtifactsDirectory)' - inlineScript: | - npm i -g --verbose @vscode/vsce - $basePublishArgs = , "publish" - $basePublishArgs += '--azure-credential' - $basePublishArgs += '--packagePath' - $publishArgs = $basePublishArgs + 'vscode-dotnet-runtime-$(GetVersion.version)-signed.vsix' - $publishArgs += '--manifestPath' - $publishArgs += 'vscode-dotnet-runtime-$(GetVersion.version).manifest' - $publishArgs += '--signaturePath' - $publishArgs += 'vscode-dotnet-runtime-$(GetVersion.version).signature.p7s' - If ("${{ parameters.SignType }}" -ne "Real") { - Write-Host "With a test-signed build, the command to publish is printed instead of run." - Write-Host "##[command]vsce $publishArgs" - } - Else { - Write-Host "##[command]vsce $publishArgs" - vsce @publishArgs - } \ No newline at end of file + strategy: + runOnce: + deploy: + steps: + - template: install-node.yaml + - template: list-file-structure.yaml + - pwsh: | + # Extract version from downloaded VSIX filename + $packagesPath = Join-Path -Path $(System.DefaultWorkingDirectory) -ChildPath 'packages' + Write-Host "Artifacts directory contents:" + Get-ChildItem -Path $packagesPath -Recurse | Format-Table Name, FullName + + $vsixFile = Get-ChildItem -Path $packagesPath -Recurse -Filter "vscode-dotnet-runtime-*.vsix" | Select-Object -First 1 + if (-not $vsixFile) { + Write-Error "Could not find VSIX file in artifacts/packages" + exit 1 + } + + # Extract version from filename (e.g., vscode-dotnet-runtime-1.2.3.vsix -> 1.2.3) + if ($vsixFile.Name -match 'vscode-dotnet-runtime-(.+)\.vsix$') { + $version = $matches[1] + # Handle signed VSIX files (remove -signed suffix if present) + $version = $version -replace '-signed$', '' + Write-Host "Extracted version: $version" + echo "##vso[task.setvariable variable=version;isOutput=true]$version" + } else { + Write-Error "Could not extract version from VSIX filename: $($vsixFile.Name)" + exit 1 + } + name: GetVersion + displayName: '❓ Extract Version from Artifact' + - task: AzureCLI@2 + displayName: '🚀 Publish to Marketplace' + inputs: + azureSubscription: 'VSCode Marketplace Publishing' + scriptType: "pscore" + scriptLocation: 'inlineScript' + workingDirectory: $(System.DefaultWorkingDirectory) + inlineScript: | + npm i -g --verbose @vscode/vsce + + $packagesPath = Join-Path -Path $(System.DefaultWorkingDirectory) -ChildPath 'packages' + + # Find the required files using extracted version + $version = "$(GetVersion.version)" + Write-Host "Looking for files with version: $version" + + # Find VSIX file (try signed first, then regular) + $vsixFile = Get-ChildItem -Path $packagesPath -Recurse -Filter "vscode-dotnet-runtime-$version-signed.vsix" | Select-Object -First 1 + if (-not $vsixFile) { + $vsixFile = Get-ChildItem -Path $packagesPath -Recurse -Filter "vscode-dotnet-runtime-$version.vsix" | Select-Object -First 1 + } + + $manifestFile = Get-ChildItem -Path $packagesPath -Recurse -Filter "vscode-dotnet-runtime-$version.manifest" | Select-Object -First 1 + $signatureFile = Get-ChildItem -Path $packagesPath -Recurse -Filter "vscode-dotnet-runtime-$version.signature.p7s" | Select-Object -First 1 + + if (-not $vsixFile -or -not $manifestFile -or -not $signatureFile) { + Write-Error "Could not find required files for version $version in packages folder" + Write-Error "VSIX found: $($vsixFile -ne $null)" + Write-Error "Manifest found: $($manifestFile -ne $null)" + Write-Error "Signature found: $($signatureFile -ne $null)" + + Write-Host "Available files in packages folder:" + Get-ChildItem -Path $packagesPath -Recurse | Format-Table Name, FullName + exit 1 + } + + Write-Host "Using VSIX file: $($vsixFile.FullName)" + Write-Host "Using manifest: $($manifestFile.FullName)" + Write-Host "Using signature: $($signatureFile.FullName)" + + $publishArgs = @( + 'publish' + '--azure-credential' + '--packagePath' + $vsixFile.FullName + '--manifestPath' + $manifestFile.FullName + '--signaturePath' + $signatureFile.FullName + ) + + If ("${{ parameters.SignType }}" -ne "Real") { + Write-Host "With a test-signed build, the command to publish is printed instead of run." + Write-Host "##[command]vsce $publishArgs" + } + Else { + Write-Host "##[command]vsce $publishArgs" + + } \ No newline at end of file From 00d132b05a81b74064ec1ef8620f9787b321b139 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 22 Aug 2025 15:30:37 -0700 Subject: [PATCH 2/5] Add SBOM for SBOM to succeed as auto inject isnt working on prod --- pipeline-templates/publish.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pipeline-templates/publish.yaml b/pipeline-templates/publish.yaml index 9e7f399416..d108c1e047 100644 --- a/pipeline-templates/publish.yaml +++ b/pipeline-templates/publish.yaml @@ -13,12 +13,17 @@ jobs: artifactName: vscode-dotnet-install-tool targetPath: '$(System.DefaultWorkingDirectory)' # This is the destination path. listFiles: true + - input: pipelineArtifact + artifactName: SBOM + targetPath: '$(System.DefaultWorkingDirectory)\_manifest' # This is the destination path. + listFiles: true pool: ${{ parameters.pool }} displayName: '🌐 Publish to Marketplace' environment: 'vscode-dotnetcore-extension-releases' # This requires approval gates configured in Azure DevOps dependsOn: - ${{ parameters.pool.os }}_Package + - SBOM strategy: runOnce: deploy: From 0cd5fe40b4edfe4bac87f695c56920f8fbcf2a79 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 22 Aug 2025 16:05:10 -0700 Subject: [PATCH 3/5] fix slash --- pipeline-templates/publish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline-templates/publish.yaml b/pipeline-templates/publish.yaml index d108c1e047..ab35685842 100644 --- a/pipeline-templates/publish.yaml +++ b/pipeline-templates/publish.yaml @@ -15,7 +15,7 @@ jobs: listFiles: true - input: pipelineArtifact artifactName: SBOM - targetPath: '$(System.DefaultWorkingDirectory)\_manifest' # This is the destination path. + targetPath: '$(System.DefaultWorkingDirectory)/_manifest' # This is the destination path. listFiles: true pool: ${{ parameters.pool }} From a4d4f29097d2ed627ce6fbd3f43cb91785684110 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 22 Aug 2025 16:07:02 -0700 Subject: [PATCH 4/5] publish sbom to build artifacts as well --- pipeline-templates/publish.yaml | 2 +- pipeline-templates/sbom.yaml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pipeline-templates/publish.yaml b/pipeline-templates/publish.yaml index ab35685842..9b4ef7e58b 100644 --- a/pipeline-templates/publish.yaml +++ b/pipeline-templates/publish.yaml @@ -14,7 +14,7 @@ jobs: targetPath: '$(System.DefaultWorkingDirectory)' # This is the destination path. listFiles: true - input: pipelineArtifact - artifactName: SBOM + artifactName: StagedSBOM targetPath: '$(System.DefaultWorkingDirectory)/_manifest' # This is the destination path. listFiles: true pool: diff --git a/pipeline-templates/sbom.yaml b/pipeline-templates/sbom.yaml index bae74a3e52..f42c7c3838 100644 --- a/pipeline-templates/sbom.yaml +++ b/pipeline-templates/sbom.yaml @@ -19,4 +19,8 @@ jobs: - output: pipelineArtifact displayName: 📢 Publishing SBOM artifact: SBOM - targetPath: $(System.DefaultWorkingDirectory)/_manifest \ No newline at end of file + targetPath: $(System.DefaultWorkingDirectory)/_manifest + - output: pipelineArtifact + displayName: 📢 Publishing SBOM for Staging + artifact: StagedSBOM + targetPath: '$(Build.ArtifactStagingDirectory)' From 044be54e0163518e3f985fafdb72ace249ccf0f1 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 22 Aug 2025 16:52:05 -0700 Subject: [PATCH 5/5] see if sbom can be dl'd --- pipeline-templates/publish.yaml | 2 +- pipeline-templates/sbom.yaml | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/pipeline-templates/publish.yaml b/pipeline-templates/publish.yaml index 9b4ef7e58b..ab35685842 100644 --- a/pipeline-templates/publish.yaml +++ b/pipeline-templates/publish.yaml @@ -14,7 +14,7 @@ jobs: targetPath: '$(System.DefaultWorkingDirectory)' # This is the destination path. listFiles: true - input: pipelineArtifact - artifactName: StagedSBOM + artifactName: SBOM targetPath: '$(System.DefaultWorkingDirectory)/_manifest' # This is the destination path. listFiles: true pool: diff --git a/pipeline-templates/sbom.yaml b/pipeline-templates/sbom.yaml index f42c7c3838..ea1cf40175 100644 --- a/pipeline-templates/sbom.yaml +++ b/pipeline-templates/sbom.yaml @@ -20,7 +20,3 @@ jobs: displayName: 📢 Publishing SBOM artifact: SBOM targetPath: $(System.DefaultWorkingDirectory)/_manifest - - output: pipelineArtifact - displayName: 📢 Publishing SBOM for Staging - artifact: StagedSBOM - targetPath: '$(Build.ArtifactStagingDirectory)'