On 07/05/2011 6:59 PM, David McCabe wrote:
Thanks for the information. I think I may need to clarify some things.
Our applications are made up of a few dozen components, some of which
are shared between projects and some of which are project-specific.
Each of these components currently has a 4-component build number
"major.minor.patch.build". When building a component, its build number
is incremented. A new major, minor or patch version resets the build
version to zero. I'm happy to change a dot to a hyphen, and I'd also
be perfectly happy for that build number to be a Subversion revision
number, but I'm not happy to go for a SNAPSHOT-style date/time: try
telling someone your latest version is "3.6.0.20110507170144".
A SNAPSHOT is not a release and ideally should never be spoken off outside
the immediate team and even then you need to explain what a SNAPSHOT
does and does not yet do and what are the restrictions on its use and
where
it does not respect the specifications. Or you can just let the other team
members curse you out when they spend hours trying to find out why their
software does not work when they use your SNAPSHOTs.
SNAPSHOTS are very useful but version 1.3.5.6 is not the same as 1.3.5.6-
SNAPSHOT.
One comes with a warranty and the other comes with a warning.
Absolutely, but therein lies the problem. If we were to use SNAPSHOT, it
would be 1.3.5-SNAPSHOT. In Maven terminology, this would result in you
eventually 'releasing' a 1.3.5-SNAPSHOT as version 1.3.5.
Our problem is that the builds that get tested are, presumably, SNAPSHOT
builds of each of the components modified since the last project release.
The 'Maven way' of doing this appears to be for every candidate for project
release, I 'release' every component.
You deploy a SNAPSHOT until you are ready to release 1.3.5 or release
1.3.5-RC1 or you want to create a release candidate. We don't use this
but I think that a lot of people do this.
If the testing fails (or a product
manager changes his mind about how a feature should work, e.g. from beta
feedback) then we would wind up 'releasing' each component modified in
making that change before we had a build that could again be a 'release
candidate'. Is that correct? This seems to make Maven 'release' more of a
'make-release-candidate' - and really quite time-consuming.
I think that you are right here.
We have made sure that our modules are functional and are working
towards better SOA with every release so we do not have a lot of
functions that cross modules.
Changes tend to be local once we get close to releases.
Using Betas and RCs will help if you are prone to late cycle changes in
functionality.
It is not that hard to change the version ID in each POM. Takes a few
seconds for each POM. You can automate this with the maven release
plug-in if you think that this is too much work to do this manually. We
don't do this but you can get others in the forum to guide you in this.
This isn't a Web application - this is a 60-component medical imaging
workstation, and the component dependency graph is deep rather than broad. A
change can be only a line of code but still result in a rebuild of many
components.
Doesn't change things very much.
Not sure why a single line of code should result in rebuilding more than
1 module.
You will have to rebuild the assembly of the application so I see only 2
modules being rebuilt in your example.
Maybe the idea is that one can 'release' all of the components after
testing? My major concern is trying to convince our quality team that having
built the application against one set of versions that another set of
versions are fundamentally identical.
You test the release after you build it. One hopes that the release is
the same as the last release candidate and only requires some very
limited functional user testing after the automated tests are run.
Is there some way for me to check that
a component's build-time transitive dependencies' versions were all
'released'?
Only use releases versions of dependencies in your build. You will get
what you specify. If the POM that builds your run-time application calls
for 1.3.5 of dependency A, then you are sure that your application is
using version 1.3.5 of jar A.
What I want, therefore, is a system in which, for a set of top-level
components to be built, it would then evaluate the set of transitive
dependencies of those components as specified in Subversion (not Nexus
I don't think so. You tag and branch the Subversion versions based on
the things that you build.
or
the local repository), work out the complete list of out-of-date
components
to build and then build all of those components such that the top-level
components represent the current state of Subversion. Plainly, if the
build
is up-to-date with Subversion, nothing should be built.
Too much work. Just run a clean development workflow and do things the
Maven way and your life will be much more pleasant and your development
team much happier with each other.
Guys who release crap will soon find out that their friends will jump on
them and the boss will know that a crappy piece of software was released
when it was still at the SNAPSHOT stage.
Alas, this is a large project but not a large team, and many components do
not have single ownership because there just aren't enough people to do
that. There are five of us across three projects and the component
versioning process is a means to allow us to manage this size of project. I
have to be absolutely sure that each check-in that any of us made has made
it to the installer. I currently do this manually, and it's very
time-consuming and error-prone (particularly since we're on CVS, so I can't
just look at the revision log since the last build...). If a change has
occurred a long way down the dependency tree, it needs a way to propagate
upwards.
We are a team of 2 but used to be 3 with over 80 modules making up 2
distinct applications with no code overlap.
Ownership is not an issue if you use Subversion, Nexus and Maven
properly and have a good modular design.
The POM file with its description of the modules dependencies is the
gospel over Subversion.
If the POM says that you built version 1.3.5.1 of your module A with
version 1.3.5.0 of dependency B, that is what you did.
You don't care what Subversion says about your modules A or B.
In your current system, you spend a lot of effort controlling code
versions because your build system does not care about versions so you
are forced to look at Subversion or CVS to control versions.
Once your build system (Maven) starts to care about versions and
guarantees that builds use the right versions of all your dependencies,
your life gets a lot easier.
You can commit anything to Subversion that you want to share, regardless
of the state of the code because anyone who checks out a module can see
from the POM which version the code is supposed to be building.
If you build a release or SNAPSHOT using your Nexus dependencies (My
advice is to never build with a workspace artifact.) you will know
exactly what you are getting regardless of what state the Subversion
code is in.
Even if you forget to tag the Subversion version, you can find the right
version of the code by looking at the Subversion history to see when the
POM changed.
It is easier if you handle Subversion right but not fatal if you don't.
Getting people to put useful comments on every commit to Subversion is
really helpful.
SNAPSHOTS are a powerful tool to help a team work together.
Stubs, partial implementations can be shared as SNAPSHOTS.
The person providing the SNAPSHOT and the person using it need to
communicate so that as the SNAPSHOT dependency gets more functionality
and fewer bugs, the person writing the code that depends on it is aware
of the state.
I am trying to find out what the 'Maven way' is for each of these issues,
but there has to be flexibility. Maven is the closest thing out there to the
system we have right now, and I would much prefer to use it than to bolt on
additional functionality to our large Ant script collection... but if it
won't fit our organization, then it is Maven that will go.
Ant and Maven are based on completely different philosophies.
I don't see anything yet that you are doing or building that could not
be handled by Maven.
Thousands of teams are building applications like yours.
Try to adopt the simplest Maven approach and then add complexity later
if you see a clear way to optimize your workflow.
Trying to optimize your use of Maven at the start can get you into a
complex and poorly structured set of Maven modules with too many obscure
plug-ins.
My impression is that you need to use the compile plug-in and the
assembly plug-in to build the Desktop jar.
My advice is to start out by taking the time to manually manage the
updating of the POM versions until you get comfortable with the workflow
and then see how this can be automated or simplified.
We opted for simplification over automation and put in the time up front
in a new release to plan how the versions of all of the modules that
make up the application will be affected by the proposed changes.
We have decided to treat our own modules in the same way we treat third
party modules.
We do not force all of the modules to have the same version number.
If module B is not affected by the change, version 1.3.5.1 of module A
can depend on version 1.3.5.0 of module B. We start with module A
version 1.3.5.1-SNAPSHOT depending in release 1.3.5.0 of module B.
This reduced the effort required to manage the project when adding new
features or fixing bugs which have limited scope.
I hope that this helps you give you the confidence to move forward.
Ron
Thanks,
David
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]