Peter Palaga
Tweak Maven so that large projects can be developed in a more continuous manner
Tweak Maven so that large projects can be developed in a more continuous manner
Continous Integration (CI) Martin Fowler (2006)
A practice where
Continuous Delivery (CD) Martin Fowler (2013):
Why is CI/CD good?
Tweak Maven so that large projects can be developed in a more continuous manner
Maven based
Large
Take WildFly as an example
Tweak Maven so that large projects can be developed in a more continuous manner
Given that Component A depends on Component B
What is wrong with the above process?
Tweak Maven so that large projects can be developed in a more continuous manner
With the stock Maven, there are only two options to shorten the cycles:
You never know what you get
The build of a component depending on another SNAPSHOT component is not reproducible
Best practice: Remote SNAPSHOTs always off (esp. for CI)
The component’s team must want to release
Welcome srcdeps
!
srcdeps
Parts in bold eliminated
srcdeps
work (1/2)Three basic ideas
Coin a convention for version strings to express the commit ID to build the given dependency from
<dependency>
<groupId>org.my-group</groupId>
<artifactId>my-artifact</artifactId>
<version>1.2.3-SRC-revision-deadbeef</version> <!-- deadbeef is a git commit ID -->
</dependency>
srcdeps
work (2/2)When an artifact with *-SRC-revision-{commitId}
version is looked up in Maven local repo
pom.xml
files to whatever *-SRC-revision-{commitId}
was requestedpublic class Demo {
public String sayHello() {
return "Hello World!";
}
}
public class DemoTest {
@Test
public void sayHelloTest() {
Assert.assertEquals("Hello World!", new Demo().sayHello());
}
}
junit
public class Demo {
public String sayHello() {
return "Hello World!";
}
}
public class DemoTest {
@Test
public void sayHelloTest() {
Assert.assertDevConf(new Demo().sayHello());
}
}
Add what is necessary
public class Assert {
public static void assertDevConf(String actual) {
assertEquals("Not the right conference!!!", "Hello DevConf!", actual);
}
...
Commit and push whereever appropriate
srcdeps
configuration in the depeendent projectmvn org.srcdeps.mvn:srcdeps-maven-plugin:3.0.1:init
That generates .mvn/extensions.xml
and .mvn/srcdeps.yaml
files
.mvn/extensions.xml
<extensions>
<extension>
<groupId>org.l2x6.srcdeps</groupId>
<artifactId>srcdeps-maven-local-repository</artifactId>
<version>3.0.1</version>
</extension>
</extensions>
Much more powerful than the plugin API
.mvn/srcdeps.yaml
configModelVersion: 2.0
repositories:
junit:
selectors:
- junit # a groupId[:artifactId[:version]] pattern, optionally with * wildcard
urls:
- git:https://github.com/ppalaga/junit4.git
junit
in the dependent project...
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.13-SRC-revision-fd0a1c029b99277c955417b0c2b294000d9bf7f4</version>
</dependency>
...
cd srcdeps-demo
mvn clean test
...
Failed tests:
sayHelloTest(org.srcdeps.demo.DemoTest):
Not the right conference!!! expected:<Hello [DevConf]!> but was:<Hello [World]!>
...
Fix Demo.sayHello()
to return "Hello DevConf!"
cd srcdeps-demo
mvn clean test
...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...
BUILD SUCCESS
Q.E.D.
${local.maven.repo.dir}/../srcdeps/${groupId}
, typically ~/.m2/srcdeps/${groupId}
srcdeps
featuresDependencies can refer to not only commits, but also branches and tags:
1.2.3-SRC-revision-{myCommitId}
1.2.3-SRC-branch-{myBranchName}
1.2.3-SRC-revision-{myTagName}
Source dependencies work for vitually any kind of a dependency incl. parent, managed imports and even plugins
Configurable via .mvn/srcdeps.yaml
:
-Dcheckstyle.skip
-DskipTests
by defaultbuildTimeout
failWith: {goals: release:prepare}
to prevent releases with source dependenciesAs long as deloyment of artifacts to public Maven repositories is meant
NO
Because tools unaware of srcdeps
will see the -SRC-
deps as non-available
Delivery of binaries to production?
Why not?
Can you think of any?
srcdeps
(IDEs, static pom.xml analysers, …) will see the -SRC-
deps as non-availableHowever immutable git commits are, they can still disappear from repos, or even the whole repo can be deleted
srcdeps
only against your own repos or your own mirrors of third party reposThere is still a few things that may differ among devs: java version, mvn version
mvnw
with a fixed mvn version
The -SRC-
artifacts (jars, wars, …) built by you and me will typically not be binary equal
srcdeps
Dependency project dead or not releasing fast enough
Dependency project doing nasty things
srcdeps
Created around October 2015 during my time in Hawkular https://github.com/hawkular/
Pull request to introduce srcdeps
to WildFly Core open this week
srcdeps
will be allowed in pull requests but will not be allowed to be merged to stable
branches, such as master
→ a partial productivity win for the submittersrcdeps
project statusContributions welcome!
srcdeps
Thanks!
/