Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DownloadBuildArtifact: FileContainer #4521

Merged
merged 4 commits into from
Jun 16, 2017

Conversation

scottdallamura
Copy link
Contributor

No description provided.

"version": {
"Major": 0,
"Minor": 1,
"Patch": 48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we start from 0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but why patch level 48?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was iterating. Does it matter where we start it? I can bump it down to 0.0.1 if it's really important.

"name": "downloadPath",
"type": "string",
"label": "Destination directory",
"defaultValue": "$(System.ArtifactsDirectory)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RM extension in the agent doesn't set this variable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems like a bug. It is a System.* variable. It also seems problematic to hope all extensions set something like that. Shouldn't the agent just set it since it's a system level thing? The agent should define the a dir then RM extension should respect and use it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should definately default to this though

"version": {
"Major": 0,
"Minor": 1,
"Patch": 47
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this one is 47 the task.json has 48. :D

});
}
catch (err) {
downloadReject(err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to know which file failed?

// pipe the content to the target
contentStream.pipe(outputStream);
contentStream.on('end', () => {
tl.debug(`Downloaded ${item.relativePath} to ${outputFilename}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider: removing outputfilename from this statment might reduce noise.

createdFolders[folder] = true;
}

tl.debug(`Downloading ${item.relativePath} to ${outputFilename}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of debug, this should probably localized and console.log so there feedback to the web console.

Also consider wrapping the path single quotes to enable easier diagnosing for weirdo trailing space issue or something like that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note, i didnt see any non-verbose output anywhere else, but i could have missed something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

artifact and file level should be info. we might also want to info out course grained % - like every 10% - but probably only if file count > 10?? Granular file level details should be debug.


// ignore folders
items = items.filter(item => item.itemType === ContainerItemType.File);
tl.debug(`Found ${items.length} File items in #/${containerId}/${containerPath}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File is capitalized (intentional?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, intentional, as I'm referring to the itemType value. Items are "File" or "Folder", IIRC. Although I suppose that value isn't relevant to your average build watcher...

resolve(itemResponse.result);
}
else {
// TODO: decide whether to retry or bail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forget about this todo? or will this land in a future PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future PR. I need to evaluate the different ways things might fail, and a retry strategy.

}

main()
.then((result) => tl.setResult(tl.TaskResult.Succeeded, ""))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a \t? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


// get the artifact metadata
let buildApi = vssConnection.getBuildApi();
let artifact = await buildApi.getArtifact(buildId, artifactName, projectId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, it looks like we will be able to plug in fileshare easily.

i'm curious what your thoughts are about setting variables. can discuss offline.

"description": "Download a build artifact.",
"helpMarkDown": "",
"category": "Utility",
"author": "Microsoft Corporation",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preview: true

],
"dataSourceBindings": [
],
"instanceNameFormat": "Download Build Artifact",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't artifact name get formatted into this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call.

}

main()
.then((result) => tl.setResult(tl.TaskResult.Succeeded, ""))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not wrap main function in a try / catch or wrap main() call in try catch? I'm trying to push a linear C# coding paradigm and avoid .then code unless we have to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copypasta. Sure.


async function main(): Promise<void> {
let projectId = tl.getVariable('System.TeamProjectId');
let buildId = parseInt(tl.getInput("buildId"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does user get a nice actionable message if not an int?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course if not supplied no message but if supplied and I give it string is it silently ignored or does user get actionable error and failure?

let downloadPath = tl.getPathInput("downloadPath");

let accessToken = getAuthToken();
let credentialHandler = getBearerHandler(accessToken);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run this task locally interactively to test / debug?

In the step by step I encourage that:
https://github.com/Microsoft/vsts-task-lib/blob/master/node/docs/stepbystep.md

In order to pull it off, I have to support a pat (interactive) or bearer (run in a job).

See here. Let me know if you have any better ideas.

https://gist.github.com/bryanmacfarlane/154f14dd8cb11a71ef04b0c836e5be6e#file-vsts_sample-ts

@@ -0,0 +1,8 @@
{
"resolution": "main",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh - we want to get away from typings. Can you do npm install @types with this task? Please set the right pattern going forward. We already npm install if package.json exists so I think it should just work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's deprecated. I have an action item to back through our tasks 1:1. After I do that, I want to send as a pattern to other teams to do the same...

@bryanmacfarlane
Copy link
Contributor

before coming out of preview we should add UNC support (robocopy). Perhaps Eric should add that in since he's familiar with it on the publish side ...

@ericsciple

let contentStream = await downloader(item);

// create the target stream
let outputStream = fs.createWriteStream(outputFilename);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if the file exists?

what if the path exists as a directory, will this produce a weird non-intuitive error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the file exists, it is overwritten. if it's a folder and we're trying to write a file to it, on windows we get EISDIR: illegal operation on a directory, open 'e:\test\downloadbuildartifact\drop\ConsoleApplication1\bin\Release\ConsoleApplication1.pdb'

@scottdallamura scottdallamura force-pushed the users/scdallam/downloadbuildartifact branch from e8b0215 to 35a3481 Compare June 15, 2017 21:10
let artifact = await buildApi.getArtifact(buildId, artifactName, projectId);

let providers: ArtifactProvider[] = [
new FileContainerProvider()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want a fileshare provider that throws in the downloadArtifact method. I want an clear message that "File share artifacts are not yet supported in the early preview. Coming soon.". I don't want it to fall through and tell the customer file shares aren't supported (confusing and mixed message.

@scottdallamura scottdallamura merged commit f1f8906 into master Jun 16, 2017
@scottdallamura scottdallamura deleted the users/scdallam/downloadbuildartifact branch June 16, 2017 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants