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!
srcdepsParts 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());
}
}
junitpublic 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.yamlconfigModelVersion: 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 defaultbuildTimeoutfailWith: {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
srcdepsDependency project dead or not releasing fast enough
Dependency project doing nasty things
srcdepsCreated 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!
srcdepsThanks!
/