TFS实现持续集成

最近在项目总做了一个小的应用,帮助项目实现持续集成。

在这个持续集成中,用了一些TFS的API,自动生成新版本,并且调用加密程序对二进制文件进行加密,根据开发者的变更自动生成ReadMe,然后发送邮件给测试人员。大概分下面几步。
1.连接TFS 
2.建立Map关系
3.生成Readme
4.取得最新代码
5.对bin和md去掉只读属性
6.讲md拷贝到bin下面
7.编译
8.加密
9.将加密后的文件放到目标路径
10.删除所有pdb文件
11.去掉只读属性
12.写版本号

1.连接TFS

tfs = new TfsTeamProjectCollection(
                        new Uri(InitInfo.ServerUrl),
                        new NetworkCredential(InitInfo.LoginName, InitInfo.Password));

 

2.建立Map关系

versionControlServer = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
workspace = versionControlServer.TryGetWorkspace(InitInfo.LocalFolder); if (workspace == null) { workspace = versionControlServer.CreateWorkspace(InitInfo.Workspace, (tfs.Credentials as NetworkCredential).UserName); } else { workspace = versionControlServer.GetWorkspace(InitInfo.Workspace, InitInfo.WorkspaceOwner); } workspace.Map("$/" + InitInfo.ProjectName, InitInfo.LocalFolder);

 

3.生成Readme

生成ReadMe一共分三种

(1)根据代码关联到的Task或者Bug生成ReadMe

VersionControlServer versionControlServer = (VersionControlServer)this.tfs.GetService(typeof(VersionControlServer));

                if (versionControlServer == null)
                {
                    CommentToReadme.ErrInfo = "获取不到VersionControlServer";

                    return;
                }

                var histroies = versionControlServer.QueryHistory(
                    InitInfo.LocalFolder,
                    VersionSpec.Latest,
                    0,
                    RecursionType.Full,
                    null,
                    null,
                    null,
                    Int32.MaxValue,
                    true,
                    false,
                    true);

                foreach (Changeset pChangeset in histroies)
                {
                    if (!this.dicErrInfo.ContainsKey(pChangeset.Committer))
                    {
                        this.dicErrInfo.Add(pChangeset.Committer, new List<string>());
                    }
                    if (!this.dicWorkItemsTitle.ContainsKey(pChangeset.Committer))
                    {
                        this.dicWorkItemsTitle.Add(pChangeset.Committer, new List<string>());
                    }

                    if (!pChangeset.CreationDate.ToShortDateString().Equals
                        (System.DateTime.Now.AddDays(-1).ToShortDateString()))
                    {
                        continue;
                    }

                    WorkItem[] workItems = pChangeset.WorkItems;

                    if (workItems.Length != 0)
                    {
                        for (int index = 0; index < workItems.Length; index++)
                        {
                            this.dicWorkItemsTitle[pChangeset.Committer].Add(workItems[index].Title);
                        }
                    }
                    else
                    {
                        Change[] changes = pChangeset.Changes;

                        if (changes.Length != 0)
                        {
                            for (int index = 0; index < changes.Length; index++)
                            {
                                this.dicErrInfo[pChangeset.Committer].Add(changes[index].Item.CheckinDate + ":" + changes[index].Item.ServerItem);
                            }
                        }
                    }
                }
            }

 

(2)根据开发者自己写的Comment生成ReadMe

(3)根据Bug或者Task的状态生成ReadMe

