2

Our project uses Gradle (whose dependency system is compatible with Maven IIUC). When depending on external projects, we try to depend on stable versions. Sometimes we have to depend on a development version. And sometimes we have to fork the repository of a dependency and depend on that (in general we try to upstream our changes as soon as possible).

How can we ensure that every of our developers get a consistent build environment?

  • We could use Mercurial subrepositories (which are similar to Git submodules and allow to "embed" specific revisions of external repositories into our repository). The disadvantage is that every developer has to build all the non-released versions of the dependencies.

  • We could set up an internal artifact server and build all the forked dependencies centrally.

    • We could leave the version of the dependency unchanged in the forked repository. Then we have to somehow ensure that changes in the repository get picked up by all developers to have a consistent environment across all machines.
    • We could give every "significant" revision in the forked repository a special version and change our project to depend on these versions. This has the disadvantage that we can't just use the branch we use to upstream our changes (since the version should be unchanged when creating a pull request).

Thoughts? Are there better ways to solve this problem?

1 Answers1

1

We could use Mercurial subrepositories

This also has the risk of becoming a "hidden" dependency: all the builds pass so nobody thinks of removing the subrepository once the original project has been released. More likely to happen if you have a large number of dependent projects.

We could set up an internal artifact server

This is what every team that I've worked with has done, and it's just one of the reasons to use an artifact server. IMO, any team that has more than one developer and more than one project will benefit from a local repository, especially when paired with a build server.

The question of how you should version forked artifacts is trickier, and comes down to whether this is a temporary situation or whether you're planning to maintain a long-term fork.

If you're just looking to get development builds, and the project uses "snapshot" versioning, then you should almost certainly keep the project's version (and group/artifact IDs). Eventually there will be a release version and you can stop storing the snapshot in the local repository.

If, on the other hand, you're making a long-term fork where you'll cherry-pick updates from the source project, you should not only give it its own version but also its own group and artifact IDs. So instead of com.example:someartifact:1.2.3, uses com.mycompany:example-someartifact:1.2.3. Beware, however, that this introduces the possibility of classpath conflicts.

Are there better ways to solve this problem?

It's not a better way, but if the upstream project maintains its own public build repository, you could pull your artifacts from it. Even in this case I think a local repository server that proxies the remote is a better idea than putting lots of explicit repository references in your settings file.

kdgregory
  • 5,270