Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions azure-pipelines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,28 @@ The extension release pipeline has the following parameters.
- name: publishCommands
type: object
default: ['vsce publish --azure-credential --packagePath $(vsixFileName) --manifestPath extension.manifest --signaturePath extension.signature.p7s']

# The subdirectory within the build artifacts where the extension files are located.
# Leave empty (default) for extensions at the root level.
# Set to the subdirectory name (e.g., "helper") for extensions in subdirectories.
- name: artifactSubdirectory
type: string
default: ""
```

#### Using with extensions in subdirectories

If your extension is located in a subdirectory (e.g., `helper/`) and the build artifacts preserve that directory structure, you need to specify the `artifactSubdirectory` parameter when calling the release template:

```yaml
extends:
template: azure-pipelines/release-extension.yml@azExtTemplates
parameters:
publishVersion: ${{ parameters.publishVersion }}
dryRun: ${{ parameters.dryRun }}
artifactSubdirectory: "helper" # Specify the subdirectory name
environmentName: AzCodeDeploy
ExtensionReleaseServiceConnection: AzCodeReleases
```

This ensures the release pipeline looks for `package.json`, `.vsix` files, and signing artifacts in the correct subdirectory within the downloaded build artifacts.
76 changes: 69 additions & 7 deletions azure-pipelines/release-extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ parameters:
type: boolean
default: false

# A list of publish commands to run. It defaults to publishing a single .vsix file. If you want to publish multiple .vsix files (platform specifc), you can add mutliple commands to this list.
# A list of publish commands to run. It defaults to publishing a single .vsix file. If you want to publish multiple .vsix files (platform specific), you can add multiple commands to this list.
- name: publishCommands
type: object
default:
[
"vsce publish --azure-credential --packagePath $(vsixFileName) --manifestPath extension.manifest --signaturePath extension.signature.p7s",
]

# The subdirectory within the build artifacts where the extension files are located.
# Leave empty (default) for extensions at the root level.
# Set to the subdirectory name (e.g., "helper") for extensions in subdirectories.
- name: artifactSubdirectory
type: string
default: ""

# `resources` specifies the location of templates to pick up, use it to get 1ES templates
resources:
repositories:
Expand Down Expand Up @@ -75,8 +82,17 @@ extends:
# Modify the build number to include repo name, extension version, and if dry run is true
- powershell: |
# Get the version from package.json
$artifactSubdirectory = "$env:artifactSubdirectory"
$workingDirectory = "$(System.DefaultWorkingDirectory)"

if ($artifactSubdirectory) {
$workingDirectory = Join-Path $workingDirectory $artifactSubdirectory
Write-Output "Using subdirectory: $artifactSubdirectory"
Write-Output "Working directory: $workingDirectory"
}

$packageJsonPath = "$(System.DefaultWorkingDirectory)/package.json"
$packageJsonPath = Join-Path $workingDirectory "package.json"
Write-Output "Looking for package.json at: $packageJsonPath"
$npmVersionString = (Get-Content $packageJsonPath | ConvertFrom-Json).version
$isDryRun = "$env:dryRun"
$currentBuildNumber = "$(Build.BuildId)"
Expand All @@ -96,12 +112,22 @@ extends:
displayName: "\U0001F449 Prepend version from package.json to build number"
env:
dryRun: ${{ parameters.dryRun }}
artifactSubdirectory: ${{ parameters.artifactSubdirectory }}

# For safety, verify the version in package.json matches the version to publish entered by the releaser
# If they don't match, this step fails
- powershell: |
# Get the version from package.json
$packageJsonPath = "$(System.DefaultWorkingDirectory)/package.json"
$artifactSubdirectory = "$env:artifactSubdirectory"
$workingDirectory = "$(System.DefaultWorkingDirectory)"

if ($artifactSubdirectory) {
$workingDirectory = Join-Path $workingDirectory $artifactSubdirectory
Write-Output "Using subdirectory: $artifactSubdirectory"
}

$packageJsonPath = Join-Path $workingDirectory "package.json"
Write-Output "Looking for package.json at: $packageJsonPath"
$npmVersionString = (Get-Content $packageJsonPath | ConvertFrom-Json).version
$publishVersion = "$env:publishVersion"
Write-Output "Publishing version: $publishVersion"
Expand All @@ -115,24 +141,42 @@ extends:
displayName: "\U0001F449 Verify publish version"
env:
publishVersion: ${{ parameters.publishVersion }}
artifactSubdirectory: ${{ parameters.artifactSubdirectory }}

# Find the vsix to release and set the vsix file name variable
# Fails with an error if more than one .vsix file is found, or if no .vsix file is found
- powershell: |
# Get all .vsix files in the current directory
$vsixFiles = Get-ChildItem -Path $(System.DefaultWorkingDirectory) -Filter *.vsix -File
$artifactSubdirectory = "$env:artifactSubdirectory"
$workingDirectory = "$(System.DefaultWorkingDirectory)"

if ($artifactSubdirectory) {
$workingDirectory = Join-Path $workingDirectory $artifactSubdirectory
Write-Output "Using subdirectory: $artifactSubdirectory"
}

Write-Output "Looking for .vsix files in: $workingDirectory"
$vsixFiles = Get-ChildItem -Path $workingDirectory -Filter *.vsix -File

# Check if no .vsix file is found
if ($vsixFiles.Count -eq 0) {
Write-Error "No .vsix files found."
Write-Error "No .vsix files found in $workingDirectory"
exit 1
} elseif ($vsixFiles.Count -gt 1) {
Write-Error "Multiple .vsix files found in $workingDirectory. Expected exactly one."
foreach ($file in $vsixFiles) {
Write-Output " - $($file.Name)"
}
exit 1
} else {
# Set the pipeline variable
$vsixFileName = $vsixFiles.Name
# Set the pipeline variable with the full path
$vsixFileName = ($vsixFiles | Select-Object -First 1).FullName
Write-Output "##vso[task.setvariable variable=vsixFileName;]$vsixFileName"
Write-Output "Found .vsix file: $vsixFileName"
}
displayName: "\U0001F449 Find and Set .vsix File Variable"
env:
artifactSubdirectory: ${{ parameters.artifactSubdirectory }}

- task: UseNode@1
inputs:
Expand All @@ -142,6 +186,23 @@ extends:
- script: npm i -g @vscode/vsce
displayName: "\U0001F449 Install vsce"

# Set the working directory for vsce publish
- powershell: |
$artifactSubdirectory = "$env:artifactSubdirectory"
$workingDirectory = "$(System.DefaultWorkingDirectory)"

if ($artifactSubdirectory) {
$workingDirectory = Join-Path $workingDirectory $artifactSubdirectory
Write-Output "Setting working directory for vsce publish: $workingDirectory"
} else {
Write-Output "Using default working directory: $workingDirectory"
}

Write-Output "##vso[task.setvariable variable=vsceWorkingDirectory;]$workingDirectory"
displayName: "\U0001F449 Set vsce working directory"
env:
artifactSubdirectory: ${{ parameters.artifactSubdirectory }}

- ${{ each publishCommand in parameters.publishCommands }}:
# log the publishCommand
- powershell: |
Expand All @@ -154,4 +215,5 @@ extends:
azureSubscription: ${{ parameters.ExtensionReleaseServiceConnection }}
scriptType: pscore
scriptLocation: inlineScript
workingDirectory: $(vsceWorkingDirectory)
inlineScript: ${{ publishCommand }}