Skip to content

Commit

Permalink
Porting PackageDownloader changes to M116 (#4046)
Browse files Browse the repository at this point in the history
* Download Package task

* Fixed version format (#4042)
  • Loading branch information
Ajay Kumar Yadav authored Apr 17, 2017
1 parent 7f8cf1c commit 519dede
Show file tree
Hide file tree
Showing 15 changed files with 4,359 additions and 0 deletions.
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}"
}
148 changes: 148 additions & 0 deletions Tasks/PackageDownloader/download.ts
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));
Binary file added Tasks/PackageDownloader/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions Tasks/PackageDownloader/package.json
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"
}
}
110 changes: 110 additions & 0 deletions Tasks/PackageDownloader/task.json
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}"
}
}
Loading

0 comments on commit 519dede

Please sign in to comment.