Some progress on continuous deployment

As I posted a couple of weeks ago I'm working on working a continuous deployment setup so that I can push changes live quicker and easier for the projects I'm working on. I've installed and configured Hudson, which was a good first step. It's shown me that my builds are a bit fragile, they're heavily based on packages that I've compiled and installed into my local Maven repository. To solve the problem and to make my build a little more sensible I'm getting Artifactory working. At this stage I'm just trying to get a very basic system in place so that I have an idea of how long a deployment will take. It's a little more complicated because I'm using Java and the WARs contain all the libraries. I could just use the defaults and push a deployment directly to the target servers, but that doesn't work. First wars are big, they can easily weigh in at 20Mb. There are a couple of things I could do here. Ideally I could unroll all the jar libs and only include the classes I need. That would drastically reduce the size, as a bonus I could probably also have it give me a warning that I'm including an unused jar, even better if I could work out the path to the maven dependency. But there's the whole problem of resources, the fact that using Springframework means most of the classes aren't being explicitly called and the fact that since I don't know anything that does all of this this, I'd have to write it all. So I've written that whole idea off, and added a shorter to-do item to make sure I'm only including jars I need. Instead I've gone for a far easier solution: deploy exploded wars, and use rsync so I can push only changes to the server. The next step is to get trigger a Hudson build with a commit-hook and use a successful Hudson build to trigger a script that does the rsync. Then I'll have very basic continuous deployments up and running albeit without any automatic roll backs of a failed deployment which ultimately is a must, but it's a start.

Continuous Deployment

I've been working lately trying to implement some of the things Eric Ries talks about. Primarily the idea of continuous deployments for lean startups and getting away from the fear of release. On the surface and looking back on some of the disastrous releases I've seen (deployed) it's a frightening concept. The problem with most of those releases though hasn't so much been that there was a bug or a problem, it was there was no fall back position - the release was made and there was no way to unmake it. Also working in Java releasing WARs has been a pretty big issue - you have to upload the whole release to fix even a small bug like a typo. One bug in these cases can mean you're 15-20 minutes from uploading a fix. It's a very bad place to be and I want to avoid it at all costs in the future, both the problems and as a result the fear of a release. With that in mind I've been fashioning a system for Sproozi where a release is made as an exploded war using Hudson. On commit it's tested, deployed to a single server in the cluster and tested some more. The server joins the main cluster and it's monitored as the release is pushed to the rest of the servers to make sure it's stable. The only problem I'm having conceptually is how do I treat a commit that comes in before a release is finished - I guess I have to sit on it, but what if the release fails and I have to lock the repository? What about if the release is a success but in the meantime I have 2, 3 or even more commits that I'm sitting on? Do I deploy them one at a time until they're either all successful or one fails? How has anyone else practising dealt with these issues?

Stop asking questions.

I've had an ongoing conversation with a few people over the course of a few projects about the questions to ask when people sign up on the web or what hoops you make them jump through. Ask most people what they need to know about user's and you'll end up with a list of information from the useful like name to the truly useless like job title or title. Give me one good reason for either. Are you going to be sending Mr John Smith or Dr. Sarah Jones a letter using their formal titles? When it comes to things like Job Title, the reason I usually hear is that it'll be useful for marketing and demographics later. Maybe, but I've never actually seen that later come to anything. So I don't buy it. If the signup form is the depth of your engagement with your user you might as well drop the pretense of a web application and go back to sending newsletters. Just don't do it. Ask your user the bare minimum number of questions you need to get them started using what your product does now and stop throwing up barriers to entry. Aside from just the questions that are asked there are other things, the hoops almost every site makes you jump through before you can start using it. Probably the best example is the ubiquitous confirm your email step. Do we need to be doing this? In some circumstances I'll admit it makes sense, if your delivering content via email for example or signing up for a mailing list. Of course you want to make sure the user wants what you're sending them. But for every other site, I'm not sold. It's just another step they have to take to start using your service and all the little steps all add up to users hating signing up for new things. Also it begs the question, why even bother? For 99% of websites the only reason to make sure a user has entered their email address correctly is so that you can let them recover a password. You're adding the step for people that have lost their password and haven't managed to get their email right. That's going to be a fairly small proportion of your users; even less if you let login with their email address, then they'll know it's wrong anyway as soon as they try it. Do we pander to the idiots or make things as quick and easy for everyone else? I'll take quick an easy any day. I'm finding myself not just asking what any given field in a form is for and making it justify it's self, I'm trying to figure out how to get by without it. I'm leaning towards going beyond just the bare minimum and into the realm of how can I modify this service to work with even less.

