Help using the TeamCity API to remotely manage builds

Hi,

I have a need to write some ANT tasks to interact with TeamCity remotely.

Can someone give me some pointers on which jars I need and possibly some code snippets on how to:

- Trigger builds
- List builds
- Set Build properties.

Thank you,

Scott

17 comments
Comment actions Permalink

Hello,
Sorry for delay, there were synchronization problems and I dind't notice the
message before.

Could you explain why do you want to do this actions from inside ant?
Anyway, you can use
jetbeains.buildServer.serverProxy.RemoteBuildServerFacade from
buildServerRemoteServerProxy.jar (you'll find it in the plugin lib
directory). This class allows you to trigger build or find last build
instance.
Unfortunatelly remote interface does not allow you to modify configuration
(change build properties) at the moment.

--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:13578582.1162213419456.JavaMail.itn@is.intellij.net...

Hi,

>

I have a need to write some ANT tasks to interact with TeamCity
remotely.

>

Can someone give me some pointers on which jars I need and possibly
some code snippets on how to:

>

- Trigger builds
- List builds
- Set Build properties.

>

Thank you,

>

Scott



0
Comment actions Permalink

Let me explain why I need to be able to trigger builds from inside ANT....

We have a requirement in Release Engineering to have builds split in 2 parts:

- build the release for testing.
- once approved, publish the release to internal users.

The approval step is handled as an workflow step in JIRA whereby a listener will then communicate with TeamCity to trigger the "Publish" build configuration.

I'm already doing this with Luntbuild and I'd like to be able to do it TeamCity as well.

In addition, can I request the feature to allow the remote interface to modify configurations? It would be interesting to be able to set the next build version...

Thanks,

SH

0
Comment actions Permalink

All these actions can be easy performed on the server side, you can write
your server plugin, in this plugin add listener to the BuildServer and do
whatever you want when build started, finished and so on. On the server side
you can modify build properties, create new configurations, view artifacts
and build logs. Is this way suitable for you?

--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:11798064.1162225612752.JavaMail.itn@is.intellij.net...

Let me explain why I need to be able to trigger builds from inside ANT....

>

We have a requirement in Release Engineering to have builds split in 2
parts:

>

- build the release for testing.
- once approved, publish the release to internal users.

>

The approval step is handled as an workflow step in JIRA whereby a
listener will then communicate with TeamCity to trigger the "Publish"
build configuration.

>

I'm already doing this with Luntbuild and I'd like to be able to do it
TeamCity as well.

>

In addition, can I request the feature to allow the remote interface to
modify configurations? It would be interesting to be able to set the next
build version...

>

Thanks,

>

SH



0
Comment actions Permalink

All these actions can be easy performed on the server
side, you can write
your server plugin, in this plugin add listener to
the BuildServer and do
whatever you want when build started, finished and so
on. On the server side
you can modify build properties, create new
configurations, view artifacts
and build logs. Is this way suitable for you?


Hi Olesya,

Creating a server plugin still doesn't give me a way to trigger a build...

I tried to use RemoteBuildServerFacade to get going but I seem to be missing something...

Here's my code:

+package com.cae.tools.ant.taskdefs.optional.teamcity;

import java.util.List;

import jetbrains.buildServer.serverProxy.RemoteBuildServerFacade;
import jetbrains.buildServer.xmlrpc.XmlRpcTargetImpl;


public class ListAgents {

public static void main(String[] args) {
XmlRpcTargetImpl xmlrpc = new XmlRpcTargetImpl("http://]]>:8080/teamcity", 60);
RemoteBuildServerFacade bf = RemoteBuildServerFacade.createInstance(xmlrpc,null);
List agents = bf.getRegisteredAgents();
System.out.println("agents: " + agents.size());
}
}+

I'm not sure about the createInstance call since I cannot seem to create an ApplicationFacade.

Can you give me some more pointers?

Thanks,

SH

0
Comment actions Permalink

Creating a server plugin still doesn't give me a way to trigger a build...

