From b785b6eade63437f207907b30844dd769c78f3ef Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 09:38:58 -0500 Subject: [PATCH 01/41] pipelines: Major improvements --- azure-pipelines/v2/1es-mb-main.yml | 87 +++++++++++++ .../v2/1es-mb-release-extension.yml | 116 +++++++++++++++++ azure-pipelines/v2/1es-mb-release-npm.yml | 122 ++++++++++++++++++ azure-pipelines/v2/azcode.variables.yml | 20 +++ azure-pipelines/v2/stages/1es-stages.yml | 66 ++++++++++ azure-pipelines/v2/templates/1es-mb-sign.yml | 58 +++++++++ azure-pipelines/v2/templates/build.yml | 7 + .../v2/templates/find-tarballs.yml | 50 +++++++ azure-pipelines/v2/templates/find-vsixs.yml | 50 +++++++ azure-pipelines/v2/templates/lint.yml | 7 + azure-pipelines/v2/templates/package.yml | 7 + .../v2/templates/set-release-build-number.yml | 24 ++++ azure-pipelines/v2/templates/setup.yml | 13 ++ .../v2/templates/stage-artifacts.yml | 18 +++ azure-pipelines/v2/templates/test.yml | 38 ++++++ 15 files changed, 683 insertions(+) create mode 100644 azure-pipelines/v2/1es-mb-main.yml create mode 100644 azure-pipelines/v2/1es-mb-release-extension.yml create mode 100644 azure-pipelines/v2/1es-mb-release-npm.yml create mode 100644 azure-pipelines/v2/azcode.variables.yml create mode 100644 azure-pipelines/v2/stages/1es-stages.yml create mode 100644 azure-pipelines/v2/templates/1es-mb-sign.yml create mode 100644 azure-pipelines/v2/templates/build.yml create mode 100644 azure-pipelines/v2/templates/find-tarballs.yml create mode 100644 azure-pipelines/v2/templates/find-vsixs.yml create mode 100644 azure-pipelines/v2/templates/lint.yml create mode 100644 azure-pipelines/v2/templates/package.yml create mode 100644 azure-pipelines/v2/templates/set-release-build-number.yml create mode 100644 azure-pipelines/v2/templates/setup.yml create mode 100644 azure-pipelines/v2/templates/stage-artifacts.yml create mode 100644 azure-pipelines/v2/templates/test.yml diff --git a/azure-pipelines/v2/1es-mb-main.yml b/azure-pipelines/v2/1es-mb-main.yml new file mode 100644 index 0000000000..0e9ebc7174 --- /dev/null +++ b/azure-pipelines/v2/1es-mb-main.yml @@ -0,0 +1,87 @@ +parameters: + # Set to true for official builds, false for PRs and other unofficial builds + - name: isOfficialBuild + type: boolean + default: true + + # The jobs to run. Use to parallelize building in subdirectories + - name: jobs + type: object + default: + - name: Root + working_directory: . + + # The pool to use for the SDL stage + - name: sdlPool + type: object + default: + name: VSEngSS-MicroBuild2022-1ES + image: server2022-microbuildVS2022-1es + os: windows + + # The pool to use for the build stage + - name: buildPool + type: object + default: + name: AzurePipelines-EO + image: 1ESPT-Ubuntu22.04 + os: linux + + # Set to 'real' or 'test' to enable MicroBuild signing + - name: signType + type: string + values: + - real + - test + - none + default: real + + # Supply to disable MicroBuild signing steps and use these instead + - name: alternativeSigningSteps + type: stepList + default: [] + + # Additional steps to run during setup (e.g. npm authenticate etc.) + - name: additionalSetupSteps + type: stepList + default: [] + + # Set to the ARM service connection name to enable tests with Azure federated credentials + - name: testARMServiceConnection + type: string + default: "" + +resources: + repositories: + - repository: MicroBuildTemplate + type: git + name: MicroBuildTemplates/MicroBuildTemplates + ref: refs/tags/release + +extends: + ${{ if eq(parameters.isOfficialBuild, true) }}: + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + ${{ else }}: + template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate + + parameters: + sdl: + ${{ if eq(parameters.isOfficialBuild, true) }}: + tsa: + enabled: true + componentgovernance: + directoryExclusionPatterns: "**/.vscode-test" + codeql: + excludePathPatterns: "**/.vscode-test, **/dist" + + pool: ${{ parameters.sdlPool }} + + stages: + - template: ./stages/1es-stages.yml + parameters: + jobs: ${{ parameters.jobs }} + buildPool: ${{ parameters.buildPool }} + signType: ${{ parameters.signType }} + alternativeSigningSteps: ${{ parameters.alternativeSigningSteps }} + additionalSetupSteps: ${{ parameters.additionalSetupSteps }} + testARMServiceConnection: ${{ parameters.testARMServiceConnection }} diff --git a/azure-pipelines/v2/1es-mb-release-extension.yml b/azure-pipelines/v2/1es-mb-release-extension.yml new file mode 100644 index 0000000000..97429b2860 --- /dev/null +++ b/azure-pipelines/v2/1es-mb-release-extension.yml @@ -0,0 +1,116 @@ +parameters: + # The name of the package to publish. + # This is regex matched against .vsix files found in the build artifact. + - name: packageToPublish + type: string + + # The intended package version to publish. + # This is used to verify the version in package.json matches the version to publish to avoid publishing the wrong package/version + - name: publishVersion + type: string + + # When true, skips the deployment job that actually publishes the package + - name: dryRun + type: boolean + default: false + + # In the build artifacts, the name of the artifact containing the package to publish + - name: artifactName + type: string + default: Build Root + + # The service connection that VSCE will use to publish the extension + - name: extensionReleaseServiceConnection + type: string + + # Set to the AzDO environment used for enforcing approval before the release runs + - name: releaseApprovalEnvironment + type: string + default: "" + + # The pool to use for releases + - name: releasePool + type: object + default: + name: VSEngSS-MicroBuild2022-1ES + image: server2022-microbuildVS2022-1es + os: windows + +resources: + repositories: + - repository: MicroBuildTemplate + type: git + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/heads/release + +extends: + template: azure-pipelines/MicroBuild.1ES.Official.Publish.yml@MicroBuildTemplate + parameters: + pool: ${{ parameters.releasePool }} + stages: + - stage: ReleaseStage + displayName: Release extension + jobs: + - job: Publish + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} + displayName: Publish extension + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + pipeline: build + targetPath: "$(System.DefaultWorkingDirectory)" + artifactName: "${{ parameters.artifactName }}" + steps: + - checkout: none + + - task: NodeTool@0 + displayName: "\U0001F449 Using Node.js" + inputs: + versionSpec: 22.x + + - template: ./templates/find-vsixs.yml + parameters: + vsixName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + + # Publish the package to VS Marketplace + - ${{ if eq(parameters.dryRun, false) }}: + - task: AzureCLI@2 + displayName: "\U0001F449 Publish VSIXs to Marketplace" + inputs: + azureSubscription: ${{ parameters.extensionReleaseServiceConnection }} + scriptType: pscore + scriptLocation: inlineScript + inlineScript: | + $vsixList = '$(vsixListJson)' | ConvertFrom-Json + + # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well + foreach ($vsix in $vsixList) { + Set-Location $vsix.directory + + $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" + if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { + # TODO: Need to make sure this is the right argument syntax for multiple proposed APIs + $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" + } + + # TODO: Need to make sure that if an extension was packaged as platform-specific, it doesn't still need to be published with the same platform-specific argument + Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" + Write-Output " $($commandLine)" + + # Execute the publish command line + # & $commandLine # TODO: temporarily disabled for testing + # if ($LASTEXITCODE -ne 0) { + # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" + # exit 1 + # } + } diff --git a/azure-pipelines/v2/1es-mb-release-npm.yml b/azure-pipelines/v2/1es-mb-release-npm.yml new file mode 100644 index 0000000000..897c2cade0 --- /dev/null +++ b/azure-pipelines/v2/1es-mb-release-npm.yml @@ -0,0 +1,122 @@ +parameters: + # The name of the package to publish. + # This is regex matched against .tgz files found in the build artifact. + - name: packageToPublish + type: string + + # The intended package version to publish. + # This is used to verify the version in package.json matches the version to publish to avoid publishing the wrong package/version + - name: publishVersion + type: string + + # When true, skips the deployment job that actually publishes the package + - name: dryRun + type: boolean + default: false + + # In the build artifacts, the name of the artifact containing the package to publish + - name: artifactName + type: string + default: Build Root + + # ESRP release also requires owner aliases, though does not use them currently + - name: ownerAliases + type: string + + # ESRP release also requires approver aliases, though does not use them currently + - name: approverAliases + type: string + + # The pool to use for releases + - name: releasePool + type: object + default: + name: VSEngSS-MicroBuild2022-1ES + image: server2022-microbuildVS2022-1es + os: windows + + # The GitHub service connection to use for creating the GitHub release (optional) + - name: gitHubServiceConnection + type: string + default: "" + + # Set to the AzDO environment used for enforcing approval before the release runs + - name: releaseApprovalEnvironment + type: string + default: "" + +resources: + repositories: + - repository: MicroBuildTemplate + type: git + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/heads/release + +extends: + template: azure-pipelines/MicroBuild.1ES.Official.Publish.yml@MicroBuildTemplate + parameters: + pool: ${{ parameters.releasePool }} + stages: + - stage: ReleaseStage + displayName: Release NPM package + jobs: + - job: Publish + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} + displayName: Publish NPM package + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + pipeline: build + targetPath: "$(System.DefaultWorkingDirectory)" + artifactName: "${{ parameters.artifactName }}" + steps: + - checkout: none + + - template: ./templates/find-tarballs.yml + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + + - pwsh: | + $tarballList = '$(tarballListJson)' | ConvertFrom-Json + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" + + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" + + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, "")) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false diff --git a/azure-pipelines/v2/azcode.variables.yml b/azure-pipelines/v2/azcode.variables.yml new file mode 100644 index 0000000000..d66c950114 --- /dev/null +++ b/azure-pipelines/v2/azcode.variables.yml @@ -0,0 +1,20 @@ +variables: + # Related to extension release approval process + - name: extensionReleaseServiceConnection + value: AzCodeReleases + - name: extensionReleaseApprovalEnvironment + value: AzCodeDeploy + + # Related to NPM release approval process + - name: gitHubServiceConnection + value: GitHub-AzureTools + - name: npmReleaseApprovalEnvironment + value: AzCodeDeploy + - name: npmReleaseOwnerAlias + value: azcode + - name: npmReleaseApproverAlias + value: jinglou + + # Test + - name: testARMServiceConnection + value: AzCodeE2ETests diff --git a/azure-pipelines/v2/stages/1es-stages.yml b/azure-pipelines/v2/stages/1es-stages.yml new file mode 100644 index 0000000000..15e340ad14 --- /dev/null +++ b/azure-pipelines/v2/stages/1es-stages.yml @@ -0,0 +1,66 @@ +parameters: + # The jobs to run. Use to parallelize building in subdirectories + - name: jobs + type: object + + # The pool to use for the build stage + - name: buildPool + type: object + + # Set to 'real' or 'test' to enable MicroBuild signing + - name: signType + type: string + values: + - real + - test + - none + + # Supply to disable MicroBuild signing steps and use these instead + - name: alternativeSigningSteps + type: stepList + + # Additional steps to run during setup (e.g. npm authenticate etc.) + - name: additionalSetupSteps + type: stepList + + # Set to enable tests with Azure federated credentials + - name: testARMServiceConnection + type: string + +stages: + - stage: BuildStage + pool: ${{ parameters.buildPool }} + jobs: + - ${{ each job in parameters.jobs }}: + - job: ${{ job.name }} + templateContext: + ${{ if eq(length(parameters.alternativeSigningSteps), 0) }}: + mb: # Enable the MicroBuild Signing toolset + signing: + enabled: ${{ ne(parameters.signType, 'none') }} + signType: ${{ parameters.signType }} + signWithProd: ${{ eq(parameters.signType, 'real') }} + zipSources: false + outputs: + - output: pipelineArtifact + targetPath: $(Build.ArtifactStagingDirectory)/build/$(artifact_name) + artifactName: Build $(artifact_name) + variables: + artifact_name: ${{ replace(job.name, '_', '-') }} + working_directory: ${{ job.working_directory }} + steps: + - checkout: self + fetchDepth: 1 + - template: ../templates/setup.yml + - ${{ parameters.additionalSetupSteps }} + - template: ../templates/lint.yml + - template: ../templates/build.yml + - template: ../templates/package.yml + - ${{ if and(eq(length(parameters.alternativeSigningSteps), 0), ne(parameters.signType, 'none')) }}: + - template: ../templates/1es-mb-sign.yml + ${{ elseif ne(length(parameters.alternativeSigningSteps), 0) }}: + - ${{ parameters.alternativeSigningSteps }} + - template: ../templates/stage-artifacts.yml + - template: ../templates/test.yml + parameters: + testARMServiceConnection: ${{ parameters.testARMServiceConnection }} diff --git a/azure-pipelines/v2/templates/1es-mb-sign.yml b/azure-pipelines/v2/templates/1es-mb-sign.yml new file mode 100644 index 0000000000..8b8b2c208f --- /dev/null +++ b/azure-pipelines/v2/templates/1es-mb-sign.yml @@ -0,0 +1,58 @@ +steps: + # Eww, but DDSignFiles.dll requires .NET Core 3.1 + - task: UseDotNet@2 + displayName: "\U0001F449 Signing: Install .NET Core 3.1" + inputs: + packageType: sdk + version: 3.1.x + + # ...and the actual PME signing tool requires .NET 8 + - task: UseDotNet@2 + displayName: "\U0001F449 Signing: Install .NET 8" + inputs: + packageType: sdk + version: 8.x + + - template: ./find-vsixs.yml + + - pwsh: | + $vsixList = '$(vsixListJson)' | ConvertFrom-Json + $fileListObject = @{ + SignFileRecordList = @( + @{ + SignFileList = @() + Certs = "4014052" # This is the VSCode publisher signing cert number + } + ) + } + + foreach ($vsix in $vsixList) { + Set-Location $vsix.directory + + # Generate manifest + Write-Output "Generating manifest for $($vsix.vsixName)..." + & npx @vscode/vsce@latest generate-manifest -i $vsix.vsixName -o $vsix.manifestName + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to generate manifest for $($vsix.vsixName)" + exit 1 + } + + # Copy the manifest to the soon-to-be-signed signature file + Copy-Item $vsix.manifestName $vsix.signatureName + + # Add to the list of files to sign + $fileListObject.SignFileRecordList[0].SignFileList += @{ + SrcPath = $(Join-Path $vsix.directory $vsix.signatureName) + DstPath = $null + } + } + + # Write out the file list to sign + $fileListObject | ConvertTo-Json -Depth 4 | Out-File -FilePath $(Build.SourcesDirectory)/filesToSign.json + displayName: "\U0001F449 Prepare VSIXs for signing" + + - pwsh: | + & dotnet $env:MBSIGN_APPFOLDER/DDSignFiles.dll -- /filelist:$(Build.SourcesDirectory)/filesToSign.json + displayName: "\U0001F449 Sign VSIX signature files" + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/azure-pipelines/v2/templates/build.yml b/azure-pipelines/v2/templates/build.yml new file mode 100644 index 0000000000..e49c244b4c --- /dev/null +++ b/azure-pipelines/v2/templates/build.yml @@ -0,0 +1,7 @@ +steps: + - task: Npm@1 + displayName: "\U0001F449 Build" + inputs: + command: custom + customCommand: run build + workingDir: $(working_directory) diff --git a/azure-pipelines/v2/templates/find-tarballs.yml b/azure-pipelines/v2/templates/find-tarballs.yml new file mode 100644 index 0000000000..73c5980ac0 --- /dev/null +++ b/azure-pipelines/v2/templates/find-tarballs.yml @@ -0,0 +1,50 @@ +parameters: + # Set to filter to tarballs matching this name (optional) + - name: tarballName + type: string + default: "" + + # Set to verify publish version matches package.json version (optional) + - name: publishVersion + type: string + default: "" + +steps: + - pwsh: | + # Find all the matching tarballs + $tarballFiles = Get-ChildItem -Recurse -Filter "${{ parameters.tarballName }}*.tgz" + + # Must be exactly one matching tarball found + if ($tarballFiles.Count -eq 0) { + Write-Error "No matching tarballs found." + exit 1 + } elseif ($tarballFiles.Count -gt 1) { + Write-Error "More than one matching tarball found." + exit 1 + } + + # Loop over the found tarballs and get their details + $tarballList = @() + foreach ($tarballFile in $tarballFiles) { + Write-Output "Discovered tarball: $($tarballFile.FullName)" + + # Get some details from the adjacent package.json + $packageJson = Get-Content "$($tarballFile.DirectoryName)/package.json" | ConvertFrom-Json + + # If publishVersion is set, verify it matches the package.json version + if ('${{ parameters.publishVersion }}' -ne '' -and $packageJson.version -ne '${{ parameters.publishVersion }}') { + Write-Error "Publish version ${{ parameters.publishVersion }} doesn't match version found in package.json $($packageJson.version). Cancelling." + exit 1 + } + + # Add it to the list + $tarballList += @{ + directory = $tarballFile.DirectoryName + tarballName = $tarballFile.Name + npmVersionString = $packageJson.version + } + } + + # Store the tarball list as JSON for later steps + Write-Output "##vso[task.setvariable variable=tarballListJson]$($tarballList | ConvertTo-Json -Compress)" + displayName: "\U0001F449 Discover all tarballs" diff --git a/azure-pipelines/v2/templates/find-vsixs.yml b/azure-pipelines/v2/templates/find-vsixs.yml new file mode 100644 index 0000000000..e17c6d5d02 --- /dev/null +++ b/azure-pipelines/v2/templates/find-vsixs.yml @@ -0,0 +1,50 @@ +parameters: + # Set to filter to VSIXs matching this name (optional) + - name: vsixName + type: string + default: "" + + # Set to verify publish version matches package.json version (optional) + - name: publishVersion + type: string + default: "" + +steps: + - pwsh: | + # Find all the (matching) VSIXs + $vsixFiles = Get-ChildItem -Recurse -Filter "${{ parameters.vsixName }}*.vsix" + + # Must be at least one VSIX found + if ($vsixFiles.Count -eq 0) { + Write-Error "No VSIXs found." + exit 1 + } + + # Loop over the found VSIXs and get their details + $vsixList = @() + foreach ($vsixFile in $vsixFiles) { + Write-Output "Discovered VSIX: $($vsixFile.FullName)" + + # Get some details from the adjacent package.json + $packageJson = Get-Content "$($vsixFile.DirectoryName)/package.json" | ConvertFrom-Json + + # If publishVersion is set, verify it matches the package.json version + if ('${{ parameters.publishVersion }}' -ne '' -and $packageJson.version -ne '${{ parameters.publishVersion }}') { + Write-Error "Publish version ${{ parameters.publishVersion }} doesn't match version found in package.json $($packageJson.version). Cancelling." + exit 1 + } + + # Add it to the list + $vsixList += @{ + directory = $vsixFile.DirectoryName + vsixName = $vsixFile.Name + manifestName = "$($vsixFile.BaseName).extension.manifest" + signatureName = "$($vsixFile.BaseName).extension.signature.p7s" + npmVersionString = $packageJson.version + proposedApis = $packageJson.enabledApiProposals + } + } + + # Store the VSIX list as JSON for later steps + Write-Output "##vso[task.setvariable variable=vsixListJson]$($vsixList | ConvertTo-Json -Compress)" + displayName: "\U0001F449 Discover all VSIXs" diff --git a/azure-pipelines/v2/templates/lint.yml b/azure-pipelines/v2/templates/lint.yml new file mode 100644 index 0000000000..c6828585cb --- /dev/null +++ b/azure-pipelines/v2/templates/lint.yml @@ -0,0 +1,7 @@ +steps: + - task: Npm@1 + displayName: "\U0001F449 Lint" + inputs: + command: custom + customCommand: run lint + workingDir: $(working_directory) diff --git a/azure-pipelines/v2/templates/package.yml b/azure-pipelines/v2/templates/package.yml new file mode 100644 index 0000000000..2f56f78a8a --- /dev/null +++ b/azure-pipelines/v2/templates/package.yml @@ -0,0 +1,7 @@ +steps: + - task: Npm@1 + displayName: "\U0001F449 Package" + inputs: + command: custom + customCommand: run package + workingDir: $(working_directory) diff --git a/azure-pipelines/v2/templates/set-release-build-number.yml b/azure-pipelines/v2/templates/set-release-build-number.yml new file mode 100644 index 0000000000..3eeff65432 --- /dev/null +++ b/azure-pipelines/v2/templates/set-release-build-number.yml @@ -0,0 +1,24 @@ +parameters: + # The name of the package being published + - name: packageToPublish + type: string + + # The version to publish + - name: publishVersion + type: string + + # When true, skips the deployment job which actually publishes the package + - name: dryRun + type: boolean + +steps: + - pwsh: | + $newBuildNumber = "$(Build.BuildNumber)-${{ parameters.packageToPublish }}-${{ parameters.publishVersion}}" + + if ('${{ parameters.dryRun }}' -eq 'True') { + Write-Output "Dry run was set to True. Adding 'dry' to the build number." + $newBuildNumber += "-dry" + } + + Write-Host "##vso[build.updatebuildnumber]$newBuildNumber" + displayName: "\U0001F449 Add package name and version to build number" diff --git a/azure-pipelines/v2/templates/setup.yml b/azure-pipelines/v2/templates/setup.yml new file mode 100644 index 0000000000..5d03908b3f --- /dev/null +++ b/azure-pipelines/v2/templates/setup.yml @@ -0,0 +1,13 @@ +steps: + - task: NodeTool@0 + displayName: "\U0001F449 Using Node.js" + inputs: + versionSource: fromFile + versionFilePath: .nvmrc + + - task: Npm@1 + displayName: "\U0001F449 Install Dependencies" + inputs: + command: custom + customCommand: ci --no-optional + workingDir: $(working_directory) diff --git a/azure-pipelines/v2/templates/stage-artifacts.yml b/azure-pipelines/v2/templates/stage-artifacts.yml new file mode 100644 index 0000000000..22a78d2ad9 --- /dev/null +++ b/azure-pipelines/v2/templates/stage-artifacts.yml @@ -0,0 +1,18 @@ +steps: + - task: CopyFiles@2 + displayName: "\U0001F449 Copy packages and VSIXs to staging directory" + inputs: + # Including package.json helps with version and proposed API checks later + # Including extension.manifest and extension.signature.p7s is needed for publishing later + Contents: | + **/*.vsix + **/package.json + **/*extension.manifest + **/*extension.signature.p7s + **/*.tar.gz + **/*.tgz + !**/node_modules/** + SourceFolder: $(working_directory) + TargetFolder: $(Build.ArtifactStagingDirectory)/build/$(artifact_name) + FlattenFolders: false + condition: and(succeeded(), ne(variables['System.PullRequest.IsFork'], 'True')) diff --git a/azure-pipelines/v2/templates/test.yml b/azure-pipelines/v2/templates/test.yml new file mode 100644 index 0000000000..177bfbb005 --- /dev/null +++ b/azure-pipelines/v2/templates/test.yml @@ -0,0 +1,38 @@ +parameters: + # Set to enable tests with Azure federated credentials + - name: testARMServiceConnection + type: string + +steps: + - bash: | + /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & + displayName: "\U0001F449 Start X Virtual Frame Buffer" + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) + + - ${{ if ne(parameters.testARMServiceConnection, '') }}: + - task: AzureCLI@2 + displayName: "\U0001F449 Verify test service connection" + inputs: + azureSubscription: ${{ parameters.testARMServiceConnection }} + scriptType: pscore + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: | + Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_ID]$env:AZURESUBSCRIPTION_SERVICE_CONNECTION_ID" # TODO Note: this gets set by the task, but that behavior may not be intentional, unlike the next two which are documented for addSpnToEnvironment + Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_CLIENT_ID]$env:servicePrincipalId" + Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_TENANT_ID]$env:tenantId" + + - task: Npm@1 + displayName: "\U0001F449 Test" + inputs: + command: custom + customCommand: run test + workingDir: $(working_directory) + env: + DISPLAY: :99 # Only necessary for Linux tests, must match Xvfb display number set above + ${{ if ne(parameters.testARMServiceConnection, '') }}: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + FC_SERVICE_CONNECTION_NAME: ${{ parameters.testARMServiceConnection }} + FC_SERVICE_CONNECTION_ID: $(FC_SERVICE_CONNECTION_ID) + FC_SERVICE_CONNECTION_CLIENT_ID: $(FC_SERVICE_CONNECTION_CLIENT_ID) + FC_SERVICE_CONNECTION_TENANT_ID: $(FC_SERVICE_CONNECTION_TENANT_ID) From 8a0aebab64764a1a34b3c17991e70c705969e342 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 09:44:52 -0500 Subject: [PATCH 02/41] Remove some done TODOs --- azure-pipelines/v2/1es-mb-release-extension.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/azure-pipelines/v2/1es-mb-release-extension.yml b/azure-pipelines/v2/1es-mb-release-extension.yml index 97429b2860..41ab6bc91b 100644 --- a/azure-pipelines/v2/1es-mb-release-extension.yml +++ b/azure-pipelines/v2/1es-mb-release-extension.yml @@ -99,11 +99,9 @@ extends: $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { - # TODO: Need to make sure this is the right argument syntax for multiple proposed APIs $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" } - # TODO: Need to make sure that if an extension was packaged as platform-specific, it doesn't still need to be published with the same platform-specific argument Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" Write-Output " $($commandLine)" From 7fd314767d91a2d2e3840a0088512ca6559896e9 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 09:56:08 -0500 Subject: [PATCH 03/41] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- azure-pipelines/v2/1es-mb-main.yml | 4 ++-- azure-pipelines/v2/1es-mb-release-extension.yml | 2 +- azure-pipelines/v2/1es-mb-release-npm.yml | 2 +- azure-pipelines/v2/templates/find-vsixs.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/azure-pipelines/v2/1es-mb-main.yml b/azure-pipelines/v2/1es-mb-main.yml index 0e9ebc7174..da94add8a3 100644 --- a/azure-pipelines/v2/1es-mb-main.yml +++ b/azure-pipelines/v2/1es-mb-main.yml @@ -55,8 +55,8 @@ resources: repositories: - repository: MicroBuildTemplate type: git - name: MicroBuildTemplates/MicroBuildTemplates - ref: refs/tags/release + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/heads/release extends: ${{ if eq(parameters.isOfficialBuild, true) }}: diff --git a/azure-pipelines/v2/1es-mb-release-extension.yml b/azure-pipelines/v2/1es-mb-release-extension.yml index 41ab6bc91b..cf1c86bc58 100644 --- a/azure-pipelines/v2/1es-mb-release-extension.yml +++ b/azure-pipelines/v2/1es-mb-release-extension.yml @@ -106,7 +106,7 @@ extends: Write-Output " $($commandLine)" # Execute the publish command line - # & $commandLine # TODO: temporarily disabled for testing + # Invoke-Expression $commandLine # TODO: temporarily disabled for testing # if ($LASTEXITCODE -ne 0) { # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" # exit 1 diff --git a/azure-pipelines/v2/1es-mb-release-npm.yml b/azure-pipelines/v2/1es-mb-release-npm.yml index 897c2cade0..3505a551d9 100644 --- a/azure-pipelines/v2/1es-mb-release-npm.yml +++ b/azure-pipelines/v2/1es-mb-release-npm.yml @@ -81,7 +81,7 @@ extends: publishVersion: ${{ parameters.publishVersion }} - pwsh: | - $tarballList = '$(tarballListJson)' | ConvertFrom-Json + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) $tgzFolderName = $tarballList[0].directory $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" diff --git a/azure-pipelines/v2/templates/find-vsixs.yml b/azure-pipelines/v2/templates/find-vsixs.yml index e17c6d5d02..203954b867 100644 --- a/azure-pipelines/v2/templates/find-vsixs.yml +++ b/azure-pipelines/v2/templates/find-vsixs.yml @@ -46,5 +46,5 @@ steps: } # Store the VSIX list as JSON for later steps - Write-Output "##vso[task.setvariable variable=vsixListJson]$($vsixList | ConvertTo-Json -Compress)" + Write-Output "##vso[task.setvariable variable=vsixListJson]$($vsixList | ConvertTo-Json -Compress -AsArray)" displayName: "\U0001F449 Discover all VSIXs" From 2df5f81c9bc616081e53500da83e468f548b3b3a Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 09:57:30 -0500 Subject: [PATCH 04/41] Copilot feedback --- azure-pipelines/v2/templates/find-tarballs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/v2/templates/find-tarballs.yml b/azure-pipelines/v2/templates/find-tarballs.yml index 73c5980ac0..27e9717d95 100644 --- a/azure-pipelines/v2/templates/find-tarballs.yml +++ b/azure-pipelines/v2/templates/find-tarballs.yml @@ -46,5 +46,5 @@ steps: } # Store the tarball list as JSON for later steps - Write-Output "##vso[task.setvariable variable=tarballListJson]$($tarballList | ConvertTo-Json -Compress)" + Write-Output "##vso[task.setvariable variable=tarballListJson]$($tarballList | ConvertTo-Json -Compress -AsArray)" displayName: "\U0001F449 Discover all tarballs" From ad3874debca8c7c1ac1ec20252424845641ba783 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 09:59:33 -0500 Subject: [PATCH 05/41] Consistency with other pipeline --- azure-pipelines/v2/1es-mb-release-extension.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/v2/1es-mb-release-extension.yml b/azure-pipelines/v2/1es-mb-release-extension.yml index cf1c86bc58..c2500ca5ac 100644 --- a/azure-pipelines/v2/1es-mb-release-extension.yml +++ b/azure-pipelines/v2/1es-mb-release-extension.yml @@ -91,7 +91,7 @@ extends: scriptType: pscore scriptLocation: inlineScript inlineScript: | - $vsixList = '$(vsixListJson)' | ConvertFrom-Json + $vsixList = @('$(vsixListJson)' | ConvertFrom-Json) # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well foreach ($vsix in $vsixList) { From de7303fbae863f6d80b9315e5475c2e1146e9bc1 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:02:34 -0500 Subject: [PATCH 06/41] Note --- azure-pipelines/v2/templates/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/v2/templates/test.yml b/azure-pipelines/v2/templates/test.yml index 177bfbb005..bb097177bb 100644 --- a/azure-pipelines/v2/templates/test.yml +++ b/azure-pipelines/v2/templates/test.yml @@ -18,7 +18,7 @@ steps: scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | - Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_ID]$env:AZURESUBSCRIPTION_SERVICE_CONNECTION_ID" # TODO Note: this gets set by the task, but that behavior may not be intentional, unlike the next two which are documented for addSpnToEnvironment + Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_ID]$env:AZURESUBSCRIPTION_SERVICE_CONNECTION_ID" # Note: this gets set by the task, but that behavior may not be intentional, unlike the next two which are documented for addSpnToEnvironment. However, I asked the dev and was told it was safe to use. Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_TENANT_ID]$env:tenantId" From 38aea3b02544f2d38043f2348593d267afc684af Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:30:36 -0500 Subject: [PATCH 07/41] Add npm authenticate --- azure-pipelines/v2/templates/setup.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/azure-pipelines/v2/templates/setup.yml b/azure-pipelines/v2/templates/setup.yml index 5d03908b3f..1e887727d1 100644 --- a/azure-pipelines/v2/templates/setup.yml +++ b/azure-pipelines/v2/templates/setup.yml @@ -3,7 +3,21 @@ steps: displayName: "\U0001F449 Using Node.js" inputs: versionSource: fromFile - versionFilePath: .nvmrc + versionFilePath: $(working_directory)/.nvmrc + + - pwsh: | + if (Test-Path "$(working_directory)/.npmrc") { + Write-Host "##vso[task.setvariable variable=npmrcExists]true" + } else { + Write-Host "##vso[task.setvariable variable=npmrcExists]false" + } + displayName: "\U0001F449 Check for .npmrc" + + - task: npmAuthenticate@0 + displayName: "\U0001F449 Authenticate npm" + condition: and(succeeded(), eq(variables['npmrcExists'], 'true')) + inputs: + workingFile: $(working_directory)/.npmrc - task: Npm@1 displayName: "\U0001F449 Install Dependencies" From 07b660d17ac3dc35dd3624a327d1f4450ff657cd Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:32:34 -0500 Subject: [PATCH 08/41] Minor edits --- azure-pipelines/v2/templates/setup.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azure-pipelines/v2/templates/setup.yml b/azure-pipelines/v2/templates/setup.yml index 1e887727d1..138bfb077e 100644 --- a/azure-pipelines/v2/templates/setup.yml +++ b/azure-pipelines/v2/templates/setup.yml @@ -7,14 +7,14 @@ steps: - pwsh: | if (Test-Path "$(working_directory)/.npmrc") { - Write-Host "##vso[task.setvariable variable=npmrcExists]true" + Write-Output "##vso[task.setvariable variable=npmrcExists]true" } else { - Write-Host "##vso[task.setvariable variable=npmrcExists]false" + Write-Output "##vso[task.setvariable variable=npmrcExists]false" } displayName: "\U0001F449 Check for .npmrc" - task: npmAuthenticate@0 - displayName: "\U0001F449 Authenticate npm" + displayName: "\U0001F449 Authenticate NPM" condition: and(succeeded(), eq(variables['npmrcExists'], 'true')) inputs: workingFile: $(working_directory)/.npmrc From 9b6ffd25fbea14bf1404f3c0e22d1e54bf84a4db Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:48:27 -0500 Subject: [PATCH 09/41] Other subfolder --- {azure-pipelines/v2 => azdo-pipelines}/1es-mb-main.yml | 0 .../v2 => azdo-pipelines}/1es-mb-release-extension.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/1es-mb-release-npm.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/azcode.variables.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/stages/1es-stages.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/1es-mb-sign.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/build.yml | 0 .../v2 => azdo-pipelines}/templates/find-tarballs.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/find-vsixs.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/lint.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/package.yml | 0 .../v2 => azdo-pipelines}/templates/set-release-build-number.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/setup.yml | 0 .../v2 => azdo-pipelines}/templates/stage-artifacts.yml | 0 {azure-pipelines/v2 => azdo-pipelines}/templates/test.yml | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename {azure-pipelines/v2 => azdo-pipelines}/1es-mb-main.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/1es-mb-release-extension.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/1es-mb-release-npm.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/azcode.variables.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/stages/1es-stages.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/1es-mb-sign.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/build.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/find-tarballs.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/find-vsixs.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/lint.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/package.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/set-release-build-number.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/setup.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/stage-artifacts.yml (100%) rename {azure-pipelines/v2 => azdo-pipelines}/templates/test.yml (100%) diff --git a/azure-pipelines/v2/1es-mb-main.yml b/azdo-pipelines/1es-mb-main.yml similarity index 100% rename from azure-pipelines/v2/1es-mb-main.yml rename to azdo-pipelines/1es-mb-main.yml diff --git a/azure-pipelines/v2/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml similarity index 100% rename from azure-pipelines/v2/1es-mb-release-extension.yml rename to azdo-pipelines/1es-mb-release-extension.yml diff --git a/azure-pipelines/v2/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml similarity index 100% rename from azure-pipelines/v2/1es-mb-release-npm.yml rename to azdo-pipelines/1es-mb-release-npm.yml diff --git a/azure-pipelines/v2/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml similarity index 100% rename from azure-pipelines/v2/azcode.variables.yml rename to azdo-pipelines/azcode.variables.yml diff --git a/azure-pipelines/v2/stages/1es-stages.yml b/azdo-pipelines/stages/1es-stages.yml similarity index 100% rename from azure-pipelines/v2/stages/1es-stages.yml rename to azdo-pipelines/stages/1es-stages.yml diff --git a/azure-pipelines/v2/templates/1es-mb-sign.yml b/azdo-pipelines/templates/1es-mb-sign.yml similarity index 100% rename from azure-pipelines/v2/templates/1es-mb-sign.yml rename to azdo-pipelines/templates/1es-mb-sign.yml diff --git a/azure-pipelines/v2/templates/build.yml b/azdo-pipelines/templates/build.yml similarity index 100% rename from azure-pipelines/v2/templates/build.yml rename to azdo-pipelines/templates/build.yml diff --git a/azure-pipelines/v2/templates/find-tarballs.yml b/azdo-pipelines/templates/find-tarballs.yml similarity index 100% rename from azure-pipelines/v2/templates/find-tarballs.yml rename to azdo-pipelines/templates/find-tarballs.yml diff --git a/azure-pipelines/v2/templates/find-vsixs.yml b/azdo-pipelines/templates/find-vsixs.yml similarity index 100% rename from azure-pipelines/v2/templates/find-vsixs.yml rename to azdo-pipelines/templates/find-vsixs.yml diff --git a/azure-pipelines/v2/templates/lint.yml b/azdo-pipelines/templates/lint.yml similarity index 100% rename from azure-pipelines/v2/templates/lint.yml rename to azdo-pipelines/templates/lint.yml diff --git a/azure-pipelines/v2/templates/package.yml b/azdo-pipelines/templates/package.yml similarity index 100% rename from azure-pipelines/v2/templates/package.yml rename to azdo-pipelines/templates/package.yml diff --git a/azure-pipelines/v2/templates/set-release-build-number.yml b/azdo-pipelines/templates/set-release-build-number.yml similarity index 100% rename from azure-pipelines/v2/templates/set-release-build-number.yml rename to azdo-pipelines/templates/set-release-build-number.yml diff --git a/azure-pipelines/v2/templates/setup.yml b/azdo-pipelines/templates/setup.yml similarity index 100% rename from azure-pipelines/v2/templates/setup.yml rename to azdo-pipelines/templates/setup.yml diff --git a/azure-pipelines/v2/templates/stage-artifacts.yml b/azdo-pipelines/templates/stage-artifacts.yml similarity index 100% rename from azure-pipelines/v2/templates/stage-artifacts.yml rename to azdo-pipelines/templates/stage-artifacts.yml diff --git a/azure-pipelines/v2/templates/test.yml b/azdo-pipelines/templates/test.yml similarity index 100% rename from azure-pipelines/v2/templates/test.yml rename to azdo-pipelines/templates/test.yml From f47fc669ef680cbc0a6b39e6afe075582ebfb878 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:14:54 -0500 Subject: [PATCH 10/41] Add readme --- azdo-pipelines/README.md | 151 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 azdo-pipelines/README.md diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md new file mode 100644 index 0000000000..37ca68e8b5 --- /dev/null +++ b/azdo-pipelines/README.md @@ -0,0 +1,151 @@ +# AzDO Pipeline Templates (v2) + +This folder contains reusable Azure DevOps pipeline templates for building, testing, signing, and releasing VS Code extensions and NPM packages. These templates are designed to be used with the [1ES MicroBuild pipeline templates](http://aka.ms/1espt). + +## Main Templates + +There are three main templates available: + +| Template | Purpose | +| ------------------------------ | ---------------------------------------------- | +| `1es-mb-main.yml` | Build, test, and sign extensions/packages | +| `1es-mb-release-extension.yml` | Release a VS Code extension to the Marketplace | +| `1es-mb-release-npm.yml` | Release an NPM package via ESRP | + +## Prerequisites + +Your project must meet the following requirements to use these templates: + +1. An `.nvmrc` file at the root (or working directory) specifying the Node.js version +1. Optionally, an `.npmrc` file at the root (or working directory) for authenticating NPM +1. A `package.json` file with the following NPM scripts (if a script needs to skip, simply use a blank value or `"exit 0"` as the script): + - `lint` - Lints the code (typically using ESLint) + - `build` - Builds the code (for VS Code extensions, this should include bundling via webpack/esbuild) + - `package` - Packages the built code (e.g., into a `.vsix` or `.tgz`). Runs after `build`. + - `test` - Runs tests. Runs after `build` and `package`. +1. After the `package` script has run, the output must match the required build artifacts (see corresponding release pipeline) +1. (For compliance) A `tsaoptions.json` file in `.config` (see [Compliance Configuration](#compliance-configuration)) + +## Build Pipeline (`1es-mb-main.yml`) + +This template handles building, linting, testing, packaging, and signing your code. + +### Parameters + +| Parameter | Type | Default | Description | +| --------------------------- | -------- | -------------------------------------- | -------------------------------------------------------- | +| `isOfficialBuild` | boolean | `true` | Set to `true` for official builds, `false` for PRs | +| `jobs` | object | `[{ name: Root, working_directory: . }]` | Jobs to run; use to parallelize builds in subdirectories | +| `sdlPool` | object | Windows MicroBuild pool | Pool for SDL/compliance stage | +| `buildPool` | object | Linux Ubuntu 22.04 | Pool for build stage | +| `signType` | string | `real` | `real`, `test`, or `none` for MicroBuild signing | +| `alternativeSigningSteps` | stepList | `[]` | Custom signing steps (disables MicroBuild signing) | +| `additionalSetupSteps` | stepList | `[]` | Extra steps to run during setup | +| `testARMServiceConnection` | string | `""` | ARM service connection for federated credential tests | + +### Example + +```yaml +# TODO: Paste your example here +``` + +## Extension Release Pipeline (`1es-mb-release-extension.yml`) + +This template releases a signed VS Code extension to the Visual Studio Marketplace. + +### Parameters + +| Parameter | Type | Default | Description | +| ---------------------------------- | ------- | ------------ | -------------------------------------------------- | +| `packageToPublish` | string | *required* | Regex pattern to match the `.vsix` file | +| `publishVersion` | string | *required* | Expected version (verified against `package.json`) | +| `dryRun` | boolean | `false` | Skip the actual publish step | +| `artifactName` | string | `Build Root` | Name of the artifact containing the package | +| `extensionReleaseServiceConnection`| string | *required* | Service connection for VSCE authentication | +| `releaseApprovalEnvironment` | string | `""` | AzDO environment for release approval | +| `releasePool` | object | Windows MicroBuild pool | Pool for the release job | + +### Required Build Artifacts + +The build pipeline must produce the following artifacts for extension release: + +1. `*.vsix` - The packaged extension +1. `package.json` - Used to verify extension name and version +1. `extension.manifest` - Generated with `vsce generate-manifest` +1. `extension.signature.p7s` - The signed manifest + +### Example + +```yaml +# TODO: Paste your example here +``` + +## NPM Release Pipeline (`1es-mb-release-npm.yml`) + +This template releases an NPM package via ESRP. + +### Parameters + +| Parameter | Type | Default | Description | +| ---------------------------- | ------- | --------------------- | -------------------------------------------------- | +| `packageToPublish` | string | *required* | Regex pattern to match the `.tgz` file | +| `publishVersion` | string | *required* | Expected version (verified against `package.json`) | +| `dryRun` | boolean | `false` | Skip the actual publish step | +| `artifactName` | string | `Build Root` | Name of the artifact containing the package | +| `ownerAliases` | string | *required* | Owner aliases for ESRP | +| `approverAliases` | string | *required* | Approver aliases for ESRP | +| `releasePool` | object | Windows MicroBuild pool | Pool for the release job | +| `gitHubServiceConnection` | string | `""` | Service connection for creating GitHub releases | +| `releaseApprovalEnvironment` | string | `""` | AzDO environment for release approval | + +### Required Build Artifacts + +The build pipeline must produce the following artifacts for extension release: + +1. `*.tgz` - The packaged NPM package +1. `package.json` - Used to verify extension name and version + +### Example + +```yaml +# TODO: Paste your example here +``` + +## Compliance Configuration + +Create a `tsaoptions.json` file in `.config` for [TSA (Trust Services Automation)](http://aka.ms/tsa): + +```json +{ + "tsaVersion": "TsaV2", + "codeBase": "NewOrUpdate", + "codeBaseName": "your-extension-name", + "tsaStamp": "DevDiv", + "notificationAliases": [ + "your-team@microsoft.com" + ], + "codebaseAdmins": [ + "REDMOND\\your-security-group" + ], + "instanceUrl": "https://devdiv.visualstudio.com", + "projectName": "DevDiv", + "areaPath": "DevDiv\\Your Area Path", + "iterationPath": "DevDiv", + "allTools": true +} +``` + +## Multi-Package Builds + +To build multiple packages in parallel (e.g., in a monorepo), use the `jobs` parameter: + +```yaml +parameters: + jobs: + - name: Extension + working_directory: ./extension + - name: SDK + working_directory: ./sdk +``` + +Each job will produce a separate artifact named `Build `. From 4621974a76f0509101bf387c5bd83a8b4e9e7151 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:48:28 -0500 Subject: [PATCH 11/41] Add release instructions --- azdo-pipelines/README.md | 16 ++++++++-------- azdo-pipelines/RELEASING.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 azdo-pipelines/RELEASING.md diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index 37ca68e8b5..f6509b95f9 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -17,14 +17,14 @@ There are three main templates available: Your project must meet the following requirements to use these templates: 1. An `.nvmrc` file at the root (or working directory) specifying the Node.js version -1. Optionally, an `.npmrc` file at the root (or working directory) for authenticating NPM -1. A `package.json` file with the following NPM scripts (if a script needs to skip, simply use a blank value or `"exit 0"` as the script): +2. Optionally, an `.npmrc` file at the root (or working directory) for authenticating NPM +3. A `package.json` file with the following NPM scripts (if a script needs to skip, simply use a blank value or `"exit 0"` as the script): - `lint` - Lints the code (typically using ESLint) - `build` - Builds the code (for VS Code extensions, this should include bundling via webpack/esbuild) - `package` - Packages the built code (e.g., into a `.vsix` or `.tgz`). Runs after `build`. - `test` - Runs tests. Runs after `build` and `package`. -1. After the `package` script has run, the output must match the required build artifacts (see corresponding release pipeline) -1. (For compliance) A `tsaoptions.json` file in `.config` (see [Compliance Configuration](#compliance-configuration)) +4. After the `package` script has run, the output must match the required build artifacts (see corresponding release pipeline) +5. (For compliance) A `tsaoptions.json` file in `.config` (see [Compliance Configuration](#compliance-configuration)) ## Build Pipeline (`1es-mb-main.yml`) @@ -70,9 +70,9 @@ This template releases a signed VS Code extension to the Visual Studio Marketpla The build pipeline must produce the following artifacts for extension release: 1. `*.vsix` - The packaged extension -1. `package.json` - Used to verify extension name and version -1. `extension.manifest` - Generated with `vsce generate-manifest` -1. `extension.signature.p7s` - The signed manifest +2. `package.json` - Used to verify extension name and version +3. `extension.manifest` - Generated with `vsce generate-manifest` +4. `extension.signature.p7s` - The signed manifest ### Example @@ -103,7 +103,7 @@ This template releases an NPM package via ESRP. The build pipeline must produce the following artifacts for extension release: 1. `*.tgz` - The packaged NPM package -1. `package.json` - Used to verify extension name and version +2. `package.json` - Used to verify extension name and version ### Example diff --git a/azdo-pipelines/RELEASING.md b/azdo-pipelines/RELEASING.md new file mode 100644 index 0000000000..981653abfd --- /dev/null +++ b/azdo-pipelines/RELEASING.md @@ -0,0 +1,29 @@ +# Releasing New Pipeline Templates + +Because consumers of these pipeline templates typically do not reference `main` directly, changes merged into `main` are not automatically deployed to consumers. We use Git tags for this, for example `azext-pt/v1`. + +If at all possible, avoid breaking changes. + +The steps for releasing are as follows: + +1. Elevate to repository administrator [here](https://repos.opensource.microsoft.com/orgs/microsoft/repos/vscode-azuretools/jit/grant). This is required due to tag protection rules. +2. Run the appropriate script: + - For non-breaking changes, delete and recreate the existing Git tag: + + ```bash + git fetch origin main + git push origin --delete azext-pt/v1 + git tag -d azext-pt/v1 + git tag azext-pt/v1 origin/main + git push origin azext-pt/v1 + ``` + + - For breaking changes, a new tag needs to be established with a new version: + + ```bash + git fetch origin main + git tag azext-pt/v2 origin/main + git push origin azext-pt/v2 + ``` + + Then, consumers will need to be updated accordingly. From 87b0e5eb2fca429de272ba57253dcac2318ffb0d Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:01:03 -0500 Subject: [PATCH 12/41] Pipeline for it --- .../workflows/release-pipeline-templates.yml | 43 +++++++++++++++++++ azdo-pipelines/RELEASING.md | 26 +++-------- 2 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/release-pipeline-templates.yml diff --git a/.github/workflows/release-pipeline-templates.yml b/.github/workflows/release-pipeline-templates.yml new file mode 100644 index 0000000000..a50993ded9 --- /dev/null +++ b/.github/workflows/release-pipeline-templates.yml @@ -0,0 +1,43 @@ +name: Release Pipeline Templates + +on: + workflow_dispatch: + inputs: + tag: + description: "Tag to update or create (e.g., azext-pt/v1)" + required: true + default: "azext-pt/v1" + +jobs: + update-tag: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Validate tag format + run: | + if [[ ! "${{ inputs.tag }}" =~ ^azext-pt/v[0-9]+$ ]]; then + echo "::error::Tag must match pattern azext-pt/vN (e.g., azext-pt/v1)" + exit 1 + fi + + - name: Delete existing tag (if exists) + run: | + git push origin --delete ${{ inputs.tag }} 2>/dev/null || echo "Tag does not exist remotely, will create new" + git tag -d ${{ inputs.tag }} 2>/dev/null || true + + - name: Create and push tag + run: | + git tag ${{ inputs.tag }} origin/main + git push origin ${{ inputs.tag }} + + - name: Summary + run: | + echo "## ✅ Tag Released" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Tag:** \`${{ inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY + echo "**Commit:** \`$(git rev-parse origin/main)\`" >> $GITHUB_STEP_SUMMARY diff --git a/azdo-pipelines/RELEASING.md b/azdo-pipelines/RELEASING.md index 981653abfd..f9241e60d2 100644 --- a/azdo-pipelines/RELEASING.md +++ b/azdo-pipelines/RELEASING.md @@ -4,26 +4,12 @@ Because consumers of these pipeline templates typically do not reference `main` If at all possible, avoid breaking changes. -The steps for releasing are as follows: +## Releasing -1. Elevate to repository administrator [here](https://repos.opensource.microsoft.com/orgs/microsoft/repos/vscode-azuretools/jit/grant). This is required due to tag protection rules. -2. Run the appropriate script: - - For non-breaking changes, delete and recreate the existing Git tag: +Use the [Release Pipeline Templates](https://github.com/microsoft/vscode-azuretools/actions/workflows/release-pipeline-templates.yml) workflow to update or create tags. - ```bash - git fetch origin main - git push origin --delete azext-pt/v1 - git tag -d azext-pt/v1 - git tag azext-pt/v1 origin/main - git push origin azext-pt/v1 - ``` +1. Go to the workflow and click "Run workflow" +2. Enter the tag name (e.g., `azext-pt/v1` for updates, `azext-pt/v2` to create a new tag for breaking changes) +3. Click "Run workflow" - - For breaking changes, a new tag needs to be established with a new version: - - ```bash - git fetch origin main - git tag azext-pt/v2 origin/main - git push origin azext-pt/v2 - ``` - - Then, consumers will need to be updated accordingly. +The workflow automatically handles both new and existing tags. It's protected by a GitHub ruleset—only the workflow can modify `azext-pt/*` tags. From 3ac7c0054be512333df18051c1162c28f3a3bdb1 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:36:29 -0500 Subject: [PATCH 13/41] Branches instead of tags --- .../workflows/release-pipeline-templates.yml | 107 +++++++++++++----- azdo-pipelines/RELEASING.md | 11 +- 2 files changed, 84 insertions(+), 34 deletions(-) diff --git a/.github/workflows/release-pipeline-templates.yml b/.github/workflows/release-pipeline-templates.yml index a50993ded9..73a4d05285 100644 --- a/.github/workflows/release-pipeline-templates.yml +++ b/.github/workflows/release-pipeline-templates.yml @@ -3,41 +3,90 @@ name: Release Pipeline Templates on: workflow_dispatch: inputs: - tag: - description: "Tag to update or create (e.g., azext-pt/v1)" + branch: + description: "Branch to update (e.g., azext-pt/v1)" required: true default: "azext-pt/v1" jobs: - update-tag: + create-pr: runs-on: ubuntu-latest permissions: contents: write + pull-requests: write steps: - - uses: actions/checkout@v4 + - uses: actions/github-script@v7 with: - fetch-depth: 0 - - - name: Validate tag format - run: | - if [[ ! "${{ inputs.tag }}" =~ ^azext-pt/v[0-9]+$ ]]; then - echo "::error::Tag must match pattern azext-pt/vN (e.g., azext-pt/v1)" - exit 1 - fi - - - name: Delete existing tag (if exists) - run: | - git push origin --delete ${{ inputs.tag }} 2>/dev/null || echo "Tag does not exist remotely, will create new" - git tag -d ${{ inputs.tag }} 2>/dev/null || true - - - name: Create and push tag - run: | - git tag ${{ inputs.tag }} origin/main - git push origin ${{ inputs.tag }} - - - name: Summary - run: | - echo "## ✅ Tag Released" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Tag:** \`${{ inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY - echo "**Commit:** \`$(git rev-parse origin/main)\`" >> $GITHUB_STEP_SUMMARY + script: | + const branch = '${{ inputs.branch }}'; + + // Validate branch format + if (!/^azext-pt\/v\d+$/.test(branch)) { + core.setFailed(`Branch must match pattern azext-pt/vN (e.g., azext-pt/v1)`); + return; + } + + // Get main branch SHA + const { data: mainRef } = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'heads/main' + }); + const mainSha = mainRef.object.sha; + + // Check if release branch exists + let branchExists = true; + let branchSha = null; + try { + const { data: branchRef } = await github.rest.git.getRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `heads/${branch}` + }); + branchSha = branchRef.object.sha; + } catch (e) { + if (e.status === 404) { + branchExists = false; + } else { + throw e; + } + } + + // Create branch if it doesn't exist + if (!branchExists) { + await github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: `refs/heads/${branch}`, + sha: mainSha + }); + core.summary.addHeading('✅ Branch Created', 2); + core.summary.addRaw(`**Branch:** \`${branch}\`\n\n`); + core.summary.addRaw(`**Commit:** \`${mainSha}\`\n`); + await core.summary.write(); + return; + } + + // Check if already up to date + if (mainSha === branchSha) { + core.notice(`Branch ${branch} is already up to date with main`); + core.summary.addHeading('ℹ️ No Changes', 2); + core.summary.addRaw(`Branch \`${branch}\` is already at the same commit as \`main\`.\n`); + await core.summary.write(); + return; + } + + // Create PR + const { data: pr } = await github.rest.pulls.create({ + owner: context.repo.owner, + repo: context.repo.repo, + head: 'main', + base: branch, + title: `Release pipeline templates to ${branch}`, + body: `Updates \`${branch}\` to match \`main\`.\n\n**Current ${branch}:** \`${branchSha}\`\n**New (from main):** \`${mainSha}\`\n\nTriggered by @${{ github.actor }} via workflow dispatch.` + }); + + core.summary.addHeading('✅ PR Created', 2); + core.summary.addRaw(`**PR:** ${pr.html_url}\n\n`); + core.summary.addRaw(`**Target Branch:** \`${branch}\`\n`); + await core.summary.write(); diff --git a/azdo-pipelines/RELEASING.md b/azdo-pipelines/RELEASING.md index f9241e60d2..18f460dadf 100644 --- a/azdo-pipelines/RELEASING.md +++ b/azdo-pipelines/RELEASING.md @@ -1,15 +1,16 @@ # Releasing New Pipeline Templates -Because consumers of these pipeline templates typically do not reference `main` directly, changes merged into `main` are not automatically deployed to consumers. We use Git tags for this, for example `azext-pt/v1`. +Because consumers of these pipeline templates typically do not reference `main` directly, changes merged into `main` are not automatically deployed to consumers. We use release branches for this, for example `azext-pt/v1`. -If at all possible, avoid breaking changes. +If at all possible, avoid breaking changes. If breaking changes are necessary, it is strongly suggested to add a step to the prior version that shows a warning to consumers that the version is deprecated and should be updated as soon as possible. ## Releasing -Use the [Release Pipeline Templates](https://github.com/microsoft/vscode-azuretools/actions/workflows/release-pipeline-templates.yml) workflow to update or create tags. +Use the [Release Pipeline Templates](https://github.com/microsoft/vscode-azuretools/actions/workflows/release-pipeline-templates.yml) workflow to update or create release branches. 1. Go to the workflow and click "Run workflow" -2. Enter the tag name (e.g., `azext-pt/v1` for updates, `azext-pt/v2` to create a new tag for breaking changes) +2. Enter the branch name (e.g., `azext-pt/v1` for updates, `azext-pt/v2` to create a new branch for breaking changes) 3. Click "Run workflow" +4. If updating an existing branch, a PR will be created--review and merge it -The workflow automatically handles both new and existing tags. It's protected by a GitHub ruleset—only the workflow can modify `azext-pt/*` tags. +The release branches are protected by branch protection rules, requiring a PR to update them. From 8b7a321dde763f20cc8e5f59c7ee85be2b78de45 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:36:03 -0500 Subject: [PATCH 14/41] Add examples to readme --- azdo-pipelines/README.md | 128 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index f6509b95f9..6d51510f76 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -46,7 +46,40 @@ This template handles building, linting, testing, packaging, and signing your co ### Example ```yaml -# TODO: Paste your example here +# Trigger the build whenever `main` or `rel/*` is updated +trigger: + - main + - rel/* + +# Disable PR trigger +pr: none + +# Scheduled nightly build of `main` +schedules: + - cron: "0 0 * * *" + displayName: Nightly scheduled build + always: false # Don't rebuild if there haven't been changes + branches: + include: + - main + +resources: + repositories: + # Use the shared templates from microsoft/vscode-azuretools + - repository: azExtTemplates + type: github + name: microsoft/vscode-azuretools + ref: azext-pt/v1 + endpoint: GitHub-AzureTools # The service connection to use when accessing this repository + +variables: + # Pick up shared AZCode variables + - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + +extends: + template: azdo-pipelines/1es-mb-main.yml@azExtTemplates # Use the main build template + parameters: + testARMServiceConnection: ${{ variables.testARMServiceConnection }} ``` ## Extension Release Pipeline (`1es-mb-release-extension.yml`) @@ -77,7 +110,46 @@ The build pipeline must produce the following artifacts for extension release: ### Example ```yaml -# TODO: Paste your example here +# Only run this pipeline when manually triggered +trigger: none +pr: none + +parameters: + # The version to publish--used for ensuring the expected version is published + - name: publishVersion + displayName: Version to publish + type: string + # Whether to do a dry run (i.e., not actually publish) + - name: dryRun + displayName: Dry run + type: boolean + default: false + +resources: + pipelines: + # Reference the build pipeline to get the artifacts + - pipeline: build # This must be "build" + source: \Azure Tools\VSCode\Extensions\vscode-containers # Name of the pipeline that produces the artifacts + repositories: + # Use the shared templates from microsoft/vscode-azuretools + - repository: azExtTemplates + type: github + name: microsoft/vscode-azuretools + ref: azext-pt/v1 + endpoint: GitHub-AzureTools # The service connection to use when accessing this repository + +variables: + # Pick up shared AZCode variables + - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + +extends: + template: azdo-pipelines/1es-mb-release-extension.yml@azExtTemplates # Use the extension release template + parameters: + packageToPublish: vscode-containers + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + releaseServiceConnection: ${{ variables.extensionReleaseServiceConnection }} + releaseApprovalEnvironment: ${{ variables.extensionReleaseApprovalEnvironment }} ``` ## NPM Release Pipeline (`1es-mb-release-npm.yml`) @@ -108,7 +180,57 @@ The build pipeline must produce the following artifacts for extension release: ### Example ```yaml -# TODO: Paste your example here +# Only run this pipeline when manually triggered +trigger: none +pr: none + +parameters: + # Choose a package to publish at the time of job creation + - name: packageToPublish + displayName: Package to publish + type: string + values: + - microsoft-vscode-processutils + - microsoft-vscode-container-client + - microsoft-vscode-docker-registries + - microsoft-vscode-inproc-mcp + # The version to publish--used for ensuring the expected version is published + - name: publishVersion + displayName: Version to publish + type: string + # Whether to do a dry run (i.e., not actually publish) + - name: dryRun + displayName: Dry run + type: boolean + default: false + +resources: + pipelines: + # Reference the build pipeline to get the artifacts + - pipeline: build # This must be "build" + source: \Azure Tools\VSCode\Packages\vscode-docker-extensibility # Name of the pipeline that produces the artifacts + repositories: + # Use the shared templates from microsoft/vscode-azuretools + - repository: azExtTemplates + type: github + name: microsoft/vscode-azuretools + ref: azext-pt/v1 + endpoint: GitHub-AzureTools # The service connection to use when accessing this repository + +variables: + # Pick up shared AZCode variables + - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + +extends: + template: azdo-pipelines/1es-mb-release-npm.yml@azExtTemplates # Use the NPM release template + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + ownerAliases: ${{ variables.npmReleaseOwnerAliases }} + approverAliases: ${{ variables.npmReleaseApproverAliases }} + gitHubServiceConnection: ${{ variables.gitHubServiceConnection }} + releaseApprovalEnvironment: ${{ variables.npmReleaseApprovalEnvironment }} ``` ## Compliance Configuration From e0b382e773d8e4c4ca91cd5ec09eb9dfbbdea8b9 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:36:09 -0500 Subject: [PATCH 15/41] Renames of a few things --- azdo-pipelines/1es-mb-release-extension.yml | 4 ++-- azdo-pipelines/azcode.variables.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index c2500ca5ac..5873969a7f 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -20,7 +20,7 @@ parameters: default: Build Root # The service connection that VSCE will use to publish the extension - - name: extensionReleaseServiceConnection + - name: releaseServiceConnection type: string # Set to the AzDO environment used for enforcing approval before the release runs @@ -87,7 +87,7 @@ extends: - task: AzureCLI@2 displayName: "\U0001F449 Publish VSIXs to Marketplace" inputs: - azureSubscription: ${{ parameters.extensionReleaseServiceConnection }} + azureSubscription: ${{ parameters.releaseServiceConnection }} scriptType: pscore scriptLocation: inlineScript inlineScript: | diff --git a/azdo-pipelines/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml index d66c950114..97c9c7bab9 100644 --- a/azdo-pipelines/azcode.variables.yml +++ b/azdo-pipelines/azcode.variables.yml @@ -10,9 +10,9 @@ variables: value: GitHub-AzureTools - name: npmReleaseApprovalEnvironment value: AzCodeDeploy - - name: npmReleaseOwnerAlias + - name: npmReleaseOwnerAliases value: azcode - - name: npmReleaseApproverAlias + - name: npmReleaseApproverAliases value: jinglou # Test From 8090ffbab353eb9c6db11d5452fc76c01418ce35 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:39:33 -0500 Subject: [PATCH 16/41] Add note about signing on NPM packages --- azdo-pipelines/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index 6d51510f76..46b2c8f755 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -80,6 +80,7 @@ extends: template: azdo-pipelines/1es-mb-main.yml@azExtTemplates # Use the main build template parameters: testARMServiceConnection: ${{ variables.testARMServiceConnection }} + # signType: none # For NPM packages, disable signing ``` ## Extension Release Pipeline (`1es-mb-release-extension.yml`) From ae9655138c2b78e125508a55bf431df3e4a26561 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 11:49:41 -0500 Subject: [PATCH 17/41] Add defaults --- azdo-pipelines/stages/1es-stages.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/azdo-pipelines/stages/1es-stages.yml b/azdo-pipelines/stages/1es-stages.yml index 15e340ad14..4140903cbf 100644 --- a/azdo-pipelines/stages/1es-stages.yml +++ b/azdo-pipelines/stages/1es-stages.yml @@ -2,10 +2,17 @@ parameters: # The jobs to run. Use to parallelize building in subdirectories - name: jobs type: object + default: + - name: Root + working_directory: . # The pool to use for the build stage - name: buildPool type: object + default: + name: AzurePipelines-EO + image: 1ESPT-Ubuntu22.04 + os: linux # Set to 'real' or 'test' to enable MicroBuild signing - name: signType @@ -14,18 +21,22 @@ parameters: - real - test - none + default: real # Supply to disable MicroBuild signing steps and use these instead - name: alternativeSigningSteps type: stepList + default: [] # Additional steps to run during setup (e.g. npm authenticate etc.) - name: additionalSetupSteps type: stepList + default: [] # Set to enable tests with Azure federated credentials - name: testARMServiceConnection type: string + default: "" stages: - stage: BuildStage From ea4c554e3f49e8815af6b344359cf6cee229a8d0 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:04:11 -0500 Subject: [PATCH 18/41] Add migration doc --- azdo-pipelines/MIGRATION.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 azdo-pipelines/MIGRATION.md diff --git a/azdo-pipelines/MIGRATION.md b/azdo-pipelines/MIGRATION.md new file mode 100644 index 0000000000..2d73bad73d --- /dev/null +++ b/azdo-pipelines/MIGRATION.md @@ -0,0 +1,10 @@ +# Migrating from v1 Pipeline Templates + +Migration to the new templates is very easy. + +1. Move your build and release pipelines from `.azure-pipelines` to `.config`. Also move `tsaoptions.json`. +2. Delete the deprecated `.azure-pipelines/compliance/CredScanSuppressions.json`, `.azure-pipelines/compliance/PoliCheckExclusions.xml`, and `.azure-pipelines/SignExtension.signproj`. +3. Rewrite your build pipeline as needed, following the examples in the [README](./README.md#example). +4. Rewrite your release pipeline as needed, following the examples in the README for [extensions](./README.md#example-1) or [npm](./README.md#example-2). +5. Ensure your `.vscodeignore` or `.npmignore` is ignoring the new `.config` folder. +6. In Azure DevOps, update your [pipelines](https://devdiv.visualstudio.com/DevDiv/_build?definitionScope=%5CAzure%20Tools%5CVSCode) to point to the new pipeline files in `.config`. This can be done in the pipeline settings, and does not require the "DevDiv Edit Pipelines" entitlement. From e6da3f246aec98167a542d55160d66ad058e0f20 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:23:02 -0500 Subject: [PATCH 19/41] Copilot feedback --- azdo-pipelines/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index 46b2c8f755..8217c6ad9f 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -89,15 +89,15 @@ This template releases a signed VS Code extension to the Visual Studio Marketpla ### Parameters -| Parameter | Type | Default | Description | -| ---------------------------------- | ------- | ------------ | -------------------------------------------------- | -| `packageToPublish` | string | *required* | Regex pattern to match the `.vsix` file | -| `publishVersion` | string | *required* | Expected version (verified against `package.json`) | -| `dryRun` | boolean | `false` | Skip the actual publish step | -| `artifactName` | string | `Build Root` | Name of the artifact containing the package | -| `extensionReleaseServiceConnection`| string | *required* | Service connection for VSCE authentication | -| `releaseApprovalEnvironment` | string | `""` | AzDO environment for release approval | -| `releasePool` | object | Windows MicroBuild pool | Pool for the release job | +| Parameter | Type | Default | Description | +| --------------------------- | ------- | ------------ | -------------------------------------------------- | +| `packageToPublish` | string | *required* | Regex pattern to match the `.vsix` file | +| `publishVersion` | string | *required* | Expected version (verified against `package.json`) | +| `dryRun` | boolean | `false` | Skip the actual publish step | +| `artifactName` | string | `Build Root` | Name of the artifact containing the package | +| `releaseServiceConnection` | string | *required* | Service connection for VSCE authentication | +| `releaseApprovalEnvironment`| string | `""` | AzDO environment for release approval | +| `releasePool` | object | Windows MicroBuild pool | Pool for the release job | ### Required Build Artifacts From 05e80bc94ddb18fe8233d45b2e82cfce224111c1 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:24:01 -0500 Subject: [PATCH 20/41] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- azdo-pipelines/templates/set-release-build-number.yml | 2 +- azdo-pipelines/templates/stage-artifacts.yml | 4 ++-- azdo-pipelines/templates/test.yml | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/azdo-pipelines/templates/set-release-build-number.yml b/azdo-pipelines/templates/set-release-build-number.yml index 3eeff65432..a5987e79b1 100644 --- a/azdo-pipelines/templates/set-release-build-number.yml +++ b/azdo-pipelines/templates/set-release-build-number.yml @@ -13,7 +13,7 @@ parameters: steps: - pwsh: | - $newBuildNumber = "$(Build.BuildNumber)-${{ parameters.packageToPublish }}-${{ parameters.publishVersion}}" + $newBuildNumber = "$(Build.BuildNumber)-${{ parameters.packageToPublish }}-${{ parameters.publishVersion }}" if ('${{ parameters.dryRun }}' -eq 'True') { Write-Output "Dry run was set to True. Adding 'dry' to the build number." diff --git a/azdo-pipelines/templates/stage-artifacts.yml b/azdo-pipelines/templates/stage-artifacts.yml index 22a78d2ad9..a2118f5339 100644 --- a/azdo-pipelines/templates/stage-artifacts.yml +++ b/azdo-pipelines/templates/stage-artifacts.yml @@ -7,8 +7,8 @@ steps: Contents: | **/*.vsix **/package.json - **/*extension.manifest - **/*extension.signature.p7s + **/*.extension.manifest + **/*.extension.signature.p7s **/*.tar.gz **/*.tgz !**/node_modules/** diff --git a/azdo-pipelines/templates/test.yml b/azdo-pipelines/templates/test.yml index bb097177bb..69eca010fb 100644 --- a/azdo-pipelines/templates/test.yml +++ b/azdo-pipelines/templates/test.yml @@ -18,7 +18,9 @@ steps: scriptLocation: inlineScript addSpnToEnvironment: true inlineScript: | - Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_ID]$env:AZURESUBSCRIPTION_SERVICE_CONNECTION_ID" # Note: this gets set by the task, but that behavior may not be intentional, unlike the next two which are documented for addSpnToEnvironment. However, I asked the dev and was told it was safe to use. + # FC_SERVICE_CONNECTION_ID is sourced from AZURESUBSCRIPTION_SERVICE_CONNECTION_ID set by the AzureCLI@2 task. + # This behavior is not clearly documented, but was confirmed by the task developer as safe to rely on. + Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_ID]$env:AZURESUBSCRIPTION_SERVICE_CONNECTION_ID" Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable variable=FC_SERVICE_CONNECTION_TENANT_ID]$env:tenantId" From 42f58949ab9ce7f6ebbba7a7366a4c6fde0de938 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:29:10 -0500 Subject: [PATCH 21/41] Update azdo-pipelines/templates/1es-mb-sign.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- azdo-pipelines/templates/1es-mb-sign.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azdo-pipelines/templates/1es-mb-sign.yml b/azdo-pipelines/templates/1es-mb-sign.yml index 8b8b2c208f..6511dfa7b9 100644 --- a/azdo-pipelines/templates/1es-mb-sign.yml +++ b/azdo-pipelines/templates/1es-mb-sign.yml @@ -41,8 +41,9 @@ steps: Copy-Item $vsix.manifestName $vsix.signatureName # Add to the list of files to sign + $srcPath = Join-Path $vsix.directory $vsix.signatureName $fileListObject.SignFileRecordList[0].SignFileList += @{ - SrcPath = $(Join-Path $vsix.directory $vsix.signatureName) + SrcPath = $srcPath DstPath = $null } } From c49f2fb783a255ada4854252523ae1bbaf82b771 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:31:10 -0500 Subject: [PATCH 22/41] Add examples --- azdo-pipelines/MIGRATION.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/azdo-pipelines/MIGRATION.md b/azdo-pipelines/MIGRATION.md index 2d73bad73d..2113929505 100644 --- a/azdo-pipelines/MIGRATION.md +++ b/azdo-pipelines/MIGRATION.md @@ -8,3 +8,7 @@ Migration to the new templates is very easy. 4. Rewrite your release pipeline as needed, following the examples in the README for [extensions](./README.md#example-1) or [npm](./README.md#example-2). 5. Ensure your `.vscodeignore` or `.npmignore` is ignoring the new `.config` folder. 6. In Azure DevOps, update your [pipelines](https://devdiv.visualstudio.com/DevDiv/_build?definitionScope=%5CAzure%20Tools%5CVSCode) to point to the new pipeline files in `.config`. This can be done in the pipeline settings, and does not require the "DevDiv Edit Pipelines" entitlement. + +Example PRs: +- Extension: https://github.com/microsoft/vscode-containers/pull/365 +- NPM packages: https://github.com/microsoft/vscode-docker-extensibility/pull/334 From 0c0457a002bf8d04366bf3b875572764964b14ea Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:43:28 -0500 Subject: [PATCH 23/41] Mapping fix --- azdo-pipelines/stages/1es-stages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/stages/1es-stages.yml b/azdo-pipelines/stages/1es-stages.yml index 4140903cbf..5579513d23 100644 --- a/azdo-pipelines/stages/1es-stages.yml +++ b/azdo-pipelines/stages/1es-stages.yml @@ -69,7 +69,7 @@ stages: - template: ../templates/package.yml - ${{ if and(eq(length(parameters.alternativeSigningSteps), 0), ne(parameters.signType, 'none')) }}: - template: ../templates/1es-mb-sign.yml - ${{ elseif ne(length(parameters.alternativeSigningSteps), 0) }}: + - ${{ elseif ne(length(parameters.alternativeSigningSteps), 0) }}: - ${{ parameters.alternativeSigningSteps }} - template: ../templates/stage-artifacts.yml - template: ../templates/test.yml From 7e5ad967cb27298b12baa3376234254deb000e41 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 16:00:04 -0500 Subject: [PATCH 24/41] `TeamName` var --- azdo-pipelines/README.md | 3 +++ azdo-pipelines/azcode.variables.yml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index 8217c6ad9f..aae8545e02 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -75,6 +75,9 @@ resources: variables: # Pick up shared AZCode variables - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + # Required for MicroBuild signing + - name: TeamName + value: "Azure Tools for VS Code" # Note: if `azcode.variables.yml` is in use above, this is not needed extends: template: azdo-pipelines/1es-mb-main.yml@azExtTemplates # Use the main build template diff --git a/azdo-pipelines/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml index 97c9c7bab9..53577e5721 100644 --- a/azdo-pipelines/azcode.variables.yml +++ b/azdo-pipelines/azcode.variables.yml @@ -18,3 +18,7 @@ variables: # Test - name: testARMServiceConnection value: AzCodeE2ETests + + # Required for MicroBuild signing + - name: TeamName + value: "Azure Tools for VS Code" From dc668e9cb4a9d169e6bf29a3ed2b260516944184 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Thu, 29 Jan 2026 16:05:04 -0500 Subject: [PATCH 25/41] `TeamName` var --- azdo-pipelines/README.md | 8 +++++++- azdo-pipelines/azcode.variables.yml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/azdo-pipelines/README.md b/azdo-pipelines/README.md index aae8545e02..9225845e0b 100644 --- a/azdo-pipelines/README.md +++ b/azdo-pipelines/README.md @@ -75,7 +75,7 @@ resources: variables: # Pick up shared AZCode variables - template: azdo-pipelines/azcode.variables.yml@azExtTemplates - # Required for MicroBuild signing + # Required for MicroBuild signing and telemetry - name: TeamName value: "Azure Tools for VS Code" # Note: if `azcode.variables.yml` is in use above, this is not needed @@ -145,6 +145,9 @@ resources: variables: # Pick up shared AZCode variables - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + # Required for MicroBuild signing and telemetry + - name: TeamName + value: "Azure Tools for VS Code" # Note: if `azcode.variables.yml` is in use above, this is not needed extends: template: azdo-pipelines/1es-mb-release-extension.yml@azExtTemplates # Use the extension release template @@ -224,6 +227,9 @@ resources: variables: # Pick up shared AZCode variables - template: azdo-pipelines/azcode.variables.yml@azExtTemplates + # Required for MicroBuild signing and telemetry + - name: TeamName + value: "Azure Tools for VS Code" # Note: if `azcode.variables.yml` is in use above, this is not needed extends: template: azdo-pipelines/1es-mb-release-npm.yml@azExtTemplates # Use the NPM release template diff --git a/azdo-pipelines/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml index 53577e5721..6f4894b1eb 100644 --- a/azdo-pipelines/azcode.variables.yml +++ b/azdo-pipelines/azcode.variables.yml @@ -19,6 +19,6 @@ variables: - name: testARMServiceConnection value: AzCodeE2ETests - # Required for MicroBuild signing + # Required for MicroBuild signing and telemetry - name: TeamName value: "Azure Tools for VS Code" From 6d0f5add8f57bb02d1ce327f10ec8528a4b9a902 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:33:24 -0500 Subject: [PATCH 26/41] Apparently single quotes --- azdo-pipelines/1es-mb-release-npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 3505a551d9..057d982f2c 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -107,7 +107,7 @@ extends: approvers: "${{ parameters.approverAliases }}" # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, "")) }}: + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - task: GitHubRelease@1 displayName: "\U0001F449 Create draft release on GitHub" inputs: From b5a9578906da02b3ed663b455c46e13bf608f830 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:40:01 -0500 Subject: [PATCH 27/41] Reshaping? --- azdo-pipelines/1es-mb-release-extension.yml | 103 ++++++++++---------- azdo-pipelines/1es-mb-release-npm.yml | 91 ++++++++--------- 2 files changed, 100 insertions(+), 94 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index 5873969a7f..0660a9a114 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -51,7 +51,7 @@ extends: - stage: ReleaseStage displayName: Release extension jobs: - - job: Publish + - deployment: Publish ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: environment: ${{ parameters.releaseApprovalEnvironment }} displayName: Publish extension @@ -63,52 +63,55 @@ extends: pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - steps: - - checkout: none - - - task: NodeTool@0 - displayName: "\U0001F449 Using Node.js" - inputs: - versionSpec: 22.x - - - template: ./templates/find-vsixs.yml - parameters: - vsixName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - - - template: ./templates/set-release-build-number.yml - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} - - # Publish the package to VS Marketplace - - ${{ if eq(parameters.dryRun, false) }}: - - task: AzureCLI@2 - displayName: "\U0001F449 Publish VSIXs to Marketplace" - inputs: - azureSubscription: ${{ parameters.releaseServiceConnection }} - scriptType: pscore - scriptLocation: inlineScript - inlineScript: | - $vsixList = @('$(vsixListJson)' | ConvertFrom-Json) - - # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well - foreach ($vsix in $vsixList) { - Set-Location $vsix.directory - - $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" - if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { - $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" - } - - Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" - Write-Output " $($commandLine)" - - # Execute the publish command line - # Invoke-Expression $commandLine # TODO: temporarily disabled for testing - # if ($LASTEXITCODE -ne 0) { - # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" - # exit 1 - # } - } + strategy: + runOnce: + deploy: + steps: + - checkout: none + + - task: NodeTool@0 + displayName: "\U0001F449 Using Node.js" + inputs: + versionSpec: 22.x + + - template: ./templates/find-vsixs.yml + parameters: + vsixName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + + # Publish the package to VS Marketplace + - ${{ if eq(parameters.dryRun, false) }}: + - task: AzureCLI@2 + displayName: "\U0001F449 Publish VSIXs to Marketplace" + inputs: + azureSubscription: ${{ parameters.releaseServiceConnection }} + scriptType: pscore + scriptLocation: inlineScript + inlineScript: | + $vsixList = @('$(vsixListJson)' | ConvertFrom-Json) + + # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well + foreach ($vsix in $vsixList) { + Set-Location $vsix.directory + + $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" + if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { + $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" + } + + Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" + Write-Output " $($commandLine)" + + # Execute the publish command line + # Invoke-Expression $commandLine # TODO: temporarily disabled for testing + # if ($LASTEXITCODE -ne 0) { + # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" + # exit 1 + # } + } diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 057d982f2c..c51a9b84da 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -60,7 +60,7 @@ extends: - stage: ReleaseStage displayName: Release NPM package jobs: - - job: Publish + - deployment: Publish ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: environment: ${{ parameters.releaseApprovalEnvironment }} displayName: Publish NPM package @@ -72,51 +72,54 @@ extends: pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - steps: - - checkout: none + strategy: + runOnce: + deploy: + steps: + - checkout: none - - template: ./templates/find-tarballs.yml - parameters: - tarballName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} + - template: ./templates/find-tarballs.yml + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} - - pwsh: | - $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - $tgzFolderName = $tarballList[0].directory - $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - displayName: "\U0001F449 Set variables for found tarball" + - pwsh: | + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" - - template: ./templates/set-release-build-number.yml - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} - # Publish the package to NPM - - ${{ if eq(parameters.dryRun, false) }}: - - template: MicroBuild.Publish.yml@MicroBuildTemplate - parameters: - intent: PackageDistribution - contentType: npm - contentSource: Folder - folderLocation: "$(tgzFolderName)" - waitForReleaseCompletion: true - owners: "${{ parameters.ownerAliases }}" - approvers: "${{ parameters.approverAliases }}" + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" - # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - - task: GitHubRelease@1 - displayName: "\U0001F449 Create draft release on GitHub" - inputs: - gitHubConnection: ${{ parameters.gitHubServiceConnection }} - tagSource: userSpecifiedTag - tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - releaseNotesSource: inline - assets: "$(tgzFileName)" - isDraft: true - isPreRelease: true - addChangeLog: false + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false From bad529485456c77ee5964899aa6dc76b4f121388 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:42:37 -0500 Subject: [PATCH 28/41] Repathing I guess --- azdo-pipelines/1es-mb-release-extension.yml | 4 ++-- azdo-pipelines/1es-mb-release-npm.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index 0660a9a114..17dbc0e8e6 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -74,12 +74,12 @@ extends: inputs: versionSpec: 22.x - - template: ./templates/find-vsixs.yml + - template: azdo-pipelines/templates/find-vsixs.yml@azExtTemplates parameters: vsixName: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} - - template: ./templates/set-release-build-number.yml + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates parameters: packageToPublish: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index c51a9b84da..3bdc0457e4 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -78,7 +78,7 @@ extends: steps: - checkout: none - - template: ./templates/find-tarballs.yml + - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates parameters: tarballName: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} @@ -91,7 +91,7 @@ extends: Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" displayName: "\U0001F449 Set variables for found tarball" - - template: ./templates/set-release-build-number.yml + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates parameters: packageToPublish: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} From 657d27078690bdfe203a1005c5e0fb05e76bed73 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:54:55 -0500 Subject: [PATCH 29/41] Try this? --- azdo-pipelines/1es-mb-release-extension.yml | 107 ++++++++++---------- azdo-pipelines/1es-mb-release-npm.yml | 95 +++++++++-------- 2 files changed, 98 insertions(+), 104 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index 17dbc0e8e6..cee66e7535 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -51,67 +51,64 @@ extends: - stage: ReleaseStage displayName: Release extension jobs: - - deployment: Publish - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} + - job: Publish displayName: Publish extension templateContext: type: releaseJob isProduction: true + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - strategy: - runOnce: - deploy: - steps: - - checkout: none - - - task: NodeTool@0 - displayName: "\U0001F449 Using Node.js" - inputs: - versionSpec: 22.x - - - template: azdo-pipelines/templates/find-vsixs.yml@azExtTemplates - parameters: - vsixName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - - - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} - - # Publish the package to VS Marketplace - - ${{ if eq(parameters.dryRun, false) }}: - - task: AzureCLI@2 - displayName: "\U0001F449 Publish VSIXs to Marketplace" - inputs: - azureSubscription: ${{ parameters.releaseServiceConnection }} - scriptType: pscore - scriptLocation: inlineScript - inlineScript: | - $vsixList = @('$(vsixListJson)' | ConvertFrom-Json) - - # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well - foreach ($vsix in $vsixList) { - Set-Location $vsix.directory - - $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" - if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { - $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" - } - - Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" - Write-Output " $($commandLine)" - - # Execute the publish command line - # Invoke-Expression $commandLine # TODO: temporarily disabled for testing - # if ($LASTEXITCODE -ne 0) { - # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" - # exit 1 - # } - } + steps: + - checkout: none + + - task: NodeTool@0 + displayName: "\U0001F449 Using Node.js" + inputs: + versionSpec: 22.x + + - template: ./templates/find-vsixs.yml + parameters: + vsixName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + + # Publish the package to VS Marketplace + - ${{ if eq(parameters.dryRun, false) }}: + - task: AzureCLI@2 + displayName: "\U0001F449 Publish VSIXs to Marketplace" + inputs: + azureSubscription: ${{ parameters.releaseServiceConnection }} + scriptType: pscore + scriptLocation: inlineScript + inlineScript: | + $vsixList = @('$(vsixListJson)' | ConvertFrom-Json) + + # Publish each of the found VSIXs, automatically adding the enabled API proposals argument as well + foreach ($vsix in $vsixList) { + Set-Location $vsix.directory + + $commandLine = "npx @vscode/vsce@latest publish --azure-credential --packagePath $($vsix.vsixName) --manifestPath $($vsix.manifestName) --signaturePath $($vsix.signatureName)" + if ($vsix.proposedApis -ne $null -and $vsix.proposedApis.Count -gt 0) { + $commandLine += " --allow-proposed-apis $($vsix.proposedApis -join ' ')" + } + + Write-Output "Publishing VSIX: $($vsix.vsixName) with command:" + Write-Output " $($commandLine)" + + # Execute the publish command line + # Invoke-Expression $commandLine # TODO: temporarily disabled for testing + # if ($LASTEXITCODE -ne 0) { + # Write-Error "Failed to publish VSIX: $($vsix.vsixName)" + # exit 1 + # } + } diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 3bdc0457e4..9a3828983b 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -60,66 +60,63 @@ extends: - stage: ReleaseStage displayName: Release NPM package jobs: - - deployment: Publish - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} + - job: Publish displayName: Publish NPM package templateContext: type: releaseJob isProduction: true + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - strategy: - runOnce: - deploy: - steps: - - checkout: none + steps: + - checkout: none - - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates - parameters: - tarballName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} + - template: ./templates/find-tarballs.yml + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} - - pwsh: | - $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - $tgzFolderName = $tarballList[0].directory - $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - displayName: "\U0001F449 Set variables for found tarball" + - pwsh: | + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" - - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} + - template: ./templates/set-release-build-number.yml + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} - # Publish the package to NPM - - ${{ if eq(parameters.dryRun, false) }}: - - template: MicroBuild.Publish.yml@MicroBuildTemplate - parameters: - intent: PackageDistribution - contentType: npm - contentSource: Folder - folderLocation: "$(tgzFolderName)" - waitForReleaseCompletion: true - owners: "${{ parameters.ownerAliases }}" - approvers: "${{ parameters.approverAliases }}" + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" - # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - - task: GitHubRelease@1 - displayName: "\U0001F449 Create draft release on GitHub" - inputs: - gitHubConnection: ${{ parameters.gitHubServiceConnection }} - tagSource: userSpecifiedTag - tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - releaseNotesSource: inline - assets: "$(tgzFileName)" - isDraft: true - isPreRelease: true - addChangeLog: false + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false From 942eb109f37042e8f3ec4a0f78d73174caf88582 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:56:05 -0500 Subject: [PATCH 30/41] But keep that part --- azdo-pipelines/1es-mb-release-extension.yml | 4 ++-- azdo-pipelines/1es-mb-release-npm.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index cee66e7535..96c0fc94b8 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -71,12 +71,12 @@ extends: inputs: versionSpec: 22.x - - template: ./templates/find-vsixs.yml + - template: azdo-pipelines/templates/find-vsixs.yml@azExtTemplates parameters: vsixName: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} - - template: ./templates/set-release-build-number.yml + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates parameters: packageToPublish: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 9a3828983b..e90ed9f524 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -75,7 +75,7 @@ extends: steps: - checkout: none - - template: ./templates/find-tarballs.yml + - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates parameters: tarballName: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} @@ -88,7 +88,7 @@ extends: Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" displayName: "\U0001F449 Set variables for found tarball" - - template: ./templates/set-release-build-number.yml + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates parameters: packageToPublish: ${{ parameters.packageToPublish }} publishVersion: ${{ parameters.publishVersion }} From 5ab978a11b2e21b3938a51cac60138c4bcf6ab77 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:57:18 -0500 Subject: [PATCH 31/41] Try removing env temporarily --- azdo-pipelines/1es-mb-release-npm.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index e90ed9f524..4d29cd3489 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -65,8 +65,6 @@ extends: templateContext: type: releaseJob isProduction: true - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build From 6becbd8f6f1014784275eca057bedcd831eeb158 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:07:28 -0500 Subject: [PATCH 32/41] Disabling things --- azdo-pipelines/1es-mb-release-npm.yml | 93 ++++++++++++++------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 4d29cd3489..1810ae720d 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -65,6 +65,8 @@ extends: templateContext: type: releaseJob isProduction: true + # ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + # environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build @@ -73,48 +75,51 @@ extends: steps: - checkout: none - - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates - parameters: - tarballName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - - pwsh: | - $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - $tgzFolderName = $tarballList[0].directory - $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - displayName: "\U0001F449 Set variables for found tarball" - - - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} - - # Publish the package to NPM - - ${{ if eq(parameters.dryRun, false) }}: - - template: MicroBuild.Publish.yml@MicroBuildTemplate - parameters: - intent: PackageDistribution - contentType: npm - contentSource: Folder - folderLocation: "$(tgzFolderName)" - waitForReleaseCompletion: true - owners: "${{ parameters.ownerAliases }}" - approvers: "${{ parameters.approverAliases }}" - - # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - - task: GitHubRelease@1 - displayName: "\U0001F449 Create draft release on GitHub" - inputs: - gitHubConnection: ${{ parameters.gitHubServiceConnection }} - tagSource: userSpecifiedTag - tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - releaseNotesSource: inline - assets: "$(tgzFileName)" - isDraft: true - isPreRelease: true - addChangeLog: false + write-host 'hello from the release pipeline!' + + # - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates + # parameters: + # tarballName: ${{ parameters.packageToPublish }} + # publishVersion: ${{ parameters.publishVersion }} + + # - pwsh: | + # $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + # $tgzFolderName = $tarballList[0].directory + # $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + # Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + # Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + # displayName: "\U0001F449 Set variables for found tarball" + + # - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates + # parameters: + # packageToPublish: ${{ parameters.packageToPublish }} + # publishVersion: ${{ parameters.publishVersion }} + # dryRun: ${{ parameters.dryRun }} + + # # Publish the package to NPM + # - ${{ if eq(parameters.dryRun, false) }}: + # - template: MicroBuild.Publish.yml@MicroBuildTemplate + # parameters: + # intent: PackageDistribution + # contentType: npm + # contentSource: Folder + # folderLocation: "$(tgzFolderName)" + # waitForReleaseCompletion: true + # owners: "${{ parameters.ownerAliases }}" + # approvers: "${{ parameters.approverAliases }}" + + # # (Optional) Create a draft release on GitHub containing the package + # - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + # - task: GitHubRelease@1 + # displayName: "\U0001F449 Create draft release on GitHub" + # inputs: + # gitHubConnection: ${{ parameters.gitHubServiceConnection }} + # tagSource: userSpecifiedTag + # tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + # title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + # releaseNotesSource: inline + # assets: "$(tgzFileName)" + # isDraft: true + # isPreRelease: true + # addChangeLog: false From 561b16ec720e5dccf9adc6ad25cd4bdc0d9c1de8 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:16:51 -0500 Subject: [PATCH 33/41] Thing --- azdo-pipelines/1es-mb-release-npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 1810ae720d..05b97a1332 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -73,7 +73,7 @@ extends: targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" steps: - - checkout: none + # - checkout: none - pwsh: | write-host 'hello from the release pipeline!' From 25caf581df27315437be3f1605989f1d23ef3b6b Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:17:53 -0500 Subject: [PATCH 34/41] Thing --- azdo-pipelines/1es-mb-release-npm.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 05b97a1332..f60a2f7785 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -53,7 +53,7 @@ resources: ref: refs/heads/release extends: - template: azure-pipelines/MicroBuild.1ES.Official.Publish.yml@MicroBuildTemplate + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: pool: ${{ parameters.releasePool }} stages: @@ -73,7 +73,7 @@ extends: targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" steps: - # - checkout: none + - checkout: none - pwsh: | write-host 'hello from the release pipeline!' From f543d5663c8dd0c66a7d29dda831303899c64739 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:25:15 -0500 Subject: [PATCH 35/41] Show broken --- azdo-pipelines/1es-mb-release-npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index f60a2f7785..1810ae720d 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -53,7 +53,7 @@ resources: ref: refs/heads/release extends: - template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + template: azure-pipelines/MicroBuild.1ES.Official.Publish.yml@MicroBuildTemplate parameters: pool: ${{ parameters.releasePool }} stages: From 7d45a4b7ce781287d7a91dac713991c1b129694e Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:46:04 -0500 Subject: [PATCH 36/41] Rolling it back --- azdo-pipelines/1es-mb-release-npm.yml | 95 +++++++++++++-------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 1810ae720d..e90ed9f524 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -65,8 +65,8 @@ extends: templateContext: type: releaseJob isProduction: true - # ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - # environment: ${{ parameters.releaseApprovalEnvironment }} + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build @@ -75,51 +75,48 @@ extends: steps: - checkout: none - - pwsh: | - write-host 'hello from the release pipeline!' - - # - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates - # parameters: - # tarballName: ${{ parameters.packageToPublish }} - # publishVersion: ${{ parameters.publishVersion }} - - # - pwsh: | - # $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - # $tgzFolderName = $tarballList[0].directory - # $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - # Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - # Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - # displayName: "\U0001F449 Set variables for found tarball" + - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} - # - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - # parameters: - # packageToPublish: ${{ parameters.packageToPublish }} - # publishVersion: ${{ parameters.publishVersion }} - # dryRun: ${{ parameters.dryRun }} - - # # Publish the package to NPM - # - ${{ if eq(parameters.dryRun, false) }}: - # - template: MicroBuild.Publish.yml@MicroBuildTemplate - # parameters: - # intent: PackageDistribution - # contentType: npm - # contentSource: Folder - # folderLocation: "$(tgzFolderName)" - # waitForReleaseCompletion: true - # owners: "${{ parameters.ownerAliases }}" - # approvers: "${{ parameters.approverAliases }}" - - # # (Optional) Create a draft release on GitHub containing the package - # - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - # - task: GitHubRelease@1 - # displayName: "\U0001F449 Create draft release on GitHub" - # inputs: - # gitHubConnection: ${{ parameters.gitHubServiceConnection }} - # tagSource: userSpecifiedTag - # tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - # title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - # releaseNotesSource: inline - # assets: "$(tgzFileName)" - # isDraft: true - # isPreRelease: true - # addChangeLog: false + - pwsh: | + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" + + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} + + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" + + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false From 2478c1b5c5ac910aaded6be22af4cd2743dfd150 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:51:31 -0500 Subject: [PATCH 37/41] Switch temporarily --- azdo-pipelines/1es-mb-release-npm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index e90ed9f524..a14bc0e4f3 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -49,7 +49,7 @@ resources: repositories: - repository: MicroBuildTemplate type: git - name: 1ESPipelineTemplates/MicroBuildTemplate + name: MicroBuildTemplates/MicroBuildTemplates # TODO: Back to the 1ES repo after migration ref: refs/heads/release extends: From 4aa06978610eb4bbc76fce60dffdebaf8e8b187a Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:58:42 -0500 Subject: [PATCH 38/41] Try to make it a deployment job --- azdo-pipelines/1es-mb-release-npm.yml | 95 ++++++++++++++------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index a14bc0e4f3..222140836c 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -60,63 +60,66 @@ extends: - stage: ReleaseStage displayName: Release NPM package jobs: - - job: Publish + - deployment: Publish displayName: Publish NPM package + ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + environment: ${{ parameters.releaseApprovalEnvironment }} templateContext: type: releaseJob isProduction: true - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - steps: - - checkout: none + strategy: + runOnce: + deploy: + steps: + - checkout: none - - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates - parameters: - tarballName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} + - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} - - pwsh: | - $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - $tgzFolderName = $tarballList[0].directory - $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - displayName: "\U0001F449 Set variables for found tarball" + - pwsh: | + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" - - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} - # Publish the package to NPM - - ${{ if eq(parameters.dryRun, false) }}: - - template: MicroBuild.Publish.yml@MicroBuildTemplate - parameters: - intent: PackageDistribution - contentType: npm - contentSource: Folder - folderLocation: "$(tgzFolderName)" - waitForReleaseCompletion: true - owners: "${{ parameters.ownerAliases }}" - approvers: "${{ parameters.approverAliases }}" + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" - # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - - task: GitHubRelease@1 - displayName: "\U0001F449 Create draft release on GitHub" - inputs: - gitHubConnection: ${{ parameters.gitHubServiceConnection }} - tagSource: userSpecifiedTag - tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - releaseNotesSource: inline - assets: "$(tgzFileName)" - isDraft: true - isPreRelease: true - addChangeLog: false + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false From 3df60fb8ebe137d52a2c6172708942857db04ed7 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:09:19 -0500 Subject: [PATCH 39/41] Going back to where I was --- azdo-pipelines/1es-mb-release-extension.yml | 5 +- azdo-pipelines/1es-mb-release-npm.yml | 96 ++++++++++----------- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/azdo-pipelines/1es-mb-release-extension.yml b/azdo-pipelines/1es-mb-release-extension.yml index 96c0fc94b8..eb5b98843a 100644 --- a/azdo-pipelines/1es-mb-release-extension.yml +++ b/azdo-pipelines/1es-mb-release-extension.yml @@ -53,11 +53,12 @@ extends: jobs: - job: Publish displayName: Publish extension + # TODO: not working, `jobs.job` doesn't support `environment`, only `jobs.deployment` does + # ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + # environment: ${{ parameters.releaseApprovalEnvironment }} templateContext: type: releaseJob isProduction: true - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} inputs: - input: pipelineArtifact pipeline: build diff --git a/azdo-pipelines/1es-mb-release-npm.yml b/azdo-pipelines/1es-mb-release-npm.yml index 222140836c..02967ec320 100644 --- a/azdo-pipelines/1es-mb-release-npm.yml +++ b/azdo-pipelines/1es-mb-release-npm.yml @@ -60,10 +60,11 @@ extends: - stage: ReleaseStage displayName: Release NPM package jobs: - - deployment: Publish + - job: Publish displayName: Publish NPM package - ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: - environment: ${{ parameters.releaseApprovalEnvironment }} + # TODO: not working, `jobs.job` doesn't support `environment`, only `jobs.deployment` does + # ${{ if ne(parameters.releaseApprovalEnvironment, '') }}: + # environment: ${{ parameters.releaseApprovalEnvironment }} templateContext: type: releaseJob isProduction: true @@ -72,54 +73,51 @@ extends: pipeline: build targetPath: "$(System.DefaultWorkingDirectory)" artifactName: "${{ parameters.artifactName }}" - strategy: - runOnce: - deploy: - steps: - - checkout: none + steps: + - checkout: none - - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates - parameters: - tarballName: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} + - template: azdo-pipelines/templates/find-tarballs.yml@azExtTemplates + parameters: + tarballName: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} - - pwsh: | - $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) - $tgzFolderName = $tarballList[0].directory - $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName - Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" - Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" - displayName: "\U0001F449 Set variables for found tarball" + - pwsh: | + $tarballList = @('$(tarballListJson)' | ConvertFrom-Json) + $tgzFolderName = $tarballList[0].directory + $tgzFileName = Join-Path $tgzFolderName $tarballList[0].tarballName + Write-Host "##vso[task.setvariable variable=tgzFolderName]$tgzFolderName" + Write-Host "##vso[task.setvariable variable=tgzFileName]$tgzFileName" + displayName: "\U0001F449 Set variables for found tarball" - - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates - parameters: - packageToPublish: ${{ parameters.packageToPublish }} - publishVersion: ${{ parameters.publishVersion }} - dryRun: ${{ parameters.dryRun }} + - template: azdo-pipelines/templates/set-release-build-number.yml@azExtTemplates + parameters: + packageToPublish: ${{ parameters.packageToPublish }} + publishVersion: ${{ parameters.publishVersion }} + dryRun: ${{ parameters.dryRun }} - # Publish the package to NPM - - ${{ if eq(parameters.dryRun, false) }}: - - template: MicroBuild.Publish.yml@MicroBuildTemplate - parameters: - intent: PackageDistribution - contentType: npm - contentSource: Folder - folderLocation: "$(tgzFolderName)" - waitForReleaseCompletion: true - owners: "${{ parameters.ownerAliases }}" - approvers: "${{ parameters.approverAliases }}" + # Publish the package to NPM + - ${{ if eq(parameters.dryRun, false) }}: + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: PackageDistribution + contentType: npm + contentSource: Folder + folderLocation: "$(tgzFolderName)" + waitForReleaseCompletion: true + owners: "${{ parameters.ownerAliases }}" + approvers: "${{ parameters.approverAliases }}" - # (Optional) Create a draft release on GitHub containing the package - - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: - - task: GitHubRelease@1 - displayName: "\U0001F449 Create draft release on GitHub" - inputs: - gitHubConnection: ${{ parameters.gitHubServiceConnection }} - tagSource: userSpecifiedTag - tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" - title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" - releaseNotesSource: inline - assets: "$(tgzFileName)" - isDraft: true - isPreRelease: true - addChangeLog: false + # (Optional) Create a draft release on GitHub containing the package + - ${{ if and(eq(parameters.dryRun, false), ne(parameters.gitHubServiceConnection, '')) }}: + - task: GitHubRelease@1 + displayName: "\U0001F449 Create draft release on GitHub" + inputs: + gitHubConnection: ${{ parameters.gitHubServiceConnection }} + tagSource: userSpecifiedTag + tag: "${{ parameters.packageToPublish }}-v${{ parameters.publishVersion }}" + title: "${{ parameters.packageToPublish }} v${{ parameters.publishVersion }}" + releaseNotesSource: inline + assets: "$(tgzFileName)" + isDraft: true + isPreRelease: true + addChangeLog: false From 0a0e33c2f8d44e39e9a7ed3c4fea9673ed5e2dc8 Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:19:26 -0500 Subject: [PATCH 40/41] Try reversing owner/approver --- azdo-pipelines/azcode.variables.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azdo-pipelines/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml index 6f4894b1eb..ffe7eb9ae6 100644 --- a/azdo-pipelines/azcode.variables.yml +++ b/azdo-pipelines/azcode.variables.yml @@ -11,9 +11,9 @@ variables: - name: npmReleaseApprovalEnvironment value: AzCodeDeploy - name: npmReleaseOwnerAliases - value: azcode - - name: npmReleaseApproverAliases value: jinglou + - name: npmReleaseApproverAliases + value: azcode # Test - name: testARMServiceConnection From 745cee51e9c584baf825482caa762da4c5e6ebfb Mon Sep 17 00:00:00 2001 From: "Brandon Waterloo [MSFT]" <36966225+bwateratmsft@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:25:02 -0500 Subject: [PATCH 41/41] Fine then, be that way --- azdo-pipelines/azcode.variables.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdo-pipelines/azcode.variables.yml b/azdo-pipelines/azcode.variables.yml index ffe7eb9ae6..8f8747f625 100644 --- a/azdo-pipelines/azcode.variables.yml +++ b/azdo-pipelines/azcode.variables.yml @@ -13,7 +13,7 @@ variables: - name: npmReleaseOwnerAliases value: jinglou - name: npmReleaseApproverAliases - value: azcode + value: bwater # Test - name: testARMServiceConnection