TeamCity CI integration between local projects - teamcity

I have two projects A,B with their own build chains defined in their local .teamcity folders. In addition, A contains a dependency on B which I want to test. How do I set up a build chain that incorporates both of these individual builds such that, when B changes I test integration with A's master branch? I imagine I would first set up a second VCS root in B directed at the master branch of A such that the project structure on the agent looks as follows:
root
|-- A
| `-- .teamcity
| |-- settings.kts
| `-- /kotlin_code
`-- B
`-- .teamcity
|-- settings.kts
`-- /kotlin_code
But I have no idea how to automatically combine project settings from A into the B build chain. I perhaps could jerry-rig some checkout rule +:A/.teamcity/kotlin_code => B/.teamcity/kotlin_code_A and pick this up in B but this seems rather inelegant. I could also place all teamcity configuration in a separate repo, but then I lose revision control between A's codebase and its teamcity configuration. Is there a better solution? Many thanks!

https://teamcity-support.jetbrains.com/hc/en-us/community/posts/360004237439-Re-use-build-configuration-in-multiple-build-chains
The answer here recommends creating a template under root that encapsulates most of the functionality of B and from this generating separate build chains in A,B. I am not sure this is the most elegant solution, however, so I will leave the question open.

The best answer I have found is to define a finish build trigger that starts when the previous build completes and send a reverse dependency back through the build chain to allowing builds to be customized.

Related

How do I configure a dependency in a gradle project such that it also works as a submodule?

I want to use a project in my project as a git submodule, ideally without changing the upstream project (or if it makes sense, changing it in a way that will get merged there).
The problem is that the project consists of modules, 2 of which I want to directly use, with the one also depending on the other.
myProject
├ submodule
| ├ first
| | ├ build.gradle: implementation project(":second") <---- this fails if I don't change it to :submodule:second
| ├ second
| ├ settings.gradle: include ':first', ':second'
├ app
| ├ build.gradle: implementation project(":submodule:first"), implementation project(":submodule:second")
| ├ settings.gradle: include ':submodule:first', ':submodule:second', ':app'
As my project's settings.gradle replaces the submodule's settings.gradle, the submodule's absolute paths suddenly change. Can I somehow `include ':submodule:second as :second'?
I know I can use implementation project(somePrefix + ":second") and define this somePrefix accordingly but that would involve touching the submodule.
Gradle project paths (e.g. ':submodule:second')
actually represent project hierarchies. This means that using include ':submodule:second' in your settings.gradle will implicitly create a project called submodule, even if not relevant for the build at all.
do not need to match the directory structure (this is just a convention). You may set the project directory independent from the project path (and the project name).
Check out the following example from the documentation:
// include two projects, 'foo' and 'foo:bar'
// directories are inferred by replacing ':' with '/'
include 'foo:bar'
// include one project whose project dir does not match the logical project path
include 'baz'
project(':baz').projectDir = file('foo/baz')
However, I would recommend to not use include at all. Instead use includeBuild and setup a composite build. Composite builds differ from classical multi-project builds in their coupling. Since your Git submodule indicates a build that may be used as a standalone project (with its own settings.gradle), the strong coupling of a multi-project builds seems inappropriate. Multiple settings.gradle files may also cause problems in a multi-project build, but are fine for composite builds.

Maven repo module and parent at the same level

I have created a simple maven project with a parent pom and a module pom. When i execute a mvn clean install i notice that the parent and the module are in the same level.
Structure of the project in the local repo:
-parent folder
-module folder
While I expected something like that:
-parent folder
+—-module folder
Is this normal ?
What happened if two modules have the same name in this case ?
Assuming you are talking about the local repo usually located at ~/.m2/repository, yes, that is normal. You have to distinguish between the folder layout within the repository and the folder layout for your development.
As mentioned in this question, the artifacts are always in a folder structure according to their coordinates (groupId, artifactId and version).
groupIdSplitAtDots/artifactId/version
Whether some artifacts are modules of another is completely irrelevant for the directory-layout of the local repository.
If you have e.g. the artifacts com.organisation.topic:artifact-parent:1.2, com.organisation.topic:artifact-module1:1.2 and com.organisation.topic:artifact-module2:1.2, the folder structure will be:
com
|-- organisation
|-- topic
|-- artifact-parent
|-- 1.2
|-- artifact-module1
|-- 1.2
|-- artifact-module2
|-- 1.2
Note, that for development it is usually a good idea to have the parent module in a parent folder, resulting in a layout like this:
artifact-parent
|-- artifact-module1
|-- artifact-module2
As per your second question, identical module names (artifactIds) are not allowed. Regarding the artifactId the docs state:
The identifier for this artifact that is unique within the group given by the group ID.

maven use release:branch to branch select modules

