从托管的Team Foundation Service下载构建删除

idl*_*ind 2 build-automation continuous-integration continuous-deployment azure-devops

在tfs.visualstudio.com上使用托管的Team Foundation Service,可以在构建定义中选择"将构建输出复制到服务器",这将创建drop文件夹的zip,可以通过团队Web访问通过https下载.我真的需要自动下载这个drop,所以我可以将输入链接到我的构建管道中的下一个阶段.

不幸的是,丢弃URL并不明显,但可以使用TfsDropDownloader创建.

TL; DR - 我无法让TfsDropDownloader工作,我希望其他人使用此工具或类似的方法从https://tfs.visualstudio.com成功下载drop

使用命令行TfsDropDownloader.exe我可以这样做:

TfsDropDownloader.exe /c:"https://MYPROJECTNAME.visualstudio.com/DefaultCollection" /t:"ProjectName" /b:"BuildDefinitionName" /u:username /p:password
Run Code Online (Sandbox Code Playgroud)

...获取一个空的zip文件,其中包含上一次成功构建的正确构建标签名称,例如BuildDefinitionName_20130611.1.zip

在调试器中运行源代码,这是因为为下载而生成的URL:

https://tflonline.visualstudio.com/DefaultCollection/_apis/resources/containers/804/drop/BuildDefinitionName_20130611.1.zip
Run Code Online (Sandbox Code Playgroud)

..返回不受支持的application/json的内容类型.应用程序吞下此异常,但在创建空zip文件之前不会.

Team Foundation Service上的REST API是否可能以某种方式更改,因此生成的URL不再正确?

请注意,我使用的是我的Team Foundation Service帐户中定义的"备用凭据"(即不是我的实时ID) - 使用其他任何内容都可以获取TF30063:未经授权.

idl*_*ind 6

我通过使用备用凭据来实现它,但我还必须通过不同的路径访问REST API.

当前的TfsDropDownloader构建一个如下所示的URL:

https://project.visualstudio.com/DefaultCollection/_apis/resources/containers/804/drop/BuildDefinitionName_20130611.1.zip
Run Code Online (Sandbox Code Playgroud)

每当我尝试使用它时,它都会返回空的JSON.我肯定是经过身份验证的,因为如果我将URL调整为:

https://project.visualstudio.com/DefaultCollection/_apis/resources/containers/804/drop
Run Code Online (Sandbox Code Playgroud)

我得到了一个漂亮的JSON列表,其中包含drop中的每个文件,但没有zip.

从使用Fiddler 监视SSL流量到https://tfs.visualstudio.com我看到点击"下载drop as zip"链接我可以看到有另一个端点:

https://project.visualstudio.com/DefaultCollection/ProjectName/_api/_build/ItemContent?buildUri=vstfs%3a%2f%2f%2fBuild%2fBuild%2f639&path=%2Fdrop
Run Code Online (Sandbox Code Playgroud)

...它确实给你一个拉链."vstfs%3a%2f%2f%2fBuild%2fBuild%2f639"部分是URL编码的BuildUri.

所以我在TfsDropDownloader源代码中更改了我的GetServerPath版本来执行此操作:

private static string GetServerPath(TfsConnection collection, IBuildDetail buildDetail)
{
    var downloadPath = string.Format("{0}{1}/_api/_build/ItemContent?buildUri={2}&path=%2Fdrop",
                                            collection.Uri, 
                                            HttpUtility.UrlPathEncode(buildDetail.TeamProject), 
                                            HttpUtility.UrlEncode(buildDetail.Uri.ToString()));

    return downloadPath;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说暂时有用.希望这可以帮助其他人同样的问题!