Accessing BuildResult files from "Request Rebuild..." action
What I would like to do is also be able to reference those file(s) from within the "Request Rebuild..." action for our custom dialog section. In the Rebuild Dialog there is a reference to the BuildResult, which is not null. What I can't figure out is how to get a IBuildResultContext, which best I can tell is what the ResultPage uses to get access to the files associated with the BuildResult. This is passed to the ResultPage when it is constructed from how I am understanding the build source.
Is it possible to do want I am attempting?
If yes, what object/methods do I need to get the IBuildResultContext so I can get the contributions using getContributions or is this even necessary?
Is there another way of doing what I want too do?
Accepted answer
@Override
public void initializeContributionProvider(IProgressMonitor monitor) throws Exception {
IBuildRequest request = getStartRequest(getBuildResultContext().getBuildResultRecord().getBuildRequests());
if (request != null) {
fBuildProperties = request.getBuildDefinitionInstance().getProperties();
} else {
fBuildProperties = new ArrayList<IBuildProperty>();
}
}
private IBuildRequest getStartRequest(IBuildRequest[] allRequests) {
for (IBuildRequest currentRequest : allRequests) {
if (currentRequest.getBuildAction().getAction().equals(IBuildAction.REQUEST_BUILD)) {
return currentRequest;
}
}
// Log a message, but don't treat this as an error. It is unexpected,
// but we can handle it.
BuildUIPlugin.log(NLS.bind(Messages.BuildPropertiesContributionProvider_NO_REQUEST,
BuildResultTextHelper.getLabel(getBuildResultContext().getBuildResult())));
return null;
}
@Override
public AbstractBuildResultPage getBuildResultPage() {
return new BuildPropertiesPage(getBuildResultEditor(), getExtensionId(),
Messages.BuildPropertiesContributionProvider_TAB_TEXT, getExtendedContributionIds(),
getBuildResultContext(), fBuildProperties);
}
Comments
Nick, thanks. That is exactly the code logic I was using as a guide, but I didn't see that getBuildResultContext() was part of the common super class, so I was attempting the following logic which didn't work.:
List allRequests = getBuildResult().getBuildRequests();
IBuildRequest buildRequest = getStartRequest( (IBuildRequest[])allRequests.toArray() );
Once I change my code to use getBuildResultContext().getBuildResultRecord().getBuildRequests())
I was able to get the properties.
Thanks again, you've been a great help thru this process in answering my questions
-Steve
Good to hear you were able to get it going, Steve.
2 other answers
<extension
point="com.ibm.team.build.ui.requestBuildDialogSections">
<requestBuildDialogSection
class="com.ibm.team.build.internal.ui.dialogs.ScmOptionsSection$Factory"
order="100"/>
<requestBuildDialogSection
class="com.ibm.team.build.internal.ui.dialogs.PropertiesSection$Factory"
order="200"/>
</extension>
Comments
Nick, thanks for the info. I already have a dialog section implemented as part of our solution, which is how our user base will enter our specific build data. We will be displaying our build wizard from this section.
@Override
protected void createSectionContent( Section section )
{
ITeamRepository repos = getSite().getTeamRepository();
IBuildRequest request = getSite().getBuildRequest();
IBuildResult result = getSite().getBuildResult();
builddef = getSite().getBuildDefinition();
I couldn't see within those objects where I could retrieve the files(contributions) that were published by the engine to the BuildResult via artifactFilePublisher. I can get those files via the BuildResultContributionProvider I implemented for the BuildResultEditor, but I still don't see how I can get those files from the objects available in the dialog section.
cont'd in next comment
The flow is this:
The initial request flows to the engine which processes the build and one result of that is a file which is a serialized image of the Build object. For rebuild or view we use that file to repopulate the build object for view/rebuild wizard.
We do not want to create a ton of generic properties in the request. I have another question on the forum about that specific issue(see link below), which appears we would need to open a feature, so we are considering other short term solutions to pass the file on the initial request. But as for the BuildResult, we can already publish the file to it, but as stated above I don't see how I can obtain that file with the objects available in the dialog section, proabably because I don't have a full understanding of those objects, but I don't see any methods that would do that as provided in BuildRAesultcontext(getContributions)
Can you point me to the logic within BuildResult that I would need to retrieve the files that were published by the engine? Basically the equivalent of IBuildResultContext().getBuildResultContributions(getContributionIds())
https://jazz.net/forum/questions/106107/is-there-a-way-to-send-a-file-in-a-buildrequestbuilddefintion-to-the-build-engine?utm_campaign=forum&utm_medium=email&utm_source=forum-new-comment&utm_content=forum-question
In the editor context, the editor fetches the contributions of interest for you. In the request dialog, you'd need to do this yourself using:
com.ibm.team.build.client.ITeamBuildClient.getBuildResultContributions(IBuildResultHandle, String, IProgressMonitor)
com.ibm.team.build.client.ClientFactory.getTeamBuildClient(ITeamRepository)
Using contributions in this way could also be used for the other issue of communicating a file to the build. The corresponding API is:
com.ibm.team.build.client.ITeamBuildClient.addBuildResultContribution(IBuildResultHandle, IBuildResultContribution, IProgressMonitor)
com.ibm.team.build.common.BuildItemFactory.createBuildResultContribution()
Nick thanks. So for Rebuild it looks like its possible to get the file from the Result using the solution you provided above.
But for an initial Build Request, the BuildRequest BuildResult and BuildResultHandle are all null in createSectionContent, validate2 and applyProperties where we get control.
So how would I be able to use ITeamBuildClient.addBuildResultContribution(IBuildResultHandle, IBuildResultContribution, IProgressMonitor)
if the BuildResultHandle is null. Would I first somehow create the handle?
I see a createBuildResult() in the factory class, but not a handle. I assume I would also have too create a BuildResult as well and set that in the BuildRequest?
The reason we are passing a file is because the object can exceed the size limit for a Build Property.
Sorry, I neglected the fact that we don't actually notify the section extensions after the request has been submitted. The request is submitted in com.ibm.team.build.internal.ui.dialogs.RequestBuildDialog.requestBuildJobImpl(IBuildDefinition, ITeamRepository, IProgressMonitor). Unfortunately, I don't see any way for you to intercept this and get the request or result after it has been submitted, at least not using the standard request dialog. If you have control over the action that brings up the request dialog, you could provide your own subclass and override RequestBuildDialog.requestBuild.
Nick, is it possible to add a property to the build result from the build agent running a ANT script? I don't see a way. All I see is the ANT script can only read properties.
I am storing our custom Build object on a sever via ftp and I want to store that directory in the Build result as a property so when I do a Rebuild the request will have that property and then my custom build section can ftp the file to repopulate our custom build wizard with the original build request data. Since each build has a unique ID the ftp dir will be unique for each build. This is the solution I have come up with since there is no access to the Build Result context from the Rebuild request. From testing I can see that a property that is added in the Build Request appears in the Build Result and the Rebuild request Props, but as I mentioned I don't see a way add a property from ANT via the build agent. For our build solution to work for Rebuild I need a way to retrieve our Build Obj (a serialized file) during The Rebuild Request dialog.
Thanks,
-Steve
- query for link type contributions using com.ibm.team.build.client.ITeamBuildClient.getBuildResultContributions(IBuildResultHandle, String, IProgressMonitor), using constant com.ibm.team.build.common.model.IBuildResultContribution.LINK_EXTENDED_CONTRIBUTION_ID as the link type id
- select the one that corresponds to your custom build object, since there may be more than one link (e.g. by matching label on the IBuildResultContribution), or checking for "ftp:" prefix, or both
- you can extract the URL using com.ibm.team.build.common.model.IBuildResultContribution.getExtendedContributionProperty(String), using property name constant com.ibm.team.build.common.model.IBuildResultContribution.PROPERTY_NAME_URL
Comments
Nick, I have another question related to this. In the Results view I have a custom resultsPage which extends AbstractBuildResultPage. within that page I would like to get the properties for the buildRequest builddef (the properties listed in the props tab). AbstractBuildResultPage has a method getBuildResult which I can get a IBuildDefintionHandle, but I don't know how to get the BuildDef form the handle and thus use the getProperties. I see the properteis tab logic gets all the requests to find the starting request to obtain the builddef instnace thus properties. BuildResult has a getBuildRequests method, so I am attemtping to use that and the above logic to get to the properties. What is the best way for me to retrieve the properties?
P.S. my thought of using BuildResult.getBuildRequests() is not working as I had hoped because It returns a List of IBuildRequestHandle. I'm not clear on how to get from a Handle to an instance of the object. I.E. IBuildDefintionHandle to IBuildDef, IBuildRequestHandle to IBuildRequest.