-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Porting PackageDownloader changes to M116 (#4046)
* Download Package task * Fixed version format (#4042)
- Loading branch information
Ajay Kumar Yadav
authored
Apr 17, 2017
1 parent
7f8cf1c
commit 519dede
Showing
15 changed files
with
4,359 additions
and
0 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
Tasks/PackageDownloader/Strings/resources.resjson/en-US/resources.resjson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"loc.friendlyName": "Package Downloader", | ||
"loc.helpMarkDown": "Needs Package Management extension to be installed", | ||
"loc.description": "Download package from Package Management on Visual Studio Team Services.", | ||
"loc.instanceNameFormat": "Download Package", | ||
"loc.input.label.feed": "Feed (package source)", | ||
"loc.input.help.feed": "Select the package source", | ||
"loc.input.label.definition": "Package to download", | ||
"loc.input.help.definition": "Select the package to download, only nuget packages are supported currently", | ||
"loc.input.label.version": "Version to download", | ||
"loc.input.help.version": "Version of the package", | ||
"loc.input.label.downloadPath": "Destination directory", | ||
"loc.input.help.downloadPath": "Path on the agent machine where the package will be downloaded", | ||
"loc.messages.FailedToGetPackageMetadata": "Failed to get package metadata with error {0}", | ||
"loc.messages.FailedToDownloadNugetPackage": "Failed to download NuGet package from {0} got the following error: {1}", | ||
"loc.messages.PackageDownloadSuccessful": "Package download successful", | ||
"loc.messages.CredentialsNotFound": "Could not determine credentials to connect to Package Management service.", | ||
"loc.messages.StartingDownloadOfPackage": "Starting download of NuGet package {0} to location {1}", | ||
"loc.messages.ExtractingNugetPackage": "Extracting NuGet package {0} to directory {1}", | ||
"loc.messages.PackageTypeNotSupported": "Only NuGet packages types can be downloaded using this task.", | ||
"loc.messages.ExtractionFailed": "Failed to extract package with error {0}" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
var fs = require('fs'); | ||
var http = require('http'); | ||
var DecompressZip = require('decompress-zip'); | ||
var path = require('path') | ||
|
||
import * as corem from 'vso-node-api/CoreApi'; | ||
import * as restm from 'vso-node-api/RestClient'; | ||
import * as tl from 'vsts-task-lib/task'; | ||
import * as vsom from 'vso-node-api/VsoClient'; | ||
import * as vsts from "vso-node-api/WebApi" | ||
|
||
const ApiVersion = "3.0-preview.1"; | ||
|
||
async function main(): Promise<void> { | ||
let feedId = tl.getInput("feed"); | ||
let packageId = tl.getInput("definition"); | ||
let version = tl.getInput("version"); | ||
let downloadPath = tl.getInput("downloadPath"); | ||
let collectionUrl = tl.getVariable("System.TeamFoundationCollectionUri"); | ||
|
||
var accessToken = getAuthToken(); | ||
var credentialHandler = vsts.getBearerHandler(accessToken); | ||
var vssConnection = new vsts.WebApi(collectionUrl, credentialHandler); | ||
var coreApi = vssConnection.getCoreApi(); | ||
|
||
await downloadPackage(coreApi, feedId, packageId, version, downloadPath); | ||
} | ||
|
||
function getAuthToken() { | ||
var auth = tl.getEndpointAuthorization('SYSTEMVSSCONNECTION', false); | ||
if (auth.scheme.toLowerCase() === 'oauth') { | ||
return auth.parameters['AccessToken']; | ||
} | ||
else { | ||
throw new Error(tl.loc("CredentialsNotFound")) | ||
} | ||
} | ||
|
||
export async function downloadPackage(coreApi: corem.ICoreApi, feedId: string, packageId: string, version: string, downloadPath: string) { | ||
var packageUrl = await getNuGetPackageUrl(coreApi.vsoClient, feedId, packageId); | ||
|
||
await new Promise((resolve, reject) => { | ||
coreApi.restClient.get(packageUrl, ApiVersion, null, { responseIsCollection: false }, async function (error, status, result) { | ||
if (!!error && status != 200) { | ||
reject(tl.loc("FailedToGetPackageMetadata", error)); | ||
} | ||
|
||
var packageType = result.protocolType.toLowerCase(); | ||
var packageName = result.name; | ||
|
||
if (packageType == "nuget") { | ||
var downloadUrl = await getDownloadUrl(coreApi.vsoClient, feedId, packageName, version); | ||
|
||
if (!tl.exist(downloadPath)) { | ||
tl.mkdirP(downloadPath); | ||
} | ||
|
||
var zipLocation = path.resolve(downloadPath, "/../", packageName) + ".zip"; | ||
var unzipLocation = path.join(downloadPath, ""); | ||
|
||
console.log(tl.loc("StartingDownloadOfPackage", packageName, zipLocation)); | ||
await downloadNugetPackage(coreApi, downloadUrl, zipLocation); | ||
console.log(tl.loc("ExtractingNugetPackage", packageName, unzipLocation)); | ||
await unzip(zipLocation, unzipLocation); | ||
|
||
if (tl.exist(zipLocation)) { | ||
tl.rmRF(zipLocation, false); | ||
} | ||
|
||
resolve(); | ||
} | ||
else { | ||
reject(tl.loc("PackageTypeNotSupported")); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
export async function getNuGetPackageUrl(vsoClient: vsom.VsoClient, feedId: string, packageId: string): Promise<string> { | ||
var PackagingAreaName = "Packaging"; | ||
var PackageAreaId = "7A20D846-C929-4ACC-9EA2-0D5A7DF1B197"; | ||
|
||
var data = await vsoClient.getVersioningData(ApiVersion, PackagingAreaName, PackageAreaId, { feedId: feedId, packageId: packageId }); | ||
|
||
return data.requestUrl; | ||
} | ||
|
||
export async function getDownloadUrl(vsoClient: vsom.VsoClient, feedId: string, packageName: string, version: string): Promise<string> { | ||
var NugetArea = "NuGet" | ||
var PackageVersionContentResourceId = "6EA81B8C-7386-490B-A71F-6CF23C80B388" | ||
|
||
var data = await vsoClient.getVersioningData(ApiVersion, NugetArea, PackageVersionContentResourceId, { feedId: feedId, packageName: packageName, packageVersion: version }); | ||
|
||
return data.requestUrl; | ||
} | ||
|
||
export async function downloadNugetPackage(coreApi: corem.ICoreApi, downloadUrl: string, downloadPath: string): Promise<void> { | ||
var file = fs.createWriteStream(downloadPath); | ||
await new Promise<void>((resolve, reject) => { | ||
var accept = coreApi.restClient.createAcceptHeader("application/zip", ApiVersion); | ||
coreApi.restClient.httpClient.getStream(downloadUrl, accept, function (error, status, result) { | ||
tl.debug("Downloading package from url: " + downloadUrl); | ||
tl.debug("Download status: " + status); | ||
if (!!error && status != 200) { | ||
reject(tl.loc("FailedToDownloadNugetPackage", downloadUrl, error)); | ||
} | ||
|
||
result.pipe(file); | ||
result.on("end", () => { | ||
console.log(tl.loc("PackageDownloadSuccessful")); | ||
resolve(); | ||
}); | ||
result.on("error", err => { | ||
reject(tl.loc("FailedToDownloadNugetPackage", downloadUrl, err)); | ||
}); | ||
}); | ||
}); | ||
|
||
file.end(null, null, file.close); | ||
} | ||
|
||
export async function unzip(zipLocation: string, unzipLocation: string): Promise<void> { | ||
|
||
await new Promise<void>(function (resolve, reject) { | ||
if (tl.exist(unzipLocation)) { | ||
tl.rmRF(unzipLocation, false); | ||
} | ||
|
||
tl.debug('Extracting ' + zipLocation + ' to ' + unzipLocation); | ||
|
||
var unzipper = new DecompressZip(zipLocation); | ||
unzipper.on('error', err => { | ||
reject(tl.loc("ExtractionFailed", err)) | ||
}); | ||
unzipper.on('extract', log => { | ||
tl.debug('Extracted ' + zipLocation + ' to ' + unzipLocation + ' successfully'); | ||
resolve(); | ||
}); | ||
|
||
unzipper.extract({ | ||
path: unzipLocation | ||
}); | ||
}); | ||
} | ||
|
||
main() | ||
.then((result) => tl.setResult(tl.TaskResult.Succeeded, "")) | ||
.catch((error) => tl.setResult(tl.TaskResult.Failed, error)); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "packagedownloader", | ||
"version": "1.0.0", | ||
"description": "Package Downloader Task", | ||
"main": "downloadPackages.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Microsoft/vsts-tasks.git" | ||
}, | ||
"author": "Microsoft Corporation", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/Microsoft/vsts-tasks/issues" | ||
}, | ||
"homepage": "https://github.com/Microsoft/vsts-tasks#readme", | ||
"dependencies": { | ||
"vsts-task-lib": "^0.9.20", | ||
"vso-node-api": "6.0.1-preview", | ||
"decompress-zip": "0.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
{ | ||
"id": "8d6e8f7e-267d-442d-8c92-1f586864c62f", | ||
"name": "PackageDownloader", | ||
"friendlyName": "Package Downloader", | ||
"description": "Download package from Package Management on Visual Studio Team Services.", | ||
"helpMarkDown": "Needs Package Management extension to be installed", | ||
"category": "Utility", | ||
"visibility": [ | ||
"Build", | ||
"Release" | ||
], | ||
"author": "ms-vscs-rm", | ||
"version": { | ||
"Major": 0, | ||
"Minor": 1, | ||
"Patch": 0 | ||
}, | ||
"demands": [], | ||
"minimumAgentVersion": "1.99.0", | ||
"inputs": [ | ||
{ | ||
"name": "feed", | ||
"type": "pickList", | ||
"label": "Feed (package source)", | ||
"defaultValue": "", | ||
"required": true, | ||
"properties": { | ||
"EditableOptions": "True" | ||
}, | ||
"helpMarkDown": "Select the package source" | ||
}, | ||
{ | ||
"name": "definition", | ||
"type": "pickList", | ||
"label": "Package to download", | ||
"defaultValue": "", | ||
"required": true, | ||
"properties": { | ||
"EditableOptions": "True" | ||
}, | ||
"helpMarkDown": "Select the package to download, only nuget packages are supported currently" | ||
}, | ||
{ | ||
"name": "version", | ||
"type": "pickList", | ||
"label": "Version to download", | ||
"defaultValue": "", | ||
"required": true, | ||
"properties": { | ||
"EditableOptions": "True" | ||
}, | ||
"helpMarkDown": "Version of the package" | ||
}, | ||
{ | ||
"name": "downloadPath", | ||
"type": "string", | ||
"label": "Destination directory", | ||
"defaultValue": "$(System.ArtifactsDirectory)", | ||
"required": true, | ||
"helpMarkDown": "Path on the agent machine where the package will be downloaded" | ||
} | ||
], | ||
"dataSourceBindings": [ | ||
{ | ||
"target": "feed", | ||
"endpointId": "tfs:feed", | ||
"endpointUrl": "{{endpoint.url}}/_apis/packaging/feeds", | ||
"resultSelector": "jsonpath:$.value[*]", | ||
"resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{name}}}\" }" | ||
}, | ||
{ | ||
"target": "definition", | ||
"endpointId": "tfs:feed", | ||
"parameters": { | ||
"feed": "$(feed)" | ||
}, | ||
"endpointUrl": "{{endpoint.url}}/_apis/Packaging/Feeds/{{{feed}}}/Packages?includeUrls=false", | ||
"resultSelector": "jsonpath:$.value[?(@.protocolType=='NuGet')]", | ||
"resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{name}}}\" }" | ||
}, | ||
{ | ||
"target": "version", | ||
"endpointId": "tfs:feed", | ||
"parameters": { | ||
"feed": "$(feed)", | ||
"definition": "$(definition)" | ||
}, | ||
"endpointUrl": "{{endpoint.url}}/_apis/Packaging/Feeds/{{{feed}}}/Packages/{{{definition}}}/Versions?includeUrls=false", | ||
"resultSelector": "jsonpath:$.value[*]", | ||
"resultTemplate": "{ \"Value\" : \"{{{version}}}\", \"DisplayValue\" : \"{{{version}}}\" }" | ||
} | ||
], | ||
"instanceNameFormat": "Download Package", | ||
"execution": { | ||
"Node": { | ||
"target": "download.js", | ||
"argumentFormat": "" | ||
} | ||
}, | ||
"messages": { | ||
"FailedToGetPackageMetadata": "Failed to get package metadata with error {0}", | ||
"FailedToDownloadNugetPackage": "Failed to download NuGet package from {0} got the following error: {1}", | ||
"PackageDownloadSuccessful": "Package download successful", | ||
"CredentialsNotFound": "Could not determine credentials to connect to Package Management service.", | ||
"StartingDownloadOfPackage": "Starting download of NuGet package {0} to location {1}", | ||
"ExtractingNugetPackage": "Extracting NuGet package {0} to directory {1}", | ||
"PackageTypeNotSupported": "Only NuGet packages types can be downloaded using this task.", | ||
"ExtractionFailed": "Failed to extract package with error {0}" | ||
} | ||
} |
Oops, something went wrong.