如何在自定义工作流活动中获取构建详细信息?

时间:2011-05-31 13:24:28

标签: c# build tfs2010

我需要将自定义活动添加到默认工作流模板,以便在构建过程中尽可能早地增加程序集版本。

我想要实现的是在我的自定义活动中创建并映射完全相同的工作区(在工作流中进一步创建),以便我可以检出xml文件,增加其中的版本号,将其写回xml文件并重新检入xml文件。

我知道这个工作区将在以后的工作流程中创建,但是在构建过程中为了实现我想要实现的目标已经太晚了,所以不要移动任何活动或将它们复制到位于我的自定义活动之上(这应该没问题,因为此工作区将被删除并在以后再次重新创建)

我认为我需要的细节是BuildDirectory,WorkspaceName和SourcesDirectory。谁能告诉我如何实现工作区的创建或如何在代码中获取这些数据?

构建将在构建服务器上执行,我正在使用TFS 2010和c#。

提前致谢

1 个答案:

答案 0 :(得分:3)

我按照Ewald Hofman的一系列博客文章作为入门读物,并创建了一个自定义活动,用于检查我解析当前版本的GlobalAssemblyInfo文件的检出,更新和签入。我的任务被插入“更新放置位置”的顶部,这是在它完成工作流的“获取构建”部分之后。我只需要使用IBuildDetail和File Mask作为参数,您可以从中提取VersionControlServer以便能够访问TFS。我的代码如下:

protected override string Execute(CodeActivityContext context)
    {
        // Obtain the runtime value of the input arguments.
        string assemblyInfoFileMask = context.GetValue(AssemblyInfoFileMask);
        IBuildDetail buildDetail = context.GetValue(BuildDetail);

        var workspace = buildDetail.BuildDefinition.Workspace;
        var versionControl = buildDetail.BuildServer.TeamProjectCollection.GetService<VersionControlServer>();

        Regex regex = new Regex(AttributeKey + VersionRegex);

        // Iterate of the folder mappings in the workspace and find the AssemblyInfo files 
        // that match the mask.
        foreach (var folder in workspace.Mappings)
        {
            string path = Path.Combine(folder.ServerItem, assemblyInfoFileMask);
            context.TrackBuildMessage(string.Format("Checking for file: {0}", path));
            ItemSet itemSet = versionControl.GetItems(path, RecursionType.Full);

            foreach (Item item in itemSet.Items)
            {
                context.TrackBuildMessage(string.Format("Download {0}", item.ServerItem));
                string localFile = Path.GetTempFileName();

                try
                {
                    // Download the file and try to extract the version.
                    item.DownloadFile(localFile);
                    string text = File.ReadAllText(localFile);
                    Match match = regex.Match(text);

                    if (match.Success)
                    {
                        string versionNumber = match.Value.Substring(AttributeKey.Length + 2, match.Value.Length - AttributeKey.Length - 4);
                        Version version = new Version(versionNumber);
                        Version newVersion = new Version(version.Major, version.Minor, version.Build + 1, version.Revision);

                        context.TrackBuildMessage(string.Format("Version found {0}", newVersion));

                        return newVersion.ToString();
                    }
                }
                finally
                {
                    File.Delete(localFile);
                }
            }
        }

        return null;
    }