Skip to content

Commit

Permalink
azure-pipelines: Extension release template improvements (#1788)
Browse files Browse the repository at this point in the history
* Remove publish step

* Test deployment

* Try this

* Try publish template

* Try this

* What does this look like

* Customize build number

* Fixup

* Fixup

* Fixup

* Fixup

* Add version verification

* Fixup

* Fixup

* Fixup

* Fixup

* Try again

* Fixup

* Try this

* Try this

* Fixup

* Fixup

* Try this

* Add helpful error message

* Fixup

* Try this

* Fixup

* Works!

* Test this out

* Try this

* Fixup

* Fixup

* Try this

* Fixup

* Add repo name

* Try this out

* Testing

* Try this

* Try this

* Fixup

* Fixup

* Fixup

* Fixup

* Fixup

* Fixyp

* Add comments

* Update docs

* Add to docs

* Fixup. Sorry Brandon :D
  • Loading branch information
alexweininger authored Sep 9, 2024
1 parent 6c8a748 commit ceb419a
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 26 deletions.
61 changes: 53 additions & 8 deletions azure-pipelines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,41 +98,86 @@ extends:

### Extension release pipeline

This pipeline only downloads and releases signed VSIX artifacts from the specified build pipeline.
This pipeline downloads and releases signed VSIX artifacts from the specified build pipeline.

Some safety features have been added to this pipeline to prevent accidental releases:
1. Releases will require approval from an environment. The environment can be specified and every environment can have a different group of members that can approve releases. Self approval can be enabled/disabled.
2. A version string is required at pipeline run time that will be matched against the version present in the package.json downloaded from the build pipeline artifacts.
3. Added a "Dry Run" parameter that when set will skip the last step that actually publishes the extension.

The build pipeline needs to upload the following artifacts for this pipeline to work:
1. extension.vsix (name can vary, pipeline looks for a single *.vsix file)
2. package.json (needed to verify the extension name and version when publishing)
3. extension.manifest (created with `vsce generate-manifest`)
4. extension.signature.p7s (result of signing the manifest)

Use and modify the following YAML file to use the extension release pipeline template. Make sure to replace the `source` field with the name of the pipeline that produces the artifacts you want to release.
Use and modify the following YAML file to use the extension release pipeline template. Make sure to replace the `source` field with the name of the pipeline that produces the artifacts you want to release. Lines that should/could be customized will be marked with `# CUSTOMIZE`.

```yaml
trigger: none # Only run this pipeline when manually triggered
trigger: none
parameters:
- name: publishVersion
displayName: Version to publish
type: string
- name: dryRun
displayName: Dry run
type: boolean
default: false
resources:
pipelines:
- pipeline: build # identifier to use in pipeline resource variables
source: \Azure Tools\VSCode\Extensions\vscode-azurecontainerapps # name of the pipeline that produces the artifacts REPLACE THIS WITH YOUR PIPELINE NAME
- pipeline: build
source: \Azure Tools\VSCode\Extensions\vscode-azurecontainerapps # CUSTOMIZE - location of the pipeline that produces the artifacts
repositories:
- repository: azExtTemplates
type: github
name: microsoft/vscode-azuretools
ref: alex/release-template
endpoint: GitHub-AzureTools # The service connection to use when accessing this repository
ref: main
endpoint: GitHub-AzureTools
variables:
# Required by MicroBuild template
- name: TeamName
value: "Azure Tools for VS Code"
value: "Azure Tools for VS Code" # CUSTOMIZE
# Use those templates
extends:
template: azure-pipelines/release-extension.yml@azExtTemplates
parameters:
pipelineID: $(resources.pipeline.build.pipelineID)
runID: $(resources.pipeline.build.runID)
publishVersion: ${{ parameters.publishVersion }}
dryRun: ${{ parameters.dryRun }}
environmentName: AzCodeDeploy # CUSTOMIZE
```

The extension release pipeline has the following parameters.

```yaml
# pipelineID and runID are used to download the artifacts from a specific build pipeline
- name: pipelineID
type: string
- name: runID
type: string
# Customize the environment to associate the deployment with.
# Useful to control which group of people should be required to approve the deployment.
- name: environmentName
type: string
default: AzCodeDeploy
# The following parameters are meant to be provded by the user when initiating a pipeline run
# The intended extension version to publish.
# This is used to verify the version in package.json matches the version to publish to avoid accidental publishing.
- name: publishVersion
type: string
# When true, skips the deployment job which actually publishes the extension
- name: dryRun
type: boolean
default: false
```

### (DEPRECATED) Primary pipelines
Expand Down
109 changes: 91 additions & 18 deletions azure-pipelines/release-extension.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
parameters:
# pipelineID and runID are used to download the artifacts from a specific build pipeline
- name: pipelineID
type: string
- name: runID
type: string

# The intended extension version to publish.
# This is used to verify the version in package.json matches the version to publish to avoid accidental publishing.
- name: publishVersion
type: string

# Customize the environment to associate the deployment with.
# Useful to control which group of people should be required to approve the deployment.
- name: environmentName
type: string
default: AzCodeDeploy

# When true, skips the deployment job which actually publishes the extension
- name: dryRun
type: boolean
default: false

# `resources` specifies the location of templates to pick up, use it to get 1ES templates
resources:
repositories:
- repository: 1esPipelines
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
name: 1ESPipelineTemplates/1ESPipelineTemplates
ref: refs/tags/release

extends:
template: azure-pipelines/MicroBuild.1ES.Official.yml@1esPipelines
template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
parameters:
sdl:
codeql:
Expand All @@ -25,8 +42,10 @@ extends:

stages:
- stage: Release
displayName: Release extension
jobs:
- job: Release
- job: downloadArtifacts_job
displayName: Download artifacts
steps:
- checkout: none
- task: DownloadPipelineArtifact@2
Expand All @@ -40,7 +59,52 @@ extends:
artifact: Build Root
targetPath: $(System.DefaultWorkingDirectory)

# Modify the build number to include repo name, extension version, and if dry run is true
- powershell: |
# Get the version from package.json
$packageJsonPath = "$(Build.SourcesDirectory)/package.json"
$npmVersionString = (Get-Content $packageJsonPath | ConvertFrom-Json).version
$isDryRun = "$env:dryRun"
$currentBuildNumber = "$(Build.BuildId)"
$repoName = "$(Build.Repository.Name)"
$repoNameParts = $repoName -split '/'
$repoNameWithoutOwner = $repoNameParts[-1]
$dry = ""
if ($isDryRun -eq 'True') {
Write-Output "Dry run was set to True. Adding 'dry' to the build number."
$dry = "dry"
}
$newBuildNumber = "$repoNameWithoutOwner-$npmVersionString-$dry-$currentBuildNumber"
Write-Output "##vso[build.updatebuildnumber]$newBuildNumber"
displayName: 'Prepend version from package.json to build number'
env:
dryRun: ${{ parameters.dryRun }}
# 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 = "$(Build.SourcesDirectory)/package.json"
$npmVersionString = (Get-Content $packageJsonPath | ConvertFrom-Json).version
$publishVersion = "$env:publishVersion"
Write-Output "Publishing version: $publishVersion"
# Check if more than one .vsix file is found
if ($npmVersionString -eq $publishVersion) {
Write-Output "Publish version matches package.json version. Proceeding with release."
} else {
Write-Error "Publish version $publishVersion doesn't match version found in package.json $npmVersionString. Cancelling release."
exit 1
}
displayName: 'Verify publish version'
env:
publishVersion: ${{ parameters.publishVersion }}
# 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 $(Build.SourcesDirectory) -Filter *.vsix -File
Expand All @@ -60,20 +124,29 @@ extends:
}
displayName: "Find and Set .vsix File Variable"
- task: UseNode@1
inputs:
version: "20.x"
displayName: "Install Node.js"
- deployment: Publish
dependsOn: downloadArtifacts_job
displayName: Publish extension
environment: ${{ parameters.environmentName }}
condition: and(succeeded(), ${{ eq(parameters.dryRun, false) }})
strategy:
runOnce:
deploy:
steps:
- task: UseNode@1
inputs:
version: "20.x"
displayName: "Install Node.js"

- script: npm i -g @vscode/vsce
displayName: "Install vsce"
- script: npm i -g @vscode/vsce
displayName: "Install vsce"

# requires package.json to be present
- task: AzureCLI@2
displayName: Run vsce publish
inputs:
azureSubscription: AzCodeReleases
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
vsce publish --azure-credential --packagePath $(vsixFileName) --manifestPath extension.manifest --signaturePath extension.signature.p7s
# requires package.json to be present
- task: AzureCLI@2
displayName: Run vsce publish
inputs:
azureSubscription: AzCodeReleases
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
vsce publish --azure-credential --packagePath $(vsixFileName) --manifestPath extension.manifest --signaturePath extension.signature.p7s

0 comments on commit ceb419a

Please sign in to comment.