diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a5e0c08850..6bab78e5c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -899,6 +899,7 @@ All PRs automatically run the following validation checks: - **Spelling check** - Validates spelling across the codebase - **AOT compatibility** - Checks ahead-of-time compilation compatibility - **Tool metadata verification** - Ensures `azmcp-commands.md` is up-to-date with tool metadata (run `.\eng\scripts\Update-AzCommandsMetadata.ps1` if this fails) +- **VSIX packaging** - On changes to a VS Code extension's `package.json` or `package-lock.json`, resolves its npm dependencies and packages the extension without signing or publishing. ## Support and Community diff --git a/eng/pipelines/templates/common.yml b/eng/pipelines/templates/common.yml index 78fbac9d6d..3972b2df8c 100644 --- a/eng/pipelines/templates/common.yml +++ b/eng/pipelines/templates/common.yml @@ -103,6 +103,22 @@ extends: MaxParallel: 4 HostArchitecture: arm64 + - stage: VSIXPack + displayName: "VSIX pack" + dependsOn: + - Initialize + - Build + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) + pool: + name: $(LINUXPOOL) + image: $(LINUXVMIMAGE) + os: linux + variables: + - template: /eng/pipelines/templates/variables/image.yml + - template: /eng/pipelines/templates/variables/globals.yml + jobs: + - template: /eng/pipelines/templates/jobs/vsix/pack-vsix-pr.yml + - ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.RunLiveTests, 'true')) }}: - stage: Test displayName: 'Live test' diff --git a/eng/pipelines/templates/jobs/vsix/pack-vsix-pr.yml b/eng/pipelines/templates/jobs/vsix/pack-vsix-pr.yml new file mode 100644 index 0000000000..8a13a79e89 --- /dev/null +++ b/eng/pipelines/templates/jobs/vsix/pack-vsix-pr.yml @@ -0,0 +1,53 @@ +jobs: +- job: PackVSIXForPR + displayName: "Pack VSIX" + steps: + - checkout: self + fetchDepth: 0 + + - pwsh: | + $changedFiles = & ./eng/common/scripts/get-changedfiles.ps1 -DiffFilterType '' + $hasVsixDependencyChanges = @($changedFiles | Where-Object { + $_ -match '^servers/[^/]+/vscode/package(-lock)?\.json$' + }).Count -gt 0 + Write-Host "##vso[task.setvariable variable=RunVsixPackaging]$($hasVsixDependencyChanges.ToString().ToLowerInvariant())" + displayName: "Detect VSIX dependency changes" + + - download: current + artifact: build_info + displayName: "Download build_info" + condition: eq(variables['RunVsixPackaging'], 'true') + + - download: current + displayName: "Download binaries" + condition: eq(variables['RunVsixPackaging'], 'true') + + - task: UseNode@1 + displayName: "Install Node.js 24" + condition: eq(variables['RunVsixPackaging'], 'true') + inputs: + version: "24.x" + + - task: Powershell@2 + displayName: "Prepare binaries for VSIX" + condition: eq(variables['RunVsixPackaging'], 'true') + inputs: + pwsh: true + filePath: $(Build.SourcesDirectory)/eng/scripts/Compress-ForSigning.ps1 + arguments: > + -BuildInfoPath '$(Pipeline.Workspace)/build_info/build_info.json' + -ArtifactsPath '$(Pipeline.Workspace)' + -ArtifactPrefix 'binaries_' + -OutputPath '$(Pipeline.Workspace)/binaries' + -PrepareForVsix + + - task: Powershell@2 + displayName: "Pack VSIX" + condition: eq(variables['RunVsixPackaging'], 'true') + inputs: + pwsh: true + filePath: $(Build.SourcesDirectory)/eng/scripts/Pack-Vsix.ps1 + arguments: > + -BuildInfoPath '$(Pipeline.Workspace)/build_info/build_info.json' + -ArtifactsPath '$(Pipeline.Workspace)/binaries' + -OutputPath '$(Build.ArtifactStagingDirectory)' diff --git a/eng/scripts/Compress-ForSigning.ps1 b/eng/scripts/Compress-ForSigning.ps1 index 8961c5445a..d795bc1f76 100644 --- a/eng/scripts/Compress-ForSigning.ps1 +++ b/eng/scripts/Compress-ForSigning.ps1 @@ -7,6 +7,7 @@ param( [string] $ArtifactsPath, [string] $ArtifactPrefix, [string] $OutputPath, + [switch] $PrepareForVsix, [switch] $CI ) @@ -98,7 +99,7 @@ foreach ($server in $buildInfo.servers) { Write-Host "Copying $platformSourcePath to $platformOutputPath`n" -ForegroundColor Yellow Copy-Item -Path $platformSourcePath -Destination $platformOutputPath -Recurse -Force -ProgressAction SilentlyContinue - if ($platform.operatingSystem -eq 'macos') { + if ($platform.operatingSystem -eq 'macos' -and !$PrepareForVsix) { # Only mac binaries need to be compressed. Linux binaries aren't signed and windows are signed uncompressed. # Mac requires code signing the binary with an entitlements file such that the signed and notarized binary will properly invoke on @@ -125,7 +126,7 @@ foreach ($server in $buildInfo.servers) { } } -if($isPipelineRun) { +if($isPipelineRun -and !$PrepareForVsix) { if ($buildInfo.servers.Count -ne 1) { LogError "Compress-ForSigning.ps1 only supports single-server builds in a pipeline context." exit 1