TFS Build 2.0 C#,如何将变量添加到 build/Pass Msbuild args

TFS Build 2.0 C#, howto add variables to the build/Pass Msbuild args

我正在尝试将参数传递给 MSBuild 2.0。经过研究,我似乎需要使用变量来执行此操作,但我无法弄清楚如何将其合并到下面的队列请求中。我试过参数,但这似乎不起作用。这是我想告诉 MSBuild @" /p:OctoPackPackageVersion=" + releaseNumber.这适用于使用 IBuildRequest.ProcessParameters 的 XAML 构建。

var buildClient = new BuildHttpClient(new Uri(collectionURL), new 
VssCredentials(true));
var res = await buildClient.QueueBuildAsync(new Build
            {
                Definition = new DefinitionReference
                {
                    Id = targetBuild.Id
                },
                Project = targetBuild.Project,
                SourceVersion = ChangeSetNumber,
                Parameters = buildArg

            });
            return res.Id.ToString();

首先,TFS2015 上的新构建称为 vNext 构建,而不是 MSbuild 2.0。

您要找的应该是Build variables。变量为您提供了一种将关键数据位放入构建过程的各个部分的便捷方法。对于勾选了 Allow at queue time 框的变量,您可以启用允许您的团队在他们手动排队构建时修改值。

一些教程可能对使用变量有帮助:

Patrick,我能够通过更新构建定义找到解决我的问题的方法。这绝对不理想,但它确实有效。正如您在下面看到的,我正在尝试添加到已经存在的 msbuild args 中。如果您知道更好的方法,请告诉我。非常感谢您花时间看我的问题。

 public static async Task<string> QueueNewBuild(string project, BuildDefinitionReference targetBuild, string collectionURL, string ChangeSetNumber, string ReleaseNumber, bool CreateRelease)
    {
        var buildClient = new BuildHttpClient(new Uri(collectionURL), new VssCredentials(true));
        await Task.Delay(1000).ConfigureAwait(false);
        var buildDef = await buildClient.GetDefinitionAsync(targetBuild.Project.Id, targetBuild.Id);
        BuildDefinitionVariable OrigMSbuildvar = buildDef.Variables["MSBuildArgs"];
        buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value + " /p:OctoPackPackageVersion=" + ReleaseNumber.ToString();

        await Task.Delay(1000).ConfigureAwait(false);
        buildDef = await buildClient.UpdateDefinitionAsync(buildDef);

        await Task.Delay(1000).ConfigureAwait(false);
        Build build = new Build
        {
            Definition = new DefinitionReference
            {
                Id = targetBuild.Id
            },
            Project = targetBuild.Project,
            SourceVersion = ChangeSetNumber
        };

        await Task.Delay(1000).ConfigureAwait(false);
        var res = await buildClient.QueueBuildAsync(build);
        buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value;           
        await Task.Delay(1000).ConfigureAwait(false);
        buildDef = await buildClient.UpdateDefinitionAsync(buildDef);
        return res.Id.ToString();

    }

vNext 构建系统与遗留 XAML 构建系统不同,您不能在构建队列中直接将变量传递给构建定义中的构建任务。您使用的代码在对构建进行排队之前更新了构建定义,这意味着如果变量发生变化,构建定义可能会不断变化。

解决方法是在构建定义中添加一个变量,例如 "var1",然后将此变量用作 MSBuild 任务的参数: 这样,您就可以在构建队列时将值传递给 "var1" 变量,而无需更新构建定义。

Build build = new Build();
build.Parameters = "{\"var1\":\"/p:OctoPackPackageVersion=version2\"}";

// OR using Newtonsoft.Json.JsonConvert
var dict = new Dictionary<string, string>{{"var1", "/p:OctoPackPackageVersion=version2"}};
build.Parameters = JsonConvert.SerializeObject(dict)

我找到了这个解决方案,它非常适合我。为了方便构建定义,我设置了自定义参数而无需在服务器上更新:

foreach (var variable in targetBuildDef.Variables.Where(p => p.Value.AllowOverride))
        {
            var customVar = variables.FirstOrDefault(p => p.Key == variable.Key);
            if (customVar == null)
                continue;
            variable.Value.Value = customVar.Value.TrimEnd('\');
        }

然后在构建参数中设置变量值:

        using (TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(tFSCollectionUri)))
        {
            using (BuildHttpClient buildServer = ttpc.GetClient<BuildHttpClient>())
            {
                var requestedBuild = new Build
                {
                    Definition = targetBuildDef,
                    Project = targetBuildDef.Project
                };
                var dic = targetBuildDef.Variables.Where(z => z.Value.AllowOverride).Select(x => new KeyValuePair<string, string>(x.Key, x.Value.Value));
                var paramString = $"{{{string.Join(",", dic.Select(p => $@"""{p.Key}"":""{p.Value}"""))}}}";
                var jsonParams = HttpUtility.JavaScriptStringEncode(paramString).Replace(@"\""", @"""");
                requestedBuild.Parameters = jsonParams;
                var queuedBuild = buildServer.QueueBuildAsync(requestedBuild).Result;