Why? Is it your problem (there is not enough infomration you need on the
server ) or you cannot find out what method adds build to the queue?

I'm not sure about the createInstance call since I cannot seem to create
an ApplicationFacade.

You cannot pass null here.. Create an empty implementation with empty
methods
void assertNotDispatchThread();
void onProcessCanceled();

and return null from XmlRpcTarget.Cancelable createCancelable();

registeredAgents are useless for you. Use getRegisteredProjects, it returns
all teamcity projects. If first parameter is true, all last finished
instances will be loaded. You can also use configurations
(project.getBuildTypes) in order to add some of them to the queue.

--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:5591930.1162228925884.JavaMail.itn@is.intellij.net...
>> All these actions can be easy performed on the server
>> side, you can write
>> your server plugin, in this plugin add listener to
>> the BuildServer and do
>> whatever you want when build started, finished and so
>> on. On the server side
>> you can modify build properties, create new
>> configurations, view artifacts
>> and build logs. Is this way suitable for you?
>>
>

Hi Olesya,

>

Creating a server plugin still doesn't give me a way to trigger a build...

>

I tried to use RemoteBuildServerFacade to get going but I seem to be
missing something...

>

Here's my code:

>

+package com.cae.tools.ant.taskdefs.optional.teamcity;

>

import java.util.List;

>

import jetbrains.buildServer.serverProxy.RemoteBuildServerFacade;
import jetbrains.buildServer.xmlrpc.XmlRpcTargetImpl;

>
>

public class ListAgents {

>

public static void main(String[] args) {
XmlRpcTargetImpl xmlrpc = new XmlRpcTargetImpl("http://<some
server>:8080/teamcity", 60);
RemoteBuildServerFacade bf =
RemoteBuildServerFacade.createInstance(xmlrpc,null);
List agents = bf.getRegisteredAgents();
System.out.println("agents: " + agents.size());
}
}+

>

I'm not sure about the createInstance call since I cannot seem to create
an ApplicationFacade.

>

Can you give me some more pointers?

>

Thanks,

>

SH



0
Comment actions Permalink

Hi Olesya,

Thank you very much...your pointers really helped me.

One thing I noticed is that you are not required to authenticate in order to trigger a build?!

Can you also provide me with a snippet of code that allows me to get a list of artifacts and possibly download them?

Thanks,

scott

0
Comment actions Permalink

scoheb wrote:
>> All these actions can be easy performed on the server
>> side, you can write
>> your server plugin, in this plugin add listener to
>> the BuildServer and do
>> whatever you want when build started, finished and so
>> on. On the server side
>> you can modify build properties, create new
>> configurations, view artifacts
>> and build logs. Is this way suitable for you?
>>


Hi Olesya,

Creating a server plugin still doesn't give me a way to trigger a build...

I tried to use RemoteBuildServerFacade to get going but I seem to be missing something...


May be :)
To trigger a build from the server-side, you should create a TeamCity server-side plugin as
described at http://www.jetbrains.net/confluence/display/TW/Plugin+Development

In your component, you should get BuildType object (which represents a build configuration).
To trigger the build for this build configuration, you should invoke
buildType.addToQueue("trigger by whatever") call. This will add corresponding build configuration
to the queue and if there are available agents, build will be started.

I still see no reason why you should use remote facade for this task.

Rough code snipped for your server-side component:

public class MyComponent {
SBuildServer myServer;
public MyComponent(SBuildServer server) {
myServer = server;
}

public void addToQueue(String reason) {
SBuildType configuration = myServer.findBuildTypeById("bt2"); // use your build type id here
if (configuration != null) {
configuration.addToQueue(reason);
}
else {
System.err.println("Unable to find build configuration bt2");
}
}
}


Here's my code:

+package com.cae.tools.ant.taskdefs.optional.teamcity;

import java.util.List;

import jetbrains.buildServer.serverProxy.RemoteBuildServerFacade;
import jetbrains.buildServer.xmlrpc.XmlRpcTargetImpl;