I have a maven multi module project like so
modA
modB
modC
modD
custom-pom.xml
And here the pom
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xx.xx.correspondence</groupId>
<artifactId>xxHudsonTP</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>modA</module>
<module>modB</module>
</modules>
</project>
Now, when I invoke release:branch with the intent of creating a branch on custom-pom.xml like so
mvn release:branch -DbranchName=new-branch -f custom-pom.xml
It ends up creating a branch with all 4 modules.
Is there any way using release plugin to make sure only selected modules are branched without resorting to branching each module separately.?
Any other maven plugins..?
Edited
The background of this questions stems from the fact that the svn repo that I am working with has about 20 different modules with 4 different artifacts that they need to generate. I could have easily gone with grouping the modules into sub folders, but since a few modules are common between
the artifacts, I didn't think too much into splitting them up.
I understand that branching all modules is trivial and probably simple to manage, but the other developers in the team have this feeling of dealing with too much for accomplishing simple tasks like a one line bug fix. Hope that helps.
As far as I know, there is no solution to answer what you asked.
You have to keep in mind that multimodule projects (aggregation) means that every submodule share the same application lifecycle. This is really what modules and aggregation are intended to.
I see 2 differents workarounds.
You have 2 real differents lifecycles
There is indeed 2 groups in your 4 submodules, lets say group1 : A and B, group 2, C and D.
Split them into 2 new projects :
Group1
|-- Project A
| `-- pom.xml
|-- Project B
| `-- pom.xml
`-- pom.xml
Group2
|-- Project C
| `-- pom.xml
|-- Project D
| `-- pom.xml
`-- pom.xml
Pro : You may be able to branch group 1 and 2 separately.
Cons : You won't be able anymore to perform simultaneaous action (in one command) on every project (like realeasing or builind them)
You really have 1 single lifecycle
This is probably the case. You may want to branch only 1 or 2 submodules because of your very good understanding of the underlying architecture of the project. An so, you don't want to deal with too many conf / artifacts / time building ... Indeed, all those reasons may have indirects impacts that you won't see. Always build the whole project !
If this is for space saving (however most of SCM allow you to branch with few space, like Yorkw said), because your SCM allow you to get only submodules (and maybe both, like for Clearcase) ... sorry, there is no solution. This is the maven way, and I think this is the good one. (ok it's a little bit demagogic, but I really believe what I said)
Don't hesitate to explain us why you really want to branch only a subset of your modules. If there is another reason, you may have more accurate(s) solution(s).

Can Gradle handle local dependencies to other than sub-directories?

I don't know if I totally got the concept wrong, but I want to create several projects with dependencies to other projects which are not part of the directory structure of a parent project. I know that the normal way of doing this would be to use an external dependency which fetches from some external repository. But in this case, where let's say in project called 'F' a framework is developed, which is used in project 'P'., then P uses F, but F should IMO not necessarily be a sub-project of P as P is only used to test-drive the development of F (but it's not only a unit test). Later in the process, when F is stable, F is separated and can be consumed by other projects via a repository. But during development of F with P as it's test case, it would be nice if that round-trip through the repository could be omitted.
To make matters worse, for the initial development there is more than one test-driving consumer project, which all need to have a dependency to F, but not via an external repository.
My idea is to develop F in some place on the disk with it's own git reposity. The other P like projects reside somewhere else on the disk and have a local file system based dependency to F. Would such a construct be possible in Gradle? If so, where do I start? I scanned the Java examples but couldn't find an appropriate example.
Any ideas?
The Gradle project hierarchy is fully virtual. It just has the default that the physical location corresponds to the virtual hierarchy. But you have complete control over this. See: http://gradle.org/0.9-rc-1/docs/userguide/build_lifecycle.html#sec:settings_file
Regarding your other ideas have a look at the following Jira: http://jira.codehaus.org/browse/GRADLE-1014
You could consider a folder hierarchy like this one:
Main folder
|- F folder
| |- .git
| |- sources
| |- build.gradle (with parts specific to F)
|- P folder
| |- sources
| |- build.gradle (with part specific to P)
|- build.gradle (with common parts)
|- settings.gradle
So you can always decide to run gradle on either the F project, the P project or the two alltoegether. It will also allows you to promote you F project alone without the P or any other side projects.
For more up-to-date information, check the Multi Project Builds chapter of the Gradle documentation.

Gradle multiprojects with same name, different paths

I have a monolith Gradle project that contains multiple subprojects, each with its own subprojects, like so:
project
|
|-- subprojectA
| |-- models
|
|-- subprojectB
| |-- models
This compiles fine but the issue is when I try to add a dependency on :subprojectB:models to :subprojectA:models, Gradle thinks :subprojectA:models is trying to add a dependency on itself and complains of a circular dependency, even though I specify the fully qualified path like so (in subprojectA's build.gradle):
compile project(':subprojectB:models')
How can I avoid this? Can subprojects not have the same name even if their paths are unique?
Project identity for dependency resolution is based on the group:name:version or GAV coordinates, as explained in the linked Gradle issue.
So you need to make sure your different models project have different GAVs.
One way to make this happen is to make the subprojectA (or B) part of the group.
Another way is to assign names that are not based on the containing folder.
That's currently a known Gradle issue as Gradle by default uses the parent directory name as the project name. You can work around the issue as described here by assigning unique subproject names in the root project's settings.gradle like so:
include ':subprojectA:models', ':subprojectB:models'
project(':subprojectA:models-a').projectDir = file('subprojectA/models')
project(':subprojectB:models-b').projectDir = file('subprojectA/models')

Resources