Openness, strength or weakness?

Media_httpandrewmccal_afsnv
As I've announced here, we've recently taken the difficult decision to put development of Citrus in hold, indefinitely (let's be realistic, probably forever). I'm now wondering what if anything we should announce about our new project. Is openness a strength or a weakness? Is there value to the community in publicly documenting our design decisions, and how we've come to them? Is it something our competitors could and would use against us? Is there anyway to mitigate the effects? I like what Jeff Atwood and Joel Spolsky have done with their series of podcasts on the Stack Overflow blog where they've released their design meetings as a series of podcasts and given us all an insight into how they've come to some of the decisions they've taken. But let's face it I'm neither Jeff or Joel and I don't get anywhere near their traffic. So the first obvious question I'm asking myself is if it's even worth the effort of writing posts, let alone recording and releasing podcasts. Next is the question about maintaining a competitive advantage, given the fact that our team is so small, just the two of us at the moment; I'm only working about half time on the project and Simon, who isn't a coder is working even less. So giving someone a guide to competing with us could be downright foolish. Then again, nobody is really listening are they? So does it even matter? The other question, which I think is equally important as the project grows - hopefully into a product is what if any level of openness is appropriate post launch? Will an open discussion of ongoing design decisions as they're being taken before, or even as they're released be of any benefit to the community? Communities can be some of the biggest supporters and can be some of your most passionate users - sometimes these passions can work both ways? What level of support ongoing will a public discussion of the decisions you're taking, before users have all the prototyped interfaces to play with, be required? Is there an ongoing effort you'll need to make to maintain the level of trust and confidence of the community? I think I've talked myself out of a podcast of our internal discussions, for now - but I'm still keen to use community interaction to help us develop a product that meets the needs of the people who are interested in using it and to drum up support and interest in the project. I'll no doubt return to this topic in the coming weeks as I develop a clearer idea of how I think we should accomplish that. If any of the few of you out there listening have any questions or comments, please let me know your thoughts.
Media_httpimgzemantac_jfgih

Interfaces first

Don't write spec documents, throw away any you have near you, they're next to useless anyway. It might seem like a hearsay to some but it's true and deep down even the most most anal planner in all of us knows it. Two of the biggest reasons for this are:
  • size and scope: In order to address every aspect of your project a full specification document has to, well address every aspect of your project and it's going to be huge as a result.
  • lack of vision: For most people relating what's written on paper to a vision of a design in their heads is difficult if not impossible.
Loose documents don't work well either, because leaving the obvious unsaid just leads to problems, chiefly not everything is obvious to everyone. The devil is in the details and avoiding them until the end of a project is just going to cause trouble. "Why haven't we implemented x, that should have been obvious!"

create the interfaces

Prototype the interfaces and use them as your spec. Working this way has so many benefits, try it once and I promise you'll be converted. Before you write a single line of backend code, sit down and work out your interfaces. Build each screen, put all the buttons, fields and elements on the page I normally start with index cards and write a few simple requirements for each screen or page - just a few simple sentences listing what the page is expected to achieve. My next step is to turn those requirements into interfaces.

in HTML, not photoshop

Photoshop is great, but let's face it it's no better for trying to work out a functional interface prototype than some paper and a pencil. It's very easy to focus on making things look pretty over making them functional and you risk missing something important out. The best way to avoid both of these traps is to write your interfaces in HTML, mark them up semantically as they will be marked up in the release and use them as your working spec.

I know good design but I'm no designer

Another benefit of coding up your interfaces in HTML before you start writing code is you can hand them off to designers so they can make them look pretty as you're working on making them work. I have a pretty basic idea of design principals and the tools - but I find it hard work. So with interface first development I don't have to think about it.

let the testing begin

Another thing which is made infinitely easier with interface first development is functional testing, because your testers don't have to wait for a release before they can start developing a test suite. You are using an automated test suite aren't you? By generating interfaces as developers add functionality testers can already have been through the interfaces and written a whole series of failing tests.

updating later

The great thing about using HTML as your design and communication tool is that when it comes to making a change to a page you have the most up to date working copy there ready to modify in the form of your site. Just save the page, add the change to the HTML and you've got your interfaces ready for discussion and later implementation. What could be easier, faster or more clear for everyone?

it's not a panacea

There have been times when I've been working with notoriously difficult individuals where nothing was going to satisfy. An exmaple that springs to mind is a multi month project where we produced an interface design early in the project. The design was a set of PDF images not HTML (see above), but the delivered product was a pixel perfect implementation of it. Only once the project was delivered was there any input on the design or functioning of the project - I'm not just talking things that a PDF can't show you like what clicking a link looks like. I'm taking basic things like colours, layout and the size of elements! Would a HTML mock up have made any difference, I actually doubt it. I take blame for miscommunication and resulting mistakes when it's my fault but in this case even after the site was fully developed and deployed to a staging area for testing none of these issues were highlighted. It was only after the site was put into production that these "critical issues" were discovered.

Setting subversion up to work with contractors

In my last post I promised I'd write another about subversion and how to set things up to work with contractors. I was supposed to post this the next day, but I got caught up with other things. Anyway, let's just jump right in... We run all our projects out of one big subversion repository, some people create a repository per project or group projects into a number repositories. In all honesty it really doesn't matter how you group things, I think that one repository works better for us, I can move things around and I can allow people access to all or parts of the repository. You may feel differently, but for the time being I'm going to assume you're working with a single repository like us.

getting started: installing apache, subversion and mod_dav_svn

I recently upgraded to Subversion 1.5, there wasn't a package available for the version of Fedora we're running on our server so I had to build it. It was a relatively painless process of simply making sure dependencies existed and following the instructions in the INSTALL file. http://subversion.tigris.org/getting.html Go do that now, get subversion and mod_dav_svn installed. There are more than enough resources out there on how to install subversion that I'm not going to go into too much detail about building from source or installing on any specific platform. In fact since the steps and concepts I'm going over in this post don't require a specific version I'll just throw up some common defaults. If you're on a Red Hat based linux system try: # yum install subversion # yum install mod_dav_svn If you're on a Debian based system try: # apt-get install subversion # apt-get install libapache2-svn In your apache configuration file, near the module declarations make sure you have the following lines. LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so

setting up a repository

Again moving quite quickly here, there are tons of other better resources for getting started with Subversion on the web, better than I could hope to write. The basic command you need to run simply creates the directory structure that subversion needs. $ svnadmin create /path/to/repo It's usually best to create this somewhere near, but not in the document tree for the webserver. Open you're apache config file, or the config file that stores the details for the virtual host you're using and add the following lines: DAV svn SVNPath /path/to/your/repository AuthType Basic AuthName "Subversion repository" AuthUserFile /path/to/your/passwdfile Now create the htpasswd file and add a user or two using the following commands # htpasswd -cm # htpasswd -cm /etc/svn-passwd andrew New password: Re-type new password: Adding password for user andrew # htpasswd /etc/svn-passwd -m simon New password: Re-type new password: Adding password for user simon Restart apache and that's it all done. You should now have a running subversion repository with two users, andrew and simon, they should be able to view and commit anywhere. We'll assume these are staff members who can view and commit on any project.

Setting up for an external contractor

Now you want to bring a contractor in on a project, so let's create them a user: # htpasswd /etc/svn-passwd -m john New password: Re-type new password: Adding password for user john The next thing you need to do is to setup svnauthz to control access to the repository. Back in your apache config file, add the following line into your svn config: AuthzSVNAccessFile /home/goroam/dev.goroam.net/user/repos/svn-authz So that it looks something like this: DAV svn SVNPath /path/to/your/repository AuthType Basic AuthName "Subversion repository" AuthUserFile /path/to/your/passwdfile AuthzSVNAccessFile /path/to/your/repository/svn-authz I tend to keep my svn-authz file within my repository path, you may wish to place it elsewhere - whatever works best for you. The next step is to create the svn-authz file. That's as simple as this: [groups] staff = andrew, simon contractors = john [/] @staff = rw * = r [/external-project] @contractors = rw The file is pretty simple and self explanatory but the first block starting with [groups] defines the groups. In this case we've got two one for staff with andrew and simon and one for contractors with john as the single member. The usernames to use here are the same as you set in your htpasswd file. Authentication is controlled by the standard basic authentication, subversion is only controlling access. The next two blocks are paths within the repository. The first: [/] @staff = rw * = r Tells subversion to give all members of the staff group read and write access to everything under the / path - basically the whole repository. The next line * = r tells subversion to give everyone else, read access to everything. Again this may not work for you, but we tend to allow read access to everything to everyone with a password. If we trust them enough to give them a password, we trust them. Also it allows contractors to build dependant libraries from the head, which is required at times and saves us the trouble of working out dependencies in our svn-authz file. [/external-project] @contractors = rw In the next block, above, we're giving everyone in the contractors group read and write access to everything in the /external-project path of our repository. This of course is the project they're currently working, so your path will be different. That's it. Contractors hired, up and running in your subversion in minutes.

Slightly more complicated, but easy now that you know how

Let's just complicate things a little bit by adding two external contractors from the first company and a third from second working on two different projects. Let's say that CompanyA Limited are working on project-x. They've asked us to create accounts for Dick and Jane. Then we hire Dave from CompanyB to add a feature called zing-bang to project-y. You could, of course just create two accounts, one for each company - but we tend to avoid that. We like to know WHO committed what code. Not just where they were from, we work closely with our contractors and it helps us when we're communicating with them. We know how to create the users, but just to recap here we go again: # htpasswd /etc/svn-passwd -m dick New password: Re-type new password: Adding password for user dick # htpasswd /etc/svn-passwd -m jane New password: Re-type new password: Adding password for user jane # htpasswd /etc/svn-passwd -m dave New password: Re-type new password: Adding password for user dave Assuming, as above we have andrew and simon as staff users we should make our svn-authz file look something like this: [groups] staff = andrew, simon companya = dick, jane companyb = dave [/] @staff = rw * = r [/project-x] @companya = rw [/project-y/branches/zing-bang-feature] @companyb = rw We're only building slighty on the previous file with the groups entries, and that should be clear. The entry here for project-x should also look familiar - Both dick and jane, members of the companya group have read and write access to the path. For the next entry we've created a branch and we have company b working on the branch. I'm really just throwing that out there, mostly because I can, but also to show that you can go to any depth in the repository tree granting access as you see fit. In this case it's been determined that the work CompanyB in engaged to complete only needs to take place in this branch, so while they can read the whole repository they cannot write anywhere except here. This would allow you to continue internal development, or indeed external with some more entries on project-y making point releases while zing-bang feature is developed and CompanyB could merge the trunk in at will, since they have read access to it.

a lot of words

It was a lot of words, but the concepts are pretty simple. It doesn't take long to set subversion up and even with basic auth and htpasswd files it's not complicated to administer. So go on, get your contractors under control. I promise the dividends paid through increased accountability, visibility and communication will more than offset the time spent administrating the system.
Media_httpimgzemantac_smpaf

Get your contractors under control

In a recently conversation I was told of a situation which I've experienced in the past and I'm sure others have as well.
While on holiday the code I'm responsible for has been modified by an external contractor. Before my holiday I pointed out that we should make sure version control is used by anyone making any change. It wasn't. Now I'm frustrated and pissed off. The problem isn't that someone else was editing the code, or that I somehow lost control of a fiefdom or anything like that. It's that I've just spent hours I could be using to do something else tracking down file modification dates and then diff'ing them against my versions out of version control. Time I shouldn't have to had spent doing anything The bigger issue is now I'm under pressure by my boss to deliver some changes at the same time as I have to deal with this, and no extra time has been allowed for it.
You pay contractors to do work for you, a large part of that should be to insist they do it in a way that is consistent with your working practices. You wouldn't let them commit changes to a PHP website in ASP, Perl or Python and equally you should insist that changes are delivered consistently and in a manageable format. Warning flags get raised if someone tells me they don't use version control. Not knowing how and asking questions is one thing; I have no problem helping someone, a contractors included, learn our version control system and practices because I see our relationship as a long term one, so any investment in that relationship is worthwhile. If a contractor tells me they cannot or will not use our version control system though, we have a problem and usually we end the relationship then and there. It may sound like a hardline call based on a single criteria but it is a deal breaker for me. For a contractor there could of course be some concern that they've submitted the work and may not be paid. Version control is not the cause of this - it's dishonesty, plain and simple and if the person you're working for is that dishonest submitting code via email before the cheque clears is equally risky.  

Some ground rules

Our most basic rule is commit at least once a day while you're working on the project. This is especially the case if the work is being done on a day rate, but also if the project was quoted on a fixed rate basis. We use the data to judge if a project is on time, we're completely upfront about why we want this: Knowing the current velocity for changes gives us a really good indication of where we are in the development cycle. With a current version committed to our repository we can just checkout, deploy and see. It removes the chances of miscommunication, misunderstandings and estimate errors. Committing early and often by contractors is much like releasing early and often to users. It allows us to make regular builds and run QA on the project. The benefits of this are that we can start to run our testing regime long before we would otherwise be able to test. We try to encourage external developers to follow similar methodologies to those we use internally, the primary goal of any new project is to make a deployable release as quick as possible, then add features to it in a sensible manner. This coupled with regular commits allows us to test features as they're added, not weeks down the line days or hours before the project is to go live.

Once bitten, twice shy

We've had a few projects in the past where we outside contractors for a variety of reasons failed to deliver on time. This has lead to our losing a follow up contract on at least one occasion we're aware of. By getting code committed to our repository we can see where a project is, and if necessary step in early with concerns about the deadline. Both daily commits and QA help immensely with this and all but eliminate estimate errors because we can have an honest objective conversation about how far we're going to miss milestones very early in the process because a miss becomes obvious when you can see the velocity. The earlier you can do this, the better your chance delivering on time.

Rules for some, but not others

Sometimes it doesn't make sense to go the whole forcing version control down someone's throat route. For some projects and changes we'll just bang a few files into an zip archive, email it and get the same back, then integrate it ourselves. It usually depends on the scope of the changes and how long they're likely to be working on the project in question. We would only work with someone familiar or willing to learn version control though, even in the above scenario they'd would have to be willing to use it if we'd asked them to. How have your experiences using version control with contractors gone? Post a comment and tell us about it! I think tomorrow I'll post a bit of more hands on article on setting up version control for contractors. I'll try to focus a little more on how to build, install and implement subversion with access controls. See you then.

Get your development under control - all about version control

The key to any successful development team, far more than any other tool, is version control. No matter how many team members you have, if you're dozens of people spread across the globe or one lone developer in a basement you need version control.

A number of free and paid for systems exist, largely they accomplish the same ends: the ability for multiple developers to collaborate on the same code, the ability to track changes and the ability to manage changes across concurrent versions of code.

change management

This is potentially the biggest benefit of any source control system, the ability to manage changes in code. Most version control systems manage changes through a series of checkouts and commits by developers.

You check the code you want to work on our of the repository creating a local copy, make changes to the code and commit your changes to the repository again. Any developers that are working on the code can update their local copies an the changes you've made will be merged in.

This can be a massive boon, even if you're working alone. Version controls systems will also let you roll changes back, so if you've made a mistake, deleted a file or need to see how something worked before you can go back to any previous version.

concurrent versioning

Concurrent versioning is a great benefit when you've released software or are developing more than one major feature at the same time. It's the process of having two working versions of the code which can be edited independently.

In the case of a released version of software this allows you to release a patch before new features still in development are ready to be released. You can patch the bug, release an update to users and then use the version control system to merge the change into the development code so that your next release with the new features gets the fix too.

If you're working on a major feature you might also want to branch your code temporarily. This would allow you to perform some pretty significant refactoring on areas of the code which would not affect developers working on the rest of the code, when you finished the work you could then merge your code into the main development branch prior to release.

what else

For more information about version control see the excellent Visual guide to version control at betterexplained.com.

How to get started

There are a number of choices and a number of web based version control systems. Opensource subversion and git are used by a large number of people and compete on features with most commercial offerings. If you don't want to set up your own server to host a repository Google code, beanstalk and lighthouse are just a few web based services that can host version control environments for you. Google code is free, but you'll need to be developing an opensource project the other two are subscription services.

I personally use subversion and love it but with any version control system, commercial or free the most important thing is to pick and fit a system into your development environment. Don't pick one that is going to force you to change the way you work. Try a couple if you can and pick the one that works best for you.

Minimum Stable Feature-set

From time to time this blog will reflect a decision we take as a company, this is one of those times. We're currently working on a product called Citrus, a better way for agents to sell property online because frankly existing stuff sucks, scheduled for launch in the autumn.

One of the key decisions we've taken is not to implement everything on our feature list. We'd rather build half an app than a half assed one. As flippant as that sounds, it's true- we could spend years analysing all the competition, ensure that we've not only bested them at the key features we know we need to implement, but at everything else as well and some day in the distant future launch a product. Or we can look at our feature list, choose the killer features we know our application needs to have to achieve everything 80% of our potential customers need from our app and forget the rest.

We've chosen the latter. It's going to help us get to market faster, it's going to help us get customers quicker and it will allow our customers actual use of the product drive our vision for it- not some paper list. Also if we're totally wrong in assumption that a good product can gain traction in a poor market, we know and can move on sooner.

UPDATED: I renamed the title for consistency - we refer to the stage of development as either both the Minimum Launch Feature-set or the Minimum Stable Feature-set internally - the latter being the best really since it's useful both for an initial launch and for discussing post launch updates.

Never rewrite your software

All software is a work in progress none is ever perfect. It will always have bugs, sometimes it might even seem that the software is nothing but bugs an it's in these dark times when we normally say fuck it, let's start over. Not always, some of the good excuses I hear for a rewrite are:

  • New blood Someone new comes along and the first thing they suggest is a complete rewrite - It's alarming the number of times I hear this suggested. Sometimes it's contractors, which is somewhat exusable - it's more billable time for them. Other times it's by people newly in charge or new to the team.

  • Team members have left - rightly or wrongly they've been blamed for the code, and coding them out seems like a good idea

  • Too many bugs - An effort to hammer out the bugs feels like it would take longer than to rewrite from the ground up

  • New tools! - A shiny new framework is out and you want to use it, it will solve all your problems and put all your spare cycles to work sorting out poverty and war.

Common to all the above is the fact that everything seems like it would be easier if only you could get out from under the crushing weight of legacy. And it's a very attractive fallacy; Bugs could be solved by reworking the architecture; Features would be easier if only the code wasn't written that way; That new framework would fix the bugs we're seeing because of the one we're using.

resist the temptation

They sound like good reasons, but that's the problem with attractive things that are bad for us - they're attractive. It's so much easier to believe that the grass would be greener if we re-turfed the lawn than to work out how to fix those brown patches.

it almost always takes longer than you expect

A complete from the ground up rewrite will take longer than you think. It will probably take almost as long as it took you to get where you are now. It's tempting to believe that you don't need planning meetings to work out what has to be done. It's right there a spec in the current implantation, just get started! So you're initial estimate is just a stab in the dark anyway.

Add to this the further false belief that since you implemented the features once already, you'll be able to do it faster this time around. You won't, well you might - but you won't implement them as optimistically quick as you think you will.

Throughout the process you'll also be further from a releasable product than you think you are - much further. In a rewrite you have to rewrite every feature all those "all we have left in component x to do is..." bullet points add up.

All of this leads to one last problem with timescales for rewrites - in order to get anyone else to buy into them they have to be wildly optimistic about the schedule. So just when you need everyone most motivated and excited, as you're gearing up for a release, you've set them up to be demoralised by missing an increasing number of deadlines.

you're reinventing the [buggy] wheel

Programmers are people, people are creatures of habit. You'll inevitably end up implementing part of your radical new system in a very similar way to your existing system. Then you'll be forced to make the same compromises as you've made before and you'll undoubtedly introduce some bug that's already been patched in your existing software.

Some of your old code will also be good code, at best you might cut and paste it into the new code base but for the most part though trying to hammer it into place and wire it up is going to be as long and as buggy a process as rewriting it. So instead you follow the rewrite it all logic and rewrite it all.

you're standing still

When you're rewriting your software you're stainding still in almost every way possible. If you're rewriting everything, you're spending an awful amount of time not moving your application or business forward. Personally and professionally you're not learning much new (unless a new framework is your excuse).

Even if you're squeezing some features into your rewrite, probably because it's been so long since a release you'd be lynched by a mob if you refused, it's so long before the users are actually going to see them that you might as well not be. The perception of your software isn't going to be sometimes shaky, but getting better all the time - it's going to that it's buggy and the bugs are never fixed.

you'll probably end up no better off

The sad and somewhat painful truth is if a team can't fix something - getting them to make a new one is probably not going to fare much better. Your new version is probably going to be no better than the old, will certainly be worse than an itteratively developed and incrementally improved version of what you had could have accomplished in the same time.

Also problems you're having with a framework or tool probably aren't going to be magically solved by using a new one. Most of the these arguments are born out of a naive belief that because the framework isn't doing what the developer is expecting, the framework has bugs, changing frameworks should then solve the bugs. The problem is of course developer expectation versus reality and more often than not due to some underlying misunderstanding of the platform the framework or tool is abstracting - a reality that a new framework cannot change.

how to sensibly go about a whole rewrite of your software

While it's not sensible to start a full rewrite of your software, it's also ludicrous to decide that nothing written should be changed. Software development is a process not an event. If it's not working fix it; if it's complicated and bug prone, refactor it; if it's shit, code it out. Just don't throw the good out with the bad.

Start where it hurts

In the case of bug riddled software start with an area that is causing the most trouble. Patch the big bugs first. It can be a painful process, I won't lie. It's demoralising to everyone to have buggy software and it's not exciting or glamorous to fix it.

Bug fixes are one of the most thankless tasks developers are asked to perform, so make sure you break it up with some of more challenging and interesting tasks, throw a few features into each iteration.

if I could do it all over I'd change...

These are the generally the things that are hurting the developers rather than the user. Some of them are far reaching, architectural or framework choices. They can all be fixed though, and you don't need to rewrite the whole application to get there.

Again, start with the ones that hurt the most, if it's part of the architecture refactor it. If it's a framework you'd like to integrate to solve problems, try it out on part of the code and work to roll it out incrementally.

I promise it will be quicker, a lot quicker to go down the incremental route than it will be to rewrite the whole thing in one go.