public class ListAgents {

public static void main(String[] args) {
XmlRpcTargetImpl xmlrpc = new XmlRpcTargetImpl("http://<some server>:8080/teamcity", 60);
RemoteBuildServerFacade bf = RemoteBuildServerFacade.createInstance(xmlrpc,null);
List agents = bf.getRegisteredAgents();
System.out.println("agents: " + agents.size());
}
}+

I'm not sure about the createInstance call since I cannot seem to create an ApplicationFacade.

Can you give me some more pointers?

Thanks,

SH



--
Kirill Maximov
JetBrains, Inc.
http://www.jetbrains.com
"Develop with pleasure!"

0
Comment actions Permalink

Can you also provide me with a snippet of code that allows me to get a
list of artifacts and possibly download them?


At the moment work with artifacts is available from the server side only
(see ArtefactsInfo)
--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:30811387.1162244094680.JavaMail.itn@is.intellij.net...

Hi Olesya,

>

Thank you very much...your pointers really helped me.

>

One thing I noticed is that you are not required to authenticate in order
to trigger a build?!

>

Can you also provide me with a snippet of code that allows me to get a
list of artifacts and possibly download them?

>

Thanks,

>

scott



0
Comment actions Permalink

Hi Kirill,

>>>> I still see no reason why you should use remote facade for this task.

I have a workflow setup using JIRA to request, start and approve software releases. If an action is triggered in JIRA to start a build, how does this translate into using a server-side plugin? How could I communicate with my server-side plugin from JIRA? Seems like the only way to do this is to use the Remote Facade (ie XMLRPC).

Or is there a way to create a server-side plugin that would be exposed via XMLRPC?

Thanks,

Scott

0
Comment actions Permalink

Hello,

You can register your own controller: see WebControllerManager interface. If
you register a controller on some path then you can send an HTTP GET request
to this controller and controller will trigger a build.

--
Pavel Sher


"scoheb" <no_reply@jetbrains.com> wrote in message
news:26112984.1162309700230.JavaMail.itn@is.intellij.net...

Hi Kirill,

>
>>>>> I still see no reason why you should use remote facade for this task.
>

I have a workflow setup using JIRA to request, start and approve software
releases. If an action is triggered in JIRA to start a build, how does
this translate into using a server-side plugin? How could I communicate
with my server-side plugin from JIRA? Seems like the only way to do this
is to use the Remote Facade (ie XMLRPC).

>

Or is there a way to create a server-side plugin that would be exposed via
XMLRPC?

>

Thanks,

>

Scott



0
Comment actions Permalink

Could you explain how are you going to do this on an agent?
Maybe I could help you to do the same on the server.

>How could I communicate with my server-side plugin from JIRA?
For example you can up your own XMLRPC server on the TC server.
--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:26112984.1162309700230.JavaMail.itn@is.intellij.net...

Hi Kirill,

>
>>>>> I still see no reason why you should use remote facade for this task.
>

I have a workflow setup using JIRA to request, start and approve software
releases. If an action is triggered in JIRA to start a build, how does
this translate into using a server-side plugin? How could I communicate
with my server-side plugin from JIRA? Seems like the only way to do this
is to use the Remote Facade (ie XMLRPC).

>

Or is there a way to create a server-side plugin that would be exposed via
XMLRPC?

>

Thanks,

>

Scott



0
Comment actions Permalink

>>>> Could you explain how are you going to do this on an agent?
>>>> Maybe I could help you to do the same on the server.

Let me try to explain our methodology:

1-) User in JIRA progresses an issue to the "Approved" state.
2-) A listener in JIRA receives the event and using some custom field values:
(a) Set the next build version of the "Publish" build configuration (build type).
(b) Triggers the "Publish" build configuration.
3-) The agent that receives the build request then publishes the Artifacts to our intranet.

Notes:

