-
Notifications
You must be signed in to change notification settings - Fork 2
Home
This library provides a convenient interface for getting data from your TeamCity buildserver.
Install-Package TeamCityAPI -Version 1.0.0
dotnet add package TeamCityAPI --version 1.0.0
NuGet: https://www.nuget.org/packages/TeamCityAPI/1.0.0
Create TeamCityClient using your server address:
var client = TeamCityClient("https://buildserver.mycompany.net");Log in using a token or username and password:
client.UseToken("myToken");
client.UseLoginAndPass("myLogin", "myPassword");TeamCityClient contains properties, accessing which you can build requests to TeamCity and receive models:
var query = client.Builds;
Builds res = await query.GetAsync();The GetAsync method returns the Builds entity, which we would get by making a GET request https://buildserver.mycompany.net/app/rest/builds
In a number of places, you can specify a filter string which defines what entities to filter/affect in the request. This string representation is referred to as locator in the scope of the TeamCity REST API:
var builds = await client.Builds
.WithLocator(new BuildLocator()
{
Agent = new AgentLocator() {Name = "linux-blade-076-vm-13"},
Count = 50
})
.GetAsync();This query is similar to https://buildserver.mycompany.net/app/rest/builds?locator=agent:(name:linux-blade-076-vm-13),count:50
You can get children in request:
var query = client.Builds
.Include(b => b.Build)
.ThenInclude(x => x.Artifacts)
.Include(x => x.Build)
.ThenInclude(x => x.Agent)This query is similar to https://buildserver.mycompany.net/app/rest/builds?fields=$short,build($short,artifacts($short),agent($short))
Also there are two include types: short and long. Models can contain simple fields (bool, string, int, etc.) and composite (other models). If we use IncludeType.Short, then only simple fields will be loaded, and composite fields will be null. If we use IncludeType.Long then the composite fields will be loaded as well. Short include:
var query = client.TestOccurrences
.Include(x => x.TestOccurrence, IncludeType.Short)
.WithLocator(new TestOccurrenceLocator()
{
Count = 1,
Build = new BuildLocator { Id = 156770153}
});
var tests = await query.GetAsync();This returns object:
<testOccurrences count="1" href="https://buildserver.mycompany.net/app/rest/testOccurrences?locator=build:(id:156770153),count:1&fields=$short,testOccurrence($short)" nextHref="/app/rest/testOccurrences?fields=$short,testOccurrence($short)&locator=build:(id:156770153),count:1,start:1">
<testOccurrence id="build:(id:156770020),id:34195" name="TestName" status="UNKNOWN" ignored="true" href="/app/rest/testOccurrences/build:(id:156770020),id:34195"/>
</testOccurrences>Long include:
var query = client.TestOccurrences
.Include(x => x.TestOccurrence, IncludeType.Long)
.WithLocator(new TestOccurrenceLocator()
{
Count = 1,
Build = new BuildLocator { Id = 156770153}
});
var tests = await query.GetAsync();This returns object:
<testOccurrences count="1" href="https://buildserver.mycompany.net/app/rest/testOccurrences?locator=build:(id:156770153),count:1&fields=$short,testOccurrence($long)" nextHref="/app/rest/testOccurrences?fields=$short,testOccurrence($long)&locator=build:(id:156770153),count:1,start:1">
<testOccurrence id="build:(id:156770020),id:34195" name="TestName" status="UNKNOWN" ignored="true" href="/app/rest/testOccurrences/build:(id:156770020),id:34195">
<ignoreDetails>Not implemented</ignoreDetails>
<test id="-1831283233637679723" name="TestName" href="/app/rest/tests/id:-1831283233637679723"/>
<build id="156770020" buildTypeId="1234567" number="213.0.20211217.221911-eap09d" status="SUCCESS" state="finished" branchName="refs/heads/net213" defaultBranch="true" href="/app/rest/builds/id:156770020" webUrl="https://buildserver.mycompany.net/viewLog.html?buildId=156770020&buildTypeId=1234567">
<finishOnAgentDate>20211218T014303+0300</finishOnAgentDate>
</build>
</testOccurrence>
</testOccurrences>Some entities, such as Builds, are returned page by page. Such entities implement the IAsyncEnumerable interface. The following code loads 250 builds with agent and then prints the Build Id and Agent IP of every 250th Build in a foreach loop
var builds = await Client.Builds
.Include(x => x.Build)
.ThenInclude(x=>x.Agent)
.GetAsync(perPage: 250);
await foreach (var buildPage in builds)
{
var build = buildPage.Value.First();
Console.WriteLine($"{build.Id}, {build.Agent.Ip}");
}