To clarify, I was talking about building solutions via CCNET.
* Build breakages should be the exception, rather than the rule. You CAN see
what broke via the dashboard - look at the build log, see what files were
checked in since the last successful build, etc. Sure it takes more than one
single click, but its not a regular occurrence so no excuse for being lazy.
Plus you can easily see the actual build error messages, same ones as you
get in VisualStudio, even get them emailed around... and if you set your
build environment up properly it'll be pretty easy to figure out what any
build-breaking problem is.
* The solution file is just as much a part of the source code as any other
file, and ought to be in source control too. Therefore, yes developers
should be expected to use the same solution file as each other AND the
autobuild. Sure you can change the file for whatever reasons you need
(debugging, moving projects, whatever)... but as with any other file, good
development practice dictates that you never check in any build-breaking
change. If your team all update before committing, then you'll probably find
that collisions are rare, and even then they can be resolved just like a
collision in any other file. And if you find that you are constantly
tripping over each other's solution file changes then frankly it sounds like
your project structure is a mess and you've got bigger problems than just
your build process.
* Regarding unit testing: Our developers hardly ever run unit tests locally,
the build process does it all for them (they're getting lazy!!!). Adding new
unit tests or unit test assemblies also doesn't require changes to your
build config - again if you set it up right, CCNET really can be a low
maintenance 'fire-and-forget' build process. If you are testing internal
methods then it is no longer a unit test - and the majority of TDD
practitioners see it as somewhere between 'a waste of effort' and 'bad
practice'. Even if you must do it, there are still ways of doing it from a
separate assembly ('InternalsVisibleTo' attribute, reflection with
appropriate flags, etc... Google is your friend). And for your sake, I
really hope you are not compiling your unit test code into the same DLLs you
are releasing!
* I've yet to come across any situation where components required for the
deliverable were also required (a) not to be in source control and (b) not
to be available for the developers. API documentation can be built
dynamically. Images can be embedded as resources. Config file can and should
be controlled with good serialization practices. And most other application
'content' usually winds up coming out of a database of some sort, regardless
of whether its a web app or forms app. Why you would ever want to prevent
your developers from accessing X (where X is an integral part of the
deliverable they are developing) and still expect to include X in the
deliverable and have it function correctly is a mystery. Either you work for
the NSA, or you have some serious trust issues in your workplace... and
given you're coding in .Net, I highly doubt it's the former.
* Obfuscation, encryption, licencing etc. can all be automated if you take
the time to figure out how to do it properly. Eg. we encrypt all our
database connection strings in the config files, so the production user
password is never stored in plain text.
* A build is a build, and the same build should go through the same process
whether run manually on a developers machine or automatically on a CCNET
server, and produce the same result. If it is not possible for your
developers to do a full local build then it is not possible for them to tell
whether they have broken anything. Take a look at the bigger picture and
you'll realise your entire output is nothing but deliverable logic anyway.
That includes pre-and postbuild events too... by the way, these are stored
in the project file not the solution file, so regardless of your opinion of
them, they have no bearing on the discussion of whether to take a
project-based or solution-based approach to your build process.
Solution files can be a very useful tool in a well-designed build
environment. Much like a nailgun - if used correctly you can you can build a
whole house much faster and with less effort. If used incorrectly, of course
you can nail your own feet to the floor too.
Disclosure: I wear both hats - developer, and the sole buildmaster of a
continuous integration server farm working on over a million lines of code
for a billion dollar branch of a Fortune 100 company. On average I spend
maybe 1-2 hours per week (total) doing "buildmaster" work: maintaining build
processes & environments across all the various development projects in the
server farm. The rest of the time I can actually spend doing "developer"
work, on my own development projects. To date nobody else has ever had to
modify any of our build processes (although they could if they wanted to). I
could not achieve this level of productivity without the flexibility of
solution files!
(and of course many congrats to the CCNET dev team, for having a product
stable and flexible enough to be deployed within at least one Fortune 100
company!)
Cheers,
- Sam.
On Fri, May 8, 2009 at 6:32 PM, ogaz <[email protected]> wrote:
>
> All - thank you for your responses. I really appreciate the
> perspectives and insight.
>
> Based on some of the responses I should re-clarify that I'm not asking
> about how best to build projects within Visual Studio, but asking what
> is best when building projects via CCNet (i.e. automated builds and
> continuous integration). It is a given that using .sln files when
> building within Visual Studio is the logical and best choice.
>
> If one builds with a solution file then when it breaks, one would only
> see (using ccnet web dashboard or cctray) that the solution broke and
> not which actual project broke. This can be rather uncomfortable for
> debugging if there are many projects in the solution. Also, doesn't
> this go against the benefits of having an automated build system, that
> is, so that we can what code is working and what code is not working?
> If we just use a big, all-inclusive green-light/red-light approach, we
> lose out on useful feedback that the build system can (and should,
> IMO) provide.
>
> Generally speaking, we cannot presume that there would be a
> single .sln file that all developers would use, so that would go
> against the reason for the build process to use the same .sln file
> that is being used by the developers. Developers sometimes move
> things around in a solution for debugging purposes, with an example of
> this being when a developer changes to use a project reference (and
> includes the project into the solution) instead of an assembly.
> Because of this, developers don't always use the same exact .sln file
> or, if they do, there can be frustration amongst developers because
> the .sln file is being changed between them.
>
> As far as having to go through the trouble of having to add a new
> project to the build script when a new one is created, this also only
> takes a small bit of time and the need for the project would be caught
> either when the build breaks and/or when testing occurs. This is just
> a simple maintenance task and would be required anyway for any new
> unit tests that would need to be added and executed as well.
>
> To rely on developers running unit tests is unfortunately urealistic.
> We all know that developers running unit tests is the ideal situation
> but doesn't always happen (and in some shops/teams/groups, does not
> happen at all); this is why automated unit tests are implemented in
> build scripts, is it not? That being said, the unit tests then need
> to occur after a project builds which works with building per
> project. I agree that ideally unit tests should be in their own
> separate project, but that is not always the case (e.g. testing
> internal methods). IMO, unit tests should also be written with the
> smallest scope possible, when possible, and that would mean that they
> can be project-based; thus, there should be no "uphill battle". The
> projects are built in a queue (defined by projects that are dependent
> on each other) so there would be no outdated versions of a project
> when testing. One thing that I can see here however is an argument to
> not run unit tests on projects until after all other projects
> (regardless if they are required or not for the project unit test) are
> built successfully; this can be beneficial so as not to hinder the
> build queue (though this could be resolved by not allowing failed
> tests to fail the build queue).
>
> If a project requires resources that are not in the developer-
> accessible repository then using the .sln file that a developer uses
> will not work, since a developer may not have (or should not have)
> access to them. An example of this is if there a content files like
> report documents or many .jpgs, .pngs, etc, that need to be included
> in the deliverable but are kept in a separate not-accessible-to-
> developers repository.
>
> If a project requires obfuscation or any other special processing then
> this also would not comfortably work if using a .sln file, since there
> could be licensing, permissions, encryption, etc, constraints. This
> special processing could of course exist in some post-build or pre-
> build event using some conditional that checks to see if in or on a
> specific environment, but now that would put deliverable logic in the
> code and I don't think that is a good idea since it blurs the area of
> responsibility between a build master (or deployment team or technical
> operations department) and the developer or development teams. IMO,
> there should be no dependency this way between the source code and the
> automated builds; the source code should exist on it's own.
>
> Does this make sense? Thoughts?
>
> On May 7, 8:22 pm, Sam Calder <[email protected]> wrote:
> > I agree with Brendan. My point of view:
> >
> > > Reasons to use project files and NOT use solution files:
> > > 1. A .sln file could be modified by a developer for, let's say,
> > > debugging purposes, and that could cause the build process to fail
> >
> > ...and any developer that checks that in & triggers the build needs to be
> > beaten about the head with a cluebat, same as anyone else who checks in
> any
> > other build-breaking change. Solution files generally don't actually
> contain
> > much more than GUIDS, project references and build configs (and if you
> are
> > unlucky enough to use SourceSafe, source control bindings). It's pretty
> hard
> > to screw up a solution file.
> >
> > > 2. Solution files can use paths that do not work with the build
> > > process
> >
> > Not if they're referenced correctly (IE. relative paths), and your source
> > control is structured appropriately.
> >
> > > 3. Using solution files goes against having small, more granular
> > > builds because this would require that a whole solution is retrieved
> > > from the repository
> >
> > Solution files give you a useful layer if indirection. Nothing's stopping
> > you having a solution file that contains one project, if you want. And if
> > you have an entire enterprise platform with 50+ project files in one
> > solution then yes you should consider breaking them up into separate
> > sensible solutions based on architectural purpose (data layer, common
> code,
> > web service, server, client, etc...), with binary dependencies. But you
> > don't have to break it up into 50+ separate build processes, nor do you
> have
> > to consolidate projects just to reduce the number of builds or build
> > complexity.> 4. Automated unit tests cannot (or at least easily) be
> executed upon
> >
> > each project build, but would rather have to be done after the whole
> > solution builds
> >
> > Per my response to #3, if your solutions are small and sensible it
> shouldn't
> > be that big a problem. In fact you may find you can reuse some of the
> test
> > setup/teardown test code, mocks, etc. too.
> >
> > > Reasons to NOT use project files and instead use solution files:
> > > 1. Requires more work to setup the builds
> >
> > ...and it requires more work to maintain the existing builds too. You
> build
> > project-by-project, any time a new project is added, or renamed, or
> deleted,
> > you need to manually modify your build config. I use CCNET to build
> > solutions, you use it to build projects. I set up my CCNET build config a
> > year ago, it's maybe 30 lines long and it's hardly been modified since,
> > despite the fact my team has added maybe 20 projects to the solution file
> in
> > that time. Building from solution and having a sensible source-control
> > hierarchy makes it possible to incorporate changes automatically and
> > effortlessly.
> >
> > > 2. using project files can require having to contend with false
> > > positives when a changeset covers many projects within the solution
> > > and a build cycle detects and starts building projects out of
> > > "order" (this can be resolved by always building a whole queue from
> > > the beginning, upon a detected change, of course).
> >
> > A good reason to use solution files, yes. See my response to #3... split
> > your entire enterprise solution to sensible layers & components, use good
> > interface-based design to split dependencies where appropriate, and
> you'll
> > find changesets of the type you propose don't actually happen very often
> -
> > and when they do, well you've already chained builds between your
> solution
> > files to accomodate it anyway...
> >
> > One additional benefit you neglected to mention - as a developer you open
> > and build the solution file. If your build process opens and builds the
> same
> > file you can easily guarantee what the developer builds is what the build
> > process will build. This reliability is extra important if you rely on
> your
> > build process to create releases.
> >
> > My $0.02. I'd recommend using solution files whenever possible, and only
> > dropping back to projects if absolutely necessary.
> >
> > Cheers,
> >
> > - Sam.
> >
> > On Thu, May 7, 2009 at 8:10 PM, Brendan Crosser-McGay <[email protected]
> >wrote:
> >
> > > Rebuttal to Reasons to use project files and NOT use solution files:
> > > 1. Solution files maintain internal consistency of environments across
> all
> > > projects connected together. Make as many environments that you need
> when
> > > you start the project and the solution file allows you to switch
> > > environments across all projects, and make sure that they are all in
> sync.
> > > That's why each project should at least have two environments, Debug
> and
> > > Release. Developers who check in changes that break the build is
> actually a
> > > useful metric, and can encourage a team to run their unit tests before
> > > checking in so they don't break the build. Besides, sometimes a broken
> > > build on a solution can reveal weaknesses that need attention.
> >
> > > 2. You are going to have larger issues if you have static paths in your
> > > solution file. Visual Studio automatically uses dynamic paths in your
> > > project so it doesn't matter where the solution file and project files
> are
> > > as their base, as they can be loaded just about anywhere. The solution
> file
> > > should be seen as a "grouping" of files together under a single
> umbrella to
> > > achieve a common goal. There isn't an easy way (in visual studio) to
> > > signify that a certain set of files are essential to the entire set of
> > > projects besides using solution level folders and files.
> >
> > > 3. If you have special needs, make lots of solution files, you can use
> the
> > > same projects in as many solutions as you like.
> >
> > > 4. The act of an entire solution either passing or failing by means of
> it
> > > building is usually a very important metric. Unit tests are typically
> > > contained in a separate project, and thus you would have an uphill
> battle
> > > trying to get useful test results if you were building and testing all
> > > projects independently. Interdependence testing across projects would
> be
> > > sacrificed if it's possible to test one project based on outdated
> versions
> > > of another project.
> >
> > > Rebuttal to Reasons to NOT use project files and instead use solution
> > > files:
> > > 1. Creating a solution in Visual Studio, and then adding specific
> projects
> > > you need for the build to function is trivial, and can be done in less
> then
> > > a minute or two (depending on how fast your PC is.), all visual studio
> > > slowness aside. :) I know I have a number of projects in my source
> control
> > > that are used in multiple solutions with much success.
> >
> > > 2. Visual studio manages this, and resolves dependencies.
> >
> > > No disrespects meant, but have you been using Visual Studio for long,
> or
> > > are you coming over to it from another IDE or language entirely?
> Developing
> > > in Visual Studio would be quite difficult without using the "solution"
> > > system built into it, especially when developing a number of different
> > > interdependent projects. The best example I've found so far is
> > > CruiseControl.NET's source code itself, as it's built in C# and uses a
> > > solution file with a number of dependent files included.
> >
> > > Cheers,
> > > Brendan
> >
> > > On Thu, May 7, 2009 at 4:56 PM, ogaz <[email protected]> wrote:
> >
> > >> I am hoping some of you can offer some thoughts on this--
> >
> > >> I am trying to list reasons to use Visual Studio project files instead
> > >> of Visual Studio solution files to build projects (e.g. CCNet -->
> > >> MSBuild task --> .csproj instead of CCNet --> MSBuild task --
> > >> > .sln). I am of the thinking that ideally it is **generally** best
> > >> to build using project files instead solution files.
> >
> > >> Reasons to use project files and NOT use solution files:
> > >> 1. A .sln file could be modified by a developer for, let's say,
> > >> debugging purposes, and that could cause the build process to fail
> > >> 2. Solution files can use paths that do not work with the build
> > >> process
> > >> 3. Using solution files goes against having small, more granular
> > >> builds because this would require that a whole solution is retrieved
> > >> from the repository
> > >> 4. Automated unit tests cannot (or at least easily) be executed upon
> > >> each project build, but would rather have to be done after the whole
> > >> solution builds
> >
> > >> Reasons to NOT use project files and instead use solution files:
> > >> 1. Requires more work to setup the builds
> > >> 2. using project files can require having to contend with false
> > >> positives when a changeset covers many projects within the solution
> > >> and a build cycle detects and starts building projects out of
> > >> "order" (this can be resolved by always building a whole queue from
> > >> the beginning, upon a detected change, of course).
>