TFS рдореЗрдВ рдЕрдиреБрдХреНрд░рдо рдмрдирд╛рдПрдБ

рдирд┐рд░рдВрддрд░ рдПрдХреАрдХрд░рдг рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдЕрдХреНрд╕рд░ рдХреЗрд╡рд▓ рдПрдХ рдмрд┐рд▓реНрдб рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдмрд┐рд▓реНрдб рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

рдпрд╣ рд╕рдЪ рд╣реИ рдЬрдм рдЙрддреНрдкрд╛рдж рдХреЛрдб рдХреЛ рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╡реЗ рдПрдХ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛрддреЗ рд╣реИрдВред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдпрд╣ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдЯреАрдПрдлрдПрд╕ рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред



рдорд╛рди рд▓реАрдЬрд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╣реИрдВ, "рдЕрд╕реЗрдВрдмрд▓реА 1" рдФрд░ "рдЕрд╕реЗрдВрдмрд▓реА 2"ред
рджреЛ рдмрд┐рд▓реНрдб рдЕрд╕реЗрдВрдмрд▓реА 1 рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП рд╣реИрдВ: ClassLibrary1 рдФрд░ ClassLibrary2ред
рдЕрд╕реЗрдВрдмрд▓реА 2 рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рджреЛ рдмрд┐рд▓реНрдб рднреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП рд╣реИрдВ: A2.t2 рдФрд░ A2.t3ред

"ClassLibrary1" рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ "ClassLibrary2" рдФрд░ "A2.t2" рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

1. рдПрдХ рд╕рд░рд▓ рдФрд░ рдзреАрдорд╛ рддрд░реАрдХрд╛ (рд╣рдордиреЗ рдкрд╣рд▓реЗ рдпрд╣ рдХрд┐рдпрд╛ рдерд╛)ред

рд╣рдо "ClassLibrary2" рдФрд░ "A2.t2" рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ:

рд╣рдо рдЪреЗрдХ-рдЗрди рдореЗрдВ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВред



рдкрд┐рдЫрд▓реЗ рдмрд┐рд▓реНрдб рд╕реЗ рд╡рд░реНрдХрд┐рдВрдЧ рдлреЛрд▓реНрдбрд░ рдЬреЛрдбрд╝реЗрдВред



"A2.t2" рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдп рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ рд▓рд╛рдн рдПрдХ рд╣реИ - рдЖрдкрдХреЛ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдФрд░ рднреА рдиреБрдХрд╕рд╛рди рд╣реИрдВ:
- рдЕрдзрд┐рдХ "рдХрд╛рдо рдХрд░ рд░рд╣реЗ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред
- рдирд┐рд░реНрдорд╛рдг рдЕрдиреБрдХреНрд░рдо рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдЪреЗрдХ-рдЗрдиред
- рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдХреНрд░рдо рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд░рдо рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рд╣рдореЗрд╢рд╛ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ ClassLibrary2 рдпрд╛ A2.t2 рд╕реЗ рдкрд╣рд▓реЗ рдХреМрди рд╕рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

2. TFS API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

- рдПрдХ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ "ClassLibrary" рдмрдирд╛рдПрдВред
- рдПрдХ рдирдпрд╛ CodeActivity рддрддреНрд╡ рдЬреЛрдбрд╝реЗрдВред
- рджреЛ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдмрдирд╛рдПрдБ "BuildDetail" рдФрд░ "TfsProjectAndBuildDefinition", рдкрд╣рд▓рд╛ рдЬрд┐рд╕реЗ BuildServer рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рдирд┐рд░реНрдорд╛рдгреЛрдВ рдХреА рд╕реВрдЪреА рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВред
- рдЗрд╕ рд╕реВрдЪреА рдореЗрдВ рд▓рд╛рдЗрдиреЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдЙрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд╛рдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреА рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдирд╛рдо рдПрдХ рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдиреАрдЪреЗ рдХреЛрдб рд╣реИ:

using System; using System.Activities; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using Microsoft.TeamFoundation.Build.Client; using Microsoft.TeamFoundation.Build.Workflow.Activities; using Microsoft.TeamFoundation.Build.Workflow.Services; using Microsoft.TeamFoundation.Client; namespace QueueNewBuilds { [BuildActivity(HostEnvironmentOption.Agent)] public sealed class QueueNewBuild : CodeActivity { // The Team Project that the build definition belongs to. [RequiredArgument] public InArgument<IBuildDetail> BuildDetail { get; set; } [RequiredArgument] public InArgument<String[]> TfsProjectAndBuildDefinition { get; set; } protected override void Execute(CodeActivityContext context) { String[] dirty = context.GetValue(this.TfsProjectAndBuildDefinition); IBuildDetail buildDetail = context.GetValue(this.BuildDetail); var pds = Parse(dirty); //var workspace = buildDetail.BuildDefinition.Workspace; IBuildServer buildServer = buildDetail.BuildServer; foreach (var pd in pds) { try { string message = string.Format("Queue new build \"{0}\"-\"{1}\"", pd.TfsProject, pd.BuildDefinition); context.TrackBuildMessage(message); IBuildDefinition buildDef = buildServer.GetBuildDefinition(pd.TfsProject, pd.BuildDefinition); buildServer.QueueBuild(buildDef); } catch (Exception ex) { string message = string.Format("Queue new build error \"{0}\"-\"{1}\", Exception : \"{2}\"", pd.TfsProject, pd.BuildDefinition, ex.Message); context.TrackBuildWarning(message); } } } private IEnumerable<ProjectDefinition> Parse(string[] dirty) { if (dirty == null) yield break; foreach (var item in dirty) { var t = item.Split(';'); if (t.Length == 2) { ProjectDefinition pd = new ProjectDefinition(); pd.TfsProject = t[0].Trim(); pd.BuildDefinition = t[1].Trim(); yield return pd; } } } class ProjectDefinition { public string TfsProject { get; set; } public string BuildDefinition { get; set; } } } } 


рдЗрд╕ "рдЧрддрд┐рд╡рд┐рдзрд┐" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо "TfvcTemplate.12.xaml" рдХреА рдПрдХ рдкреНрд░рддрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ
рд╣рдо рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
рдПрдХ рдирдпрд╛ QueueNewBuild рддрд░реНрдХ, рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рдПрдВред



"рдПрдЬреЗрдВрдЯ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди" рдмреНрд▓реЙрдХ рдореЗрдВ рд╣рдо "IBuildDetail" рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡реИрд░рд┐рдПрдмрд▓ "buildDetail" рдмрдирд╛рддреЗ рд╣реИрдВред
"рдХреЛрд╢рд┐рд╢" рдмреНрд▓реЙрдХ рдХреЗ рдмрд╛рдж, "рдЧрддрд┐рд╡рд┐рдзрд┐" "GetBuildDetail" рдФрд░ "QueueNewBuild" рдЬреЛрдбрд╝реЗрдВред
"GetBuildDetail" рдмреНрд▓реЙрдХ рдореЗрдВ, "Result" рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ "buildDetail" рд╕реЗрдЯ рдХрд░реЗрдВред
QueueNewBuild рдмреНрд▓реЙрдХ рдореЗрдВ, BuildDetail рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдкрд┐рдЫрд▓реЗ рдЪрд░рдг рдореЗрдВ рдкреНрд░рд╛рдкреНрдд buildDetail рдорд╛рди рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ QueueNewBuilds рдорд╛рди рдХреЛ TfsProjectAndBuildDefinnet рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВред



рд╣рдо TFS рд╕рд░реНрд╡рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ (рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрди рдорджреЛрдВ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╡рд┐рд╕реНрддреГрдд рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ: www.ewaldhofman.nl/post/2010/05/27/Customize.Team-Build-2010- e28093-Part-7-How-is-the-custom-Assembly-found.aspx )ред

"ClassLibrary1" рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо рд╕рдВрд╢реЛрдзрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рдЗрд╕реЗ "TfvcTemplate.12.2.xaml" рдХрд╣рд╛ рд╣реИред



рд╣рдо рдирд┐рд░реНрдорд╛рдг рдЕрдиреБрдХреНрд░рдо рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред



рд╣рдо рдмрдЪрд╛рддреЗ рд╣реИрдВ, рдирд┐рд░реНрдорд╛рдг рдЪрд▓рд╛рддреЗ рд╣реИрдВ рдФрд░ рд▓рдЧрд╛рддрд╛рд░ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЖрдирдВрдж рд▓реЗрддреЗ рд╣реИрдВред

рдкрд░рд┐рдгрд╛рдо рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред



рдХреЛрдб Git: github.com/Serg2DFX/QueueNewBuilds рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред

Source: https://habr.com/ru/post/In215369/


All Articles