1-) The actual build would be done in a "Build" build configuration. This would produce the artifacts that the "Publish" build configuration would need to get a handle on. I guess when the "Build" build configuration finishes, I can get the buildTypeID and store it in a prroperties file in SVN. Then the "Publish" build configuration would use an agent on the TeamCity server, whereby allowing access to the local artifacts .

2-) So far, with Olesya's help, I'm able to trigger a build configuration using RemoteBuildServerFacade. However, I CANNOT update properties or access artifacts remotely.

So, I think I like Olesya's idea of creating a server-side XMLRPC server plugin that could expose:

a) an update build configuration properties' method.
b) an artifacts download method.

Olesya, do you think you can help me get started?

Thanks,

Scott

0
Comment actions Permalink

Hello Scott,

Olesya, do you think you can help me get started?

Of course, I'll answer you tomorrow. I'll try to write and attach small
sample plugin so you'll be able to modify it according to your purpose.
Thanks for your interest in our TeamCity!

--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:3011474.1162313344662.JavaMail.itn@is.intellij.net...
>>>>> Could you explain how are you going to do this on an agent?
>>>>> Maybe I could help you to do the same on the server.
>

Let me try to explain our methodology:

>

1-) User in JIRA progresses an issue to the "Approved" state.
2-) A listener in JIRA receives the event and using some custom field
values:
(a) Set the next build version of the "Publish" build configuration
(build type).
(b) Triggers the "Publish" build configuration.
3-) The agent that receives the build request then publishes the Artifacts
to our intranet.

>

Notes:

>

1-) The actual build would be done in a "Build" build configuration. This
would produce the artifacts that the "Publish" build configuration would
need to get a handle on. I guess when the "Build" build configuration
finishes, I can get the buildTypeID and store it in a prroperties file in
SVN. Then the "Publish" build configuration would use an agent on the
TeamCity server, whereby allowing access to the local artifacts [
.buildServer/system/$].

>

2-) So far, with Olesya's help, I'm able to trigger a build configuration
using RemoteBuildServerFacade. However, I CANNOT update properties or
access artifacts remotely.

>

So, I think I like Olesya's idea of creating a server-side XMLRPC server
plugin that could expose:

>

a) an update build configuration properties' method.
b) an artifacts download method.

>

Olesya, do you think you can help me get started?

>

Thanks,

>

Scott



0
Comment actions Permalink

Hello Scott,
here is the simple sample how to trigger builds remotelly

1) create a class TCListener:
package jetbrains.sample;

import java.io.File;
import jetbrains.buildServer.BuildType;
import jetbrains.buildServer.serverSide.ArtefactsInfo;
import jetbrains.buildServer.serverSide.BuildServerAdapter;
import jetbrains.buildServer.serverSide.RunningBuild;
import jetbrains.buildServer.serverSide.SBuildServer;
import org.apache.xmlrpc.WebServer;


public class TCListener{

private final SBuildServer myServer;

public TCListener(final SBuildServer server) {

myServer = server;

final WebServer webServer = new WebServer(7732);
webServer.addHandler("tcListener", this);
webServer.start();

server.addListener(new BuildServerAdapter(){
public void buildFinished(RunningBuild build) {
final File dir = ArtefactsInfo.getArtefactsDir(server,
build.getBuildId());
processArtifacts(dir);
}
});
}

private void processArtifacts(final File dir) {
}

/**

  • Has to be called via XmlRpc

  • @param buildId build id to be started

  • @return fake value

*/
public boolean triggerBuild(String buildId) {
BuildType type =
myServer.getProjectManager().findBuildTypeById(buildId);
if (type != null) {
type.addToQueue("tc-listener");
}
return true;
}

}

2) compile jar and add it to the server libs.

3) add bean to the buildServerSpring.xml:
Start server 4) Create a caller triggering a build having some specified number: import org.apache.xmlrpc.XmlRpcClient; import org.apache.xmlrpc.XmlRpcException; import java.util.Vector; import java.io.IOException; public class TCCaller { public static void main(String[] args) throws IOException, XmlRpcException { final XmlRpcClient client = new XmlRpcClient("localhost",7732); final Vector params = new Vector(); params.add("bt1"); client.execute("tcListener.triggerBuild", params); } } Run it. It works, build is in the queue. Please don't hesitate ask me more questions Thanks! -- Olesya Smirnova JetBrains, Inc http://www.jetbrains.com "Develop with pleasure!" "Olesya Smirnova" ]]> wrote in message
news:ei81re$4h2$1@is.intellij.net...

Hello Scott,

>> Olesya, do you think you can help me get started?

Of course, I'll answer you tomorrow. I'll try to write and attach small
sample plugin so you'll be able to modify it according to your purpose.
Thanks for your interest in our TeamCity!

>

--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"

>
>

"scoheb" <no_reply@jetbrains.com> wrote in message
news:3011474.1162313344662.JavaMail.itn@is.intellij.net...

>>>>>> Could you explain how are you going to do this on an agent?
>>>>>> Maybe I could help you to do the same on the server.
>>
>> Let me try to explain our methodology:
>>
>> 1-) User in JIRA progresses an issue to the "Approved" state.
>> 2-) A listener in JIRA receives the event and using some custom field
>> values:
>> (a) Set the next build version of the "Publish" build configuration
>> (build type).
>> (b) Triggers the "Publish" build configuration.
>> 3-) The agent that receives the build request then publishes the
>> Artifacts to our intranet.
>>
>> Notes:
>>
>> 1-) The actual build would be done in a "Build" build configuration. This
>> would produce the artifacts that the "Publish" build configuration would
>> need to get a handle on. I guess when the "Build" build configuration
>> finishes, I can get the buildTypeID and store it in a prroperties file in
>> SVN. Then the "Publish" build configuration would use an agent on the
>> TeamCity server, whereby allowing access to the local artifacts [
>> .buildServer/system/$].
>>
>> 2-) So far, with Olesya's help, I'm able to trigger a build configuration
>> using RemoteBuildServerFacade. However, I CANNOT update properties or
>> access artifacts remotely.
>>
>> So, I think I like Olesya's idea of creating a server-side XMLRPC server
>> plugin that could expose:
>>
>> a) an update build configuration properties' method.
>> b) an artifacts download method.
>>
>> Olesya, do you think you can help me get started?
>>
>> Thanks,
>>
>> Scott
>



0
Comment actions Permalink

Wow! Looks great!

One more thing...Is there a way to set the next build version?

In the OpenAPI jar, BuildType does not seem to have any setters relating to this...

Thanks once again,

Scott

0
Comment actions Permalink

One more thing...Is there a way to set the next build version?


Sorry, I forgot it.

((SBuildType)type).getBuildNumbers().setBuildNumberCounter(10);

All issues on the server side can be casted to their server interfaces
(SBuildServer, SBuildType, SBuildAgent etc)

Please remember you can change build number before it is started only.
--
Olesya Smirnova
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"


"scoheb" <no_reply@jetbrains.com> wrote in message
news:26578897.1162393717023.JavaMail.itn@is.intellij.net...

Wow! Looks great!

>

One more thing...Is there a way to set the next build version?

>

In the OpenAPI jar, BuildType does not seem to have any setters relating
to this...

>

Thanks once again,

>

Scott



0
Comment actions Permalink

Olesya Smirnova wrote:


3) add bean to the buildServerSpring.xml:
<bean id="SampleListener" />


A small correction here. There is no need to modify buildServerSpring.xml .
At the root of your plugin.jar there should be a build-server-plugin.xml file with the following
content:

]]>

This way of server-side plugin deployment is described at
http://www.jetbrains.net/confluence/display/TW/Plugin+Development page.

Start server


Kind regards,
KIR


--
Kirill Maximov
JetBrains, Inc.
http://www.jetbrains.com
"Develop with pleasure!"

0

Please sign in to leave a comment.