var service = tfs.GetService<WorkItemStore>();

                if (service == null)
                {
                    CommentToReadme.ErrInfo = "获取不到service";

                    return;
                }

                for (int index = 0; index < InitInfo.Developers.Count; index++)
                {
                    if (!this.dicResolvedBugs.ContainsKey(InitInfo.Developers[index].Name))
                    {
                        this.dicResolvedBugs.Add(InitInfo.Developers[index].Name, new List<Bug>());
                    }
                }

                for (int i = 0; i < InitInfo.Developers.Count; i++)
                {
                    string developName = InitInfo.Developers[i].Name;

                    DateTime dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                    DateTime dtQuery = dt.AddDays(-1);

                    string query = string.Format("Select * From WorkItems " +
                                                "Where [Work Item Type] = 'Bug' " +
                                                "AND ([State] = 'Resolved' OR [State] = 'Closed') " +
                                                "AND [Resolved by] = '{0}' " +
                                                "AND [Resolved Date] >= '{1}'", developName, dtQuery);
                    WorkItemCollection wc = service.Query(query);

                    for (int j = 0; j < wc.Count; j++)
                    {
                        Bug tempBug;
                        tempBug.id = wc[j].Id;
                        tempBug.title = wc[j].Title;
                        this.dicResolvedBugs[developName].Add(tempBug);
                    }
                }

4.取得最新代码

versionControlServer.DeleteWorkspace(InitInfo.Workspace, (tfs.Credentials as NetworkCredential).UserName);

                Workspace ws = versionControlServer.CreateWorkspace(InitInfo.Workspace,
                    (tfs.Credentials as NetworkCredential).UserName);
                ws.Map("$/" + InitInfo.ProjectName, InitInfo.LocalFolder);

                string item = "$/" + InitInfo.ProjectName;
                GetStatus s1 = ws.Get(new GetRequest(new ItemSpec(item,
                    RecursionType.Full), VersionSpec.Latest
                    ), GetOptions.GetAll | GetOptions.Overwrite);

                return 0;

5,6两步略过

7.编译

if (SourceXml == null)
                SourceXml = new XmlDocument();
            SourceXml.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"buildsort.xml"));
            XmlNodeList list = SourceXml.SelectNodes("/Projects/Project");

            int SuccessCount = 0;
            int FailCount = 0;
            int PCount = 0;
            
            foreach (XmlNode node in list)
            {
                string Args = localFolder + @"\source\" + node.Attributes["Name"].Value + @"\" + node.Attributes["Name"].Value + ".csproj";
                
                //Thread th = new Thread(() =>
                //{
                    Process p = new Process();

                    p.StartInfo = new ProcessStartInfo();
                    p.StartInfo.FileName = buildToolUrl;

                    p.StartInfo.Arguments = Args + " /t:Rebuild";

                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.CreateNoWindow = true;
                    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    try
                    {
                        p.Start();
                        PCount += 1;
                        while (!p.StandardOutput.EndOfStream)
                        {
                            string line = p.StandardOutput.ReadLine();

                            if (line.Trim().Length != 0)
                            {
                                Console.WriteLine(line + Environment.NewLine);
                                if (line.Contains("已成功生成") || line.Contains("Build succeeded"))
                                {
                                    SuccessCount += 1;
                                    Debug.WriteLine("成功" + SuccessCount);

                                    Console.WriteLine("正在编译第" + "【" + PCount + "/" + list.Count + "】个项目," + "成功【" + SuccessCount + "】" + "失败【" + FailCount + "】" + Environment.NewLine);

                                }
                                if (line.Contains("生成失败") || line.Contains("Build FAILED"))
                                {
                                    FailCount += 1;
                                    Debug.WriteLine("失败" + FailCount);

                                    Console.WriteLine("正在编译第" + "【" + PCount + "/" + list.Count + "】个项目," + "成功【" + SuccessCount + "】" + "失败【" + FailCount + "】" + Environment.NewLine);
                                }
                            }


                        }

                        p.WaitForExit();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        p = null;
                        if (PCount == list.Count)
                            buildFlag = true;
                       
                    }


                //});
                //th.Start();

            }

其余的也没啥可说的了,终点是TFS的API,真是个好东西,我掌握的也不多,希望大家多多指点

转载于:https://www.cnblogs.com/liangdiamond/archive/2012/09/21/2697086.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值