From 0ff49638d5793e6af2583263b13b5f49067aa8ce Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Mon, 24 Aug 2026 16:21:07 -0700 Subject: [PATCH 1/3] Harden extension packaging verification --- Build/package/jobs_package_vsix.yml | 12 ++++++------ Build/publish/cpptools_extension_pack.yml | 1 + Build/publish/cpptools_themes.yml | 1 + Build/publish/jobs_publish_vsix.yml | 20 ++++++++++++++++++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Build/package/jobs_package_vsix.yml b/Build/package/jobs_package_vsix.yml index 703fbf487..a8d161bb1 100644 --- a/Build/package/jobs_package_vsix.yml +++ b/Build/package/jobs_package_vsix.yml @@ -48,9 +48,9 @@ jobs: script: | export SRC_DIR=$(echo $BUILD_SOURCESDIRECTORY | sed 's|\\|/|g') cd "$SRC_DIR/${{ parameters.srcDir }}" - npm install + npm ci --include=dev --include=optional if [ $? -ne 0 ]; then - echo "npm install failed, sleeping for 30s before retrying..." + echo "npm ci failed, sleeping for 30s before retrying..." sleep 30 exit 1 fi @@ -59,10 +59,6 @@ jobs: - script: mkdir $(Build.ArtifactStagingDirectory)\vsix displayName: Create Staging Directory - - script: npm install --no-save --ignore-scripts=false --include=optional --force @vscode/vsce@3.9.2 - displayName: Install vsce - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} - - script: npm rebuild @vscode/vsce-sign --ignore-scripts=false displayName: Rebuild vsce-sign binary workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} @@ -93,3 +89,7 @@ jobs: inputs: solution: $(Build.SourcesDirectory)\Build\signing\SignVsix.proj msbuildArguments: /p:SignType=${{ parameters.signType }} + + - script: npx vsce verify-signature -i $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.vsix -m $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.manifest -s $(Build.ArtifactStagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s + displayName: Verify VSIX signature + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} diff --git a/Build/publish/cpptools_extension_pack.yml b/Build/publish/cpptools_extension_pack.yml index cb30e5212..a5f775965 100644 --- a/Build/publish/cpptools_extension_pack.yml +++ b/Build/publish/cpptools_extension_pack.yml @@ -40,4 +40,5 @@ extends: - template: /Build/publish/jobs_publish_vsix.yml@self parameters: vsixName: cpptools-extension-pack + srcDir: ExtensionPack diff --git a/Build/publish/cpptools_themes.yml b/Build/publish/cpptools_themes.yml index ea93bbce7..011b317e8 100644 --- a/Build/publish/cpptools_themes.yml +++ b/Build/publish/cpptools_themes.yml @@ -40,4 +40,5 @@ extends: - template: /Build/publish/jobs_publish_vsix.yml@self parameters: vsixName: cpptools-themes + srcDir: Themes diff --git a/Build/publish/jobs_publish_vsix.yml b/Build/publish/jobs_publish_vsix.yml index d2d949804..160c48746 100644 --- a/Build/publish/jobs_publish_vsix.yml +++ b/Build/publish/jobs_publish_vsix.yml @@ -2,6 +2,9 @@ parameters: - name: vsixName type: string default: '' +- name: srcDir + type: string + default: '' jobs: - job: Publish @@ -16,11 +19,16 @@ jobs: targetPath: $(Build.StagingDirectory)\vsix steps: + - checkout: self + - task: NodeTool@0 displayName: Use Node 22.x inputs: versionSpec: 22.x + - script: IF EXIST %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc del %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc + displayName: Delete .npmrc if it exists + - task: AzureCLI@2 displayName: Generate AAD_TOKEN inputs: @@ -31,16 +39,24 @@ jobs: $aadToken = az account get-access-token --query accessToken --resource $(AzureGuid) -o tsv Write-Host "##vso[task.setvariable variable=AAD_TOKEN;issecret=true]$aadToken" - - script: npm install --no-save --ignore-scripts=false --include=optional --force @vscode/vsce@3.9.2 - displayName: Install vsce + - script: npm ci --include=dev --include=optional + displayName: Install dependencies + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} - script: npm rebuild @vscode/vsce-sign --ignore-scripts=false displayName: Rebuild vsce-sign binary + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} - script: if not exist node_modules\@vscode\vsce-sign\bin\vsce-sign.exe (echo Missing vsce-sign.exe && exit 1) displayName: Verify vsce-sign binary exists + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + + - script: npx vsce verify-signature -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix -m $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest -s $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s + displayName: Verify VSIX signature + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} - script: npx vsce publish --skip-duplicate -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix --manifestPath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest --signaturePath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s displayName: Publish to Marketplace + workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} env: VSCE_PAT: $(AAD_TOKEN) From 1f560723781f679f5b0bc44942f172c30b8531de Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Sun, 20 Sep 2026 10:07:31 -0700 Subject: [PATCH 2/3] Restore base network allow policy for package pipelines --- Build/package/cpptools_extension_pack.yml | 4 +++- Build/package/cpptools_themes.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Build/package/cpptools_extension_pack.yml b/Build/package/cpptools_extension_pack.yml index 0a7bc4511..1795e6058 100644 --- a/Build/package/cpptools_extension_pack.yml +++ b/Build/package/cpptools_extension_pack.yml @@ -32,7 +32,9 @@ extends: image: 1ESPT-Windows2025 os: windows settings: - networkIsolationPolicy: CFSClean,CFSClean2,CFSClean3 + # CFSClean* supplies deny rules only; a base allow policy is also needed + # for Azure DevOps authentication and package downloads. + networkIsolationPolicy: Permissive,CFSClean,CFSClean2,CFSClean3 stages: - stage: package diff --git a/Build/package/cpptools_themes.yml b/Build/package/cpptools_themes.yml index 75dcdc091..957e44dfa 100644 --- a/Build/package/cpptools_themes.yml +++ b/Build/package/cpptools_themes.yml @@ -32,7 +32,9 @@ extends: image: 1ESPT-Windows2025 os: windows settings: - networkIsolationPolicy: CFSClean,CFSClean2,CFSClean3 + # CFSClean* supplies deny rules only; a base allow policy is also needed + # for Azure DevOps authentication and package downloads. + networkIsolationPolicy: Permissive,CFSClean,CFSClean2,CFSClean3 stages: - stage: package From 218377b37d1f46fcf994d9148b22e65baf9a108d Mon Sep 17 00:00:00 2001 From: Sean McManus Date: Sun, 20 Sep 2026 10:49:27 -0700 Subject: [PATCH 3/3] Supply release tooling through package artifacts --- Build/package/jobs_package_vsix.yml | 14 ++++++++++++++ Build/publish/cpptools_extension_pack.yml | 1 - Build/publish/cpptools_themes.yml | 1 - Build/publish/jobs_publish_vsix.yml | 19 +++++++++---------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Build/package/jobs_package_vsix.yml b/Build/package/jobs_package_vsix.yml index a8d161bb1..db94633d8 100644 --- a/Build/package/jobs_package_vsix.yml +++ b/Build/package/jobs_package_vsix.yml @@ -29,6 +29,10 @@ jobs: displayName: '${{ parameters.vsixName }}.vsix' targetPath: $(Build.ArtifactStagingDirectory)\vsix artifactName: vsix + - output: pipelineArtifact + displayName: Locked VSCE dependencies + targetPath: $(Build.ArtifactStagingDirectory)\vsce + artifactName: vsce steps: - checkout: self @@ -59,6 +63,16 @@ jobs: - script: mkdir $(Build.ArtifactStagingDirectory)\vsix displayName: Create Staging Directory + - task: CopyFiles@2 + displayName: Stage locked VSCE dependencies for publishing + inputs: + SourceFolder: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + Contents: | + package.json + package-lock.json + .npmrc + TargetFolder: $(Build.ArtifactStagingDirectory)\vsce + - script: npm rebuild @vscode/vsce-sign --ignore-scripts=false displayName: Rebuild vsce-sign binary workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} diff --git a/Build/publish/cpptools_extension_pack.yml b/Build/publish/cpptools_extension_pack.yml index a5f775965..cb30e5212 100644 --- a/Build/publish/cpptools_extension_pack.yml +++ b/Build/publish/cpptools_extension_pack.yml @@ -40,5 +40,4 @@ extends: - template: /Build/publish/jobs_publish_vsix.yml@self parameters: vsixName: cpptools-extension-pack - srcDir: ExtensionPack diff --git a/Build/publish/cpptools_themes.yml b/Build/publish/cpptools_themes.yml index 011b317e8..ea93bbce7 100644 --- a/Build/publish/cpptools_themes.yml +++ b/Build/publish/cpptools_themes.yml @@ -40,5 +40,4 @@ extends: - template: /Build/publish/jobs_publish_vsix.yml@self parameters: vsixName: cpptools-themes - srcDir: Themes diff --git a/Build/publish/jobs_publish_vsix.yml b/Build/publish/jobs_publish_vsix.yml index 160c48746..097d31921 100644 --- a/Build/publish/jobs_publish_vsix.yml +++ b/Build/publish/jobs_publish_vsix.yml @@ -2,9 +2,6 @@ parameters: - name: vsixName type: string default: '' -- name: srcDir - type: string - default: '' jobs: - job: Publish @@ -17,10 +14,12 @@ jobs: pipeline: vsixBuild artifactName: vsix targetPath: $(Build.StagingDirectory)\vsix + - input: pipelineArtifact + pipeline: vsixBuild + artifactName: vsce + targetPath: $(Build.StagingDirectory)\vsce steps: - - checkout: self - - task: NodeTool@0 displayName: Use Node 22.x inputs: @@ -41,22 +40,22 @@ jobs: - script: npm ci --include=dev --include=optional displayName: Install dependencies - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + workingDirectory: $(Build.StagingDirectory)\vsce - script: npm rebuild @vscode/vsce-sign --ignore-scripts=false displayName: Rebuild vsce-sign binary - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + workingDirectory: $(Build.StagingDirectory)\vsce - script: if not exist node_modules\@vscode\vsce-sign\bin\vsce-sign.exe (echo Missing vsce-sign.exe && exit 1) displayName: Verify vsce-sign binary exists - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + workingDirectory: $(Build.StagingDirectory)\vsce - script: npx vsce verify-signature -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix -m $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest -s $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s displayName: Verify VSIX signature - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + workingDirectory: $(Build.StagingDirectory)\vsce - script: npx vsce publish --skip-duplicate -i $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.vsix --manifestPath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.manifest --signaturePath $(Build.StagingDirectory)\vsix\${{ parameters.vsixName }}.signature.p7s displayName: Publish to Marketplace - workingDirectory: $(Build.SourcesDirectory)\${{ parameters.srcDir }} + workingDirectory: $(Build.StagingDirectory)\vsce env: VSCE_PAT: $(AAD_TOKEN)