Building Azure DevOps Extension on Azure DevOps
import * as path from 'path'; | |
import * as tl from 'azure-pipelines-task-lib/task'; | |
async function run() { | |
} | |
run(); |
Param( | |
[string] [Parameter(Mandatory=$true)] $SourceDirectory | |
) | |
cd $SourceDirectory | |
Get-ChildItem *.ts -File -Recurse | Where-Object { | |
$_.FullName -notlike "*node_modules*" | |
} | ForEach-Object { | |
tsc $_.FullName | |
} |
{ | |
"id": "{{ GUID }}", | |
"name": "deploy", | |
"friendlyName": "Deploy Website", | |
"description": "Deploy website to Netlify", | |
"helpMarkDown": "This deployes website to Netlify", | |
"author": "{{ Author Name }}", | |
"preview": false, | |
"showEnvironmentVariables": false, | |
"runsOn": [ | |
"Agent", | |
"MachineGroup", | |
"Server" | |
], | |
"category": "Azure Pipelines", | |
"version": { | |
"Major": 1, | |
"Minor": 0, | |
"Patch": 0 | |
}, | |
"instanceNameFormat": "Deploy to Netlify", | |
"inputs": [ | |
{ | |
"type": "string", | |
"name": "authToken", | |
"label": "Authentication Token", | |
"defaultValue": "", | |
"required": true, | |
"helpMarkDown": "The authentication token to login to Netlify" | |
}, | |
{ | |
"type": "string", | |
"name": "siteId", | |
"label": "Site ID", | |
"defaultValue": "", | |
"required": true, | |
"helpMarkDown": "The site ID to deploy to" | |
}, | |
{ | |
"type": "filePath", | |
"name": "sourceDirectory", | |
"label": "Source Directory", | |
"defaultValue": "$(System.DefaultWorkingDirectory)", | |
"required": true, | |
"helpMarkDown": "The source directory to deploy" | |
}, | |
{ | |
"type": "boolean", | |
"name": "isValidationOnly", | |
"label": "Validation Only (No Production Deployment)", | |
"defaultValue": false, | |
"required": true, | |
"helpMarkDown": "Value indicating whether to only validate deployment or not" | |
}, | |
{ | |
"type": "string", | |
"name": "message", | |
"label": "Deployment Message", | |
"defaultValue": "", | |
"required": false, | |
"helpMarkDown": "The short message to include in the deployment log" | |
}, | |
{ | |
"type": "filePath", | |
"name": "functionsDirectory", | |
"label": "Functions Directory", | |
"defaultValue": "", | |
"required": false, | |
"helpMarkDown": "The functions directory to deploy" | |
} | |
], | |
"execution": { | |
"Node": { | |
"target": "index.js" | |
} | |
} | |
} |
tl.setResourcePath(path.join(__dirname, 'task.json')); | |
try { | |
const authToken: string = tl.getInput('authToken', true); | |
const siteId: string = tl.getInput('siteId', true); | |
const sourceDirectory: string = tl.getPathInput('sourceDirectory', true, true); | |
const isValidationOnly: boolean = tl.getBoolInput('isValidationOnly', true); | |
const message: string = tl.getInput('message', false); | |
const functionsDirectory: string = tl.getPathInput('functionsDirectory', false, true); | |
const args: Array<string> = new Array<string>(); | |
args.push('deploy') | |
args.push('--auth=' + authToken); | |
args.push('--site=' + siteId); | |
args.push('--dir=' + sourceDirectory); | |
if (!isValidationOnly) { | |
args.push('--prod'); | |
} | |
if (message) { | |
args.push('--message=' + message); | |
} | |
if (functionsDirectory) { | |
args.push('--functions=' + functionsDirectory); | |
} | |
args.push('--json'); | |
await tl.exec('netlify', args); | |
} | |
catch (err) { | |
tl.setResult(tl.TaskResult.Failed, err.message); | |
} |
{ | |
"id": "{{ GUID }}", | |
"name": "install", | |
"friendlyName": "Install Netlify CLI", | |
"description": "Install Netlify CLI", | |
"helpMarkDown": "This installs the netlify-cli", | |
"author": "{{ Author Name }}", | |
"preview": false, | |
"showEnvironmentVariables": false, | |
"runsOn": [ | |
"Agent", | |
"MachineGroup", | |
"Server" | |
], | |
"category": "Azure Pipelines", | |
"version": { | |
"Major": 1, | |
"Minor": 0, | |
"Patch": 0 | |
}, | |
"instanceNameFormat": "Install Netlify CLI", | |
"inputs": [ | |
{ | |
"type": "string", | |
"name": "version", | |
"label": "Version", | |
"defaultValue": "", | |
"required": false, | |
"helpMarkDown": "The version of Netlify CLI. If omitted, the latest version of netlify-cli is installed. Visit the [npm package](https://www.npmjs.com/package/netlify) to get an appropriate version." | |
} | |
], | |
"execution": { | |
"Node": { | |
"target": "index.js" | |
} | |
} | |
} |
tl.setResourcePath(path.join(__dirname, 'task.json')); | |
try { | |
const version: string = tl.getInput('version', false); | |
const args: Array<string> = new Array<string>(); | |
args.push('install'); | |
args.push('-g'); | |
if (version) { | |
args.push('netlify-cli@' + version); | |
} | |
else { | |
args.push('netlify-cli'); | |
} | |
await tl.exec('npm', args); | |
} | |
catch (err) { | |
tl.setResult(tl.TaskResult.Failed, err.message); | |
} |
# netlify-build.yaml | |
name: $(Version).$(rev:r) | |
... | |
stages: | |
# Build Pipeline | |
- stage: Build | |
jobs: | |
- job: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
demands: npm | |
workspace: | |
clean: all | |
steps: | |
# Calls the template | |
- template: templates/npm-build-steps.yaml | |
parameters: | |
extensionName: $(ExtensionName) |
# pipelines/netlify-build.yaml | |
name: $(Version).$(rev:r) | |
variables: | |
- group: Common Netlify | |
trigger: | |
branches: | |
include: | |
- dev | |
- feature/* | |
- hotfix/* | |
paths: | |
include: | |
- 'Netlify/*' | |
exclude: | |
- 'pipelines/*' | |
- 'scripts/*' | |
- '.editorconfig' | |
- '.gitignore' | |
- 'README.md' | |
stages: | |
# Build Pipeline | |
- stage: Build | |
jobs: | |
- job: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
demands: npm | |
workspace: | |
clean: all | |
steps: | |
- task: Npm@1 | |
displayName: 'Install npm Packages' | |
inputs: | |
command: install | |
workingDir: '$(Build.SourcesDirectory)/$(ExtensionName)/src' | |
verbose: false | |
- task: PowerShell@2 | |
displayName: 'Compile TypeScript Files' | |
inputs: | |
targetType: filePath | |
filePath: '$(Build.SourcesDirectory)/scripts/Compile-TypeScripts.ps1' | |
arguments: '-SourceDirectory $(Build.SourcesDirectory)/$(ExtensionName)/src' |
netlify deploy --auth=*** --site=*** --dir=*** --prod --functions=*** --json |
# pipelines/netlify-pr.yaml | |
pr: | |
branches: | |
include: | |
- dev | |
paths: | |
include: | |
- 'Netlify/*' | |
exclude: | |
- 'pipelines/*' | |
- 'scripts/*' | |
- '.editorconfig' | |
- '.gitignore' | |
- 'README.md' |
# pipelines/netlify-release.yaml | |
name: $(Version).$(rev:r) | |
... | |
stages: | |
# Build Pipeline | |
- stage: Build | |
jobs: | |
- job: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
demands: npm | |
workspace: | |
clean: all | |
variables: | |
- group: Common Marketplace | |
- group: PROD Marketplace | |
steps: | |
# Calls the template | |
- template: templates/npm-build-steps.yaml | |
parameters: | |
extensionName: $(ExtensionName) | |
# Continue existing tasks | |
- task: ms-devlabs.vsts-developer-tools-build-tasks.tfx-installer-build-task.TfxInstaller@1 | |
displayName: 'Install tfx-cli' | |
inputs: | |
version: v0.7.x | |
autoUpdate: true | |
... |
# pipelines/netlify-release.yaml | |
name: $(Version).$(rev:r) | |
variables: | |
- group: Common Netlify | |
trigger: | |
branches: | |
include: | |
- release/netlify | |
paths: | |
include: | |
- 'Netlify/*' | |
exclude: | |
- 'pipelines/*' | |
- 'scripts/*' | |
- '.editorconfig' | |
- '.gitignore' | |
- 'README.md' | |
stages: | |
# Build Pipeline | |
- stage: Build | |
jobs: | |
- job: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
demands: npm | |
workspace: | |
clean: all | |
variables: | |
- group: Common Marketplace | |
- group: PROD Marketplace | |
steps: | |
- task: Npm@1 | |
displayName: 'Install npm Packages' | |
inputs: | |
command: install | |
workingDir: '$(Build.SourcesDirectory)/$(ExtensionName)/src' | |
verbose: false | |
- task: PowerShell@2 | |
displayName: 'Compile TypeScript Files' | |
inputs: | |
targetType: filePath | |
filePath: '$(Build.SourcesDirectory)/scripts/Compile-TypeScripts.ps1' | |
arguments: '-SourceDirectory $(Build.SourcesDirectory)/$(ExtensionName)/src' | |
- task: ms-devlabs.vsts-developer-tools-build-tasks.tfx-installer-build-task.TfxInstaller@1 | |
displayName: 'Install tfx-cli' | |
inputs: | |
version: v0.7.x | |
autoUpdate: true | |
- task: ms-devlabs.vsts-developer-tools-build-tasks.package-extension-build-task.PackageVSTSExtension@1 | |
displayName: 'Package Extension' | |
inputs: | |
rootFolder: '$(Build.SourcesDirectory)/$(ExtensionName)' | |
patternManifest: '$(ManifestFileName)' | |
outputPath: '$(Build.ArtifactStagingDirectory)' | |
outputVariable: 'Extension.OutputPath' | |
publisherId: '$(PublisherId)' | |
extensionId: '$(ExtensionId)' | |
extensionName: '$(ExtensionName)' | |
extensionVersion: '$(Version)' | |
updateTasksVersion: false | |
updateTasksId: false | |
extensionVisibility: private | |
extensionPricing: free | |
- task: PublishBuildArtifacts@1 | |
displayName: 'Publish Artifact' | |
inputs: | |
pathToPublish: $(Build.ArtifactStagingDirectory) | |
artifactName: drop | |
publishLocation: 'Container' | |
# Release Pipeline to DEV | |
- stage: DEV | |
jobs: | |
- deployment: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
variables: | |
- group: Common Marketplace | |
- group: DEV Marketplace | |
environment: netlify-dev | |
strategy: | |
runOnce: | |
deploy: | |
steps: | |
- task: TfxInstaller@1 | |
#- task: ms-devlabs.vsts-developer-tools-build-tasks.tfx-installer-build-task.TfxInstaller@1 | |
displayName: 'Install tfx-cli' | |
inputs: | |
version: "v0.7.x" | |
autoUpdate: true | |
- task: PublishExtension@1 | |
#- task: ms-devlabs.vsts-developer-tools-build-tasks.publish-extension-build-task.PublishExtension@1 | |
displayName: 'Publish Extension' | |
inputs: | |
connectedServiceName: aliencube.marketplace.visualstudio.com | |
fileType: vsix | |
vsixFile: '$(Pipeline.Workspace)/drop/$(PublisherId.Prod).$(ExtensionId)-$(Version).vsix' | |
publisherId: $(PublisherId) | |
updateTasksVersion: false | |
updateTasksId: false | |
extensionVisibility: $(Visibility) | |
extensionPricing: $(Pricing) | |
outputVariable: Extension.OutputPath | |
shareWith: $(Organisation) | |
# Release Pipeline to PROD | |
- stage: PROD | |
jobs: | |
- deployment: HostedVs2017 | |
displayName: Hosted VS2017 | |
pool: | |
name: Hosted VS2017 | |
variables: | |
- group: Common Marketplace | |
- group: PROD Marketplace | |
environment: netlify-prod | |
strategy: | |
runOnce: | |
deploy: | |
steps: | |
- task: TfxInstaller@1 | |
#- task: ms-devlabs.vsts-developer-tools-build-tasks.tfx-installer-build-task.TfxInstaller@1 | |
displayName: 'Install tfx-cli' | |
inputs: | |
version: "v0.7.x" | |
autoUpdate: true | |
- task: PublishExtension@1 | |
#- task: ms-devlabs.vsts-developer-tools-build-tasks.publish-extension-build-task.PublishExtension@1 | |
displayName: 'Publish Extension' | |
inputs: | |
connectedServiceName: aliencube.marketplace.visualstudio.com | |
fileType: vsix | |
vsixFile: '$(Pipeline.Workspace)/drop/$(PublisherId.Prod).$(ExtensionId)-$(Version).vsix' | |
publisherId: $(PublisherId) | |
updateTasksVersion: false | |
updateTasksId: false | |
extensionVisibility: $(Visibility) | |
extensionPricing: $(Pricing) | |
outputVariable: Extension.OutputPath |
node install/index.js |
# templates/npm-build-steps.yaml | |
parameters: | |
extensionName: "" | |
steps: | |
- task: Npm@1 | |
displayName: 'Install npm Packages' | |
inputs: | |
command: install | |
workingDir: '$(Build.SourcesDirectory)/${{ parameters.extensionName }}/src' | |
verbose: false | |
- task: PowerShell@2 | |
displayName: 'Compile TypeScript Files' | |
inputs: | |
targetType: filePath | |
filePath: '$(Build.SourcesDirectory)/scripts/Compile-TypeScripts.ps1' | |
arguments: '-SourceDirectory $(Build.SourcesDirectory)/${{ parameters.extensionName }}/src' |
npm init |
npm install -g netlify-cli@[version] |
npm install azure-pipelines-task-lib --save | |
npm install @types/node --save-dev | |
npm install @types/q --save-dev |
npm install -g tfx-cli |
npm install -g typescript |
# PowerShell | |
$env:INPUT_VERSION = "2.11.23" | |
# bash | |
export INPUT_VERSION="2.11.23" |
tfx extension create --manifest-globs vss-extension.json |
tsc |
tsc --init |
{ | |
"manifestVersion": 1, | |
"id": "{{ Extension ID }}", | |
"version": "{{ Extension Version }}", | |
"name": "{{ Extenson Name }}", | |
"publisher": "{{ Publisher ID }}", | |
"description": "{{ Description }}", | |
"targets": [ | |
{ | |
"id": "Microsoft.VisualStudio.Services" | |
} | |
], | |
"categories": [ | |
"Azure Pipelines" | |
], | |
"tags": [ | |
"netlify" | |
], | |
"galleryFlags": [ | |
"Free", | |
"Public" | |
], | |
"icons": { | |
"default": "icon.png" | |
}, | |
"content": { | |
"details": { | |
"path": "README.md" | |
} | |
}, | |
"files": [ | |
{ | |
"path": "images", | |
"addressable": true | |
}, | |
{ | |
"path": "src/install", | |
"packagePath": "install" | |
}, | |
{ | |
"path": "src/deploy", | |
"packagePath": "deploy" | |
}, | |
{ | |
"path": "src/node_modules", | |
"packagePath": "install/node_modules" | |
}, | |
{ | |
"path": "src/node_modules", | |
"packagePath": "deploy/node_modules" | |
} | |
], | |
"links": { | |
"overview": { | |
"uri": "https://github.com/aliencube/AzureDevOps.Extensions/blob/master/README.md" | |
}, | |
"license": { | |
"uri": "https://github.com/aliencube/AzureDevOps.Extensions/blob/master/LICENSE" | |
}, | |
"repository": { | |
"uri": "https://github.com/aliencube/AzureDevOps.Extensions" | |
}, | |
"issues": { | |
"uri": "https://github.com/aliencube/AzureDevOps.Extensions/issues" | |
} | |
}, | |
"repository": { | |
"type": "git", | |
"uri": "https://github.com/aliencube/AzureDevOps.Extensions" | |
}, | |
"badges": [ | |
{ | |
"href": "https://dev.azure.com/aliencube/AzureDevOps.Extensions/_build/latest?definitionId=-1", | |
"uri": "https://dev.azure.com/aliencube/AzureDevOps.Extensions/_apis/build/status/%5Bnetlify%5D%20dev%2C%20feature%2C%20hotfix", | |
"description": "Build Status" | |
} | |
], | |
"contributions": [ | |
{ | |
"id": "install-task", | |
"type": "ms.vss-distributed-task.task", | |
"targets": [ | |
"ms.vss-distributed-task.tasks" | |
], | |
"properties": { | |
"name": "install" | |
} | |
}, | |
{ | |
"id": "deploy-task", | |
"type": "ms.vss-distributed-task.task", | |
"targets": [ | |
"ms.vss-distributed-task.tasks" | |
], | |
"properties": { | |
"name": "deploy" | |
} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment