Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Add DryRun option to RestoreCache (#27)
Browse files Browse the repository at this point in the history
* Add dry run flag

* Emit debug output

* Remove unused logging

* Add failing unit test for dryrun option

* Unit test new dryrun functionality

* Throw error if unable to parse collection uri for instance

* Remove unused logging
  • Loading branch information
ethanis authored Nov 12, 2019
1 parent eea2397 commit 7b16b67
Show file tree
Hide file tree
Showing 23 changed files with 869 additions and 106 deletions.
1 change: 0 additions & 1 deletion Tasks/Common/packaging-common/ArtifactToolRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export function runArtifactTool(artifactToolPath: string, command: string[], exe
return tl.execSync(artifactToolPath, command, execOptions);
} else {
fs.chmodSync(artifactToolPath, "755");

if (!execOptions.silent) {
execOptions.outStream.write(getCommandString(artifactToolPath, command) + os.EOL);
}
Expand Down
33 changes: 33 additions & 0 deletions Tasks/Common/packaging-common/Tests/FeedUtilityMockHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import tmrm = require("azure-pipelines-task-lib/mock-run");
import Axios from "axios";
import MockAdapter from "axios-mock-adapter";

export interface IMockResponse {
responseCode: number;
data?: any;
}

export function registerFeedUtilityMock(
tmr: tmrm.TaskMockRunner,
response: IMockResponse
) {
tmr.setInput("feedlist", "node-package-feed");
tmr.setInput("verbosity", "verbose");

process.env.BUILD_DEFINITIONNAME = "build definition";
process.env.AGENT_HOMEDIRECTORY = "/users/home/directory";
process.env.BUILD_SOURCESDIRECTORY = "/users/home/sources";
process.env.SYSTEM_SERVERTYPE = "hosted";
process.env.ENDPOINT_AUTH_SYSTEMVSSCONNECTION =
'{"parameters":{"AccessToken":"token"},"scheme":"OAuth"}';
process.env.ENDPOINT_URL_SYSTEMVSSCONNECTION =
"https://example.visualstudio.com/defaultcollection";
process.env.SYSTEM_DEFAULTWORKINGDIRECTORY = "/users/home/directory";
process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI =
"https://example.visualstudio.com/defaultcollection";

const mock = new MockAdapter(Axios);
console.log("mocking this out");

mock.onAny().reply(response.responseCode, response.data);
}
24 changes: 22 additions & 2 deletions Tasks/Common/packaging-common/cache/cacheUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import shell = require("shelljs");
import tl = require("azure-pipelines-task-lib/task");

import { UniversalPackages } from "./universalPackages";
import { doesPackageExist } from "./feedUtilities";
const universalPackages = new UniversalPackages();

const isWin = process.platform === "win32";
Expand Down Expand Up @@ -59,10 +60,27 @@ export class cacheUtilities {
tarballPath = "/" + tarballPath.replace(":", "").replace(/\\/g, "/");
}

const dryRun = tl.getBoolInput("dryRun", false);
const alias = tl.getInput("alias", false);

if (dryRun) {
try {
const packageExists = await doesPackageExist(hash);

const output =
alias && alias.length > 0 ? `CacheExists-${alias}` : "CacheExists";
tl.setVariable(output, packageExists ? "true" : "false");
tl.setVariable(hash, packageExists ? "true" : "false");
} catch (err) {
console.log(err);
}

return;
}

try {
const result = await universalPackages.download(hash, tmp_cache);

const alias = tl.getInput("alias", false);
const output =
alias && alias.length > 0 ? `CacheRestored-${alias}` : "CacheRestored";

Expand Down Expand Up @@ -145,7 +163,9 @@ export class cacheUtilities {
}

try {
const { stderr: error } = shell.exec(
const {
stderr: error
} = shell.exec(
`tar -C "${tarballParentDir}" -czf "${tarballPath}" ${targetFolders
.map(t => `\"${t}\"`)
.join(" ")}`,
Expand Down
58 changes: 58 additions & 0 deletions Tasks/Common/packaging-common/cache/feedUtilities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as pkgLocationUtils from "../locationUtilities";
import * as tl from "azure-pipelines-task-lib";
import Axios, { AxiosRequestConfig } from "axios";

interface IPackage {
id: string;
name: string;
version: string;
}

export async function doesPackageExist(hash: string): Promise<boolean> {
const feedId = tl.getInput("feedList");
// Getting package name from hash
const packageId = tl
.getVariable("Build.DefinitionName")
.replace(/\s/g, "")
.substring(0, 255)
.toLowerCase();

const version = `1.0.0-${hash}`;
const accessToken = pkgLocationUtils.getSystemAccessToken();
const collectionUri = process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI;

let instance: string = "";
const legacyRegex = /https:\/\/(\S+).visualstudio.com\S+/g;
const newRegex = /https:\/\/dev.azure.com\/(\S+)\//g;

const legacyUrl = legacyRegex.exec(collectionUri);
const newUrl = newRegex.exec(collectionUri);

if (legacyUrl) {
instance = legacyUrl[1];
} else if (newUrl) {
instance = newUrl[1];
} else {
throw `Unable to parse collection uri: '${collectionUri}'`;
}

const url = `https://pkgs.dev.azure.com/${instance}/_apis/packaging/feeds/${feedId}/upack/packages/${packageId}/versions/${version}?api-version=5.1-preview.1`;

const config: AxiosRequestConfig = {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
};
try {
const result = await Axios.get<IPackage>(url, config);

tl.debug(JSON.stringify(result.data));

return result.data.version === version;
} catch (err) {
tl.debug(err.toString());

return false;
}
}
2 changes: 1 addition & 1 deletion Tasks/Common/packaging-common/cache/universaldownload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export async function run(artifactToolPath: string, hash: string, targetFolder:
success: false,
};
}

return {
toolRan: true,
success: false,
Expand Down
113 changes: 113 additions & 0 deletions Tasks/Common/packaging-common/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Tasks/Common/packaging-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"@types/ltx": "^2.8.0",
"@types/node": "^11.13.0",
"adm-zip": "^0.4.11",
"axios": "^0.19.0",
"axios-mock-adapter": "^1.17.0",
"azure-devops-node-api": "^6.6.0",
"azure-pipelines-task-lib": "^2.8.0",
"azure-pipelines-tool-lib": "^0.12.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"loc.input.help.targetfolder": "The folder/file or wildcard of items to cache. For example, node projects can cache packages with '**/node_modules, !**/node_modules/**/node_modules'.",
"loc.input.label.feedList": "Feed",
"loc.input.label.platformIndependent": "Platform Independent?",
"loc.input.label.dryRun": "Dry run",
"loc.input.label.alias": "Cache alias",
"loc.input.label.verbosity": "Verbosity",
"loc.input.help.verbosity": "Specifies the amount of detail displayed in the output.",
Expand Down
Loading

0 comments on commit 7b16b67

Please sign in to comment.