4

I am using Team Foundation Server 2013 builds for a multi-module Gradle project, each module resides in its own Git repository. All of these repositories are located in a single TFS 2013 project. The build template is executed on the main module's repository. That is, in the build configuration, Source Settings / Repository name is set to the main module's repository.

Now, within the build, the current commit as well as the commit ID of the last successful build is identified for each of the modules (this happens via Git shell magic and a separate repository which keeps record of the last successful builds). Then, again for each module, the TFS build activity GitAssociateCommitsAndWorkItems is called and the values of CurrentCommit, PreviousCommit and RepositoryRootFolder are set to the values which correspond with that module's repository.

After the build, the build summary on the TFS web page correctly shows the commits of all modules which took place since the last successful build, including their commit message. For the commits in the main module, the commit links correctly lead to the commit summary page within TFS and work items which have been referenced in the commit's message are associated with the build as expected. For all other modules, however, the commit links don't work, because they lead to the main module's repository instead (the link leads to something like http://my-tfs-server/tfs/MyProject/_git/mainmodule/commit/0458838c815786dfaa5fac519d1fb19699c645c5). The association of work items doesn't work either in this case.

For modules which are not the main module, commit links on the TFS build summary page don't work

My question now is: How does the GitAssociateCommitsAndWorkItems determine the TFS Git repsitory to which the commits belong and is it possible to change it?

Michael Schmeißer
  • 3,407
  • 1
  • 19
  • 32

1 Answers1

1

Well, I've found a workaround which solves my problem. It is not very convenient, but is however the best solution I was able to figure out.

I basically replaced the GitAssociateCommitsAndWorkItems activity with a custom sequence which assigns the commits with the build one by one. For this, my Gradle build (more specifically its init script) produces a tab-separated output file with all commits which should be associated. Then, within the build, this file is read and each line is split into the different values, which are

  • Author
  • ID
  • Committer
  • Message (aka subject in Git)
  • Timestamp
  • TFS GUID of the repository to which the commit belongs

All except the last value can be easily retrieved from the Git commit log. The TFS GUID of a Git repository can be retrieved with TFS' REST API, using the REST endpoint http://my.tfs.server/tfs/MyProjectCollection/_apis/git/repositories?api-version=1.0 This is where you can also find the GUID of the TFS project, which you will need as well, but is not included in my commit information file, because the project GUID is constant for a given build definition (put in other words, a build definition always belongs to a single TFS project).

Then, using these values, an AssociatedCommit object is created and filled. For the Uri field of this object, the following pattern has to be used:

"vstfs:///Git/Commit/" + tfsProjectGuid + "%2f" + tfsRepositoryGuid + "%2f" + commit.CommitId

Finally, the WriteBuildInformation activity is used to associate the commit objects with the build (see the image below). The type argument for this activity is Microsoft.TeamFoundation.Build.Activities.Git.AssociatedCommit.

Activity to manually associate a commit with a build

Michael Schmeißer
  • 3,407
  • 1
  • 19
  • 32