I'm in charge of software development practices and need some help.
February 14, 2012 8:41 AM
My role at work is growing from being a plain programmer to being in charge of our development process. Sounds great, but we don't have a process so I need to come up with one. I need techniques and tools to improve our end product.
We've been playing fast and loose with our development practices, and things have come back to bite us a couple times. My goal is to implement some things that will give us a bit of structure, but I'm unsure where to begin.
I know there's no One True Way to developing software, but I feel like we're making a lot of mistakes right now. Here's an overview, for reference we're using LAMP.
Our deployment system is a script that will copy files from the shared development environment to staging, and from there to production.
We're not using any source control system, right now I'm looking at adopting Git or Mercurial.
Most of our code is probably pretty poorly documented with minimal abstraction.
I feel I need a better understanding of the end to end "best practices" of building web software. I know we need some source control in place, but I'm unsure how that trickles down to effect everything else. Should each developer have their own development environment, and if so what policies should I put in place to minimize conflicts? Having a master repository should make deploying (and rollback) of features easier, right? Should I look at adopting a PHP framework? What things should I know about that I have no idea exist?
We've been playing fast and loose with our development practices, and things have come back to bite us a couple times. My goal is to implement some things that will give us a bit of structure, but I'm unsure where to begin.
I know there's no One True Way to developing software, but I feel like we're making a lot of mistakes right now. Here's an overview, for reference we're using LAMP.
Our deployment system is a script that will copy files from the shared development environment to staging, and from there to production.
We're not using any source control system, right now I'm looking at adopting Git or Mercurial.
Most of our code is probably pretty poorly documented with minimal abstraction.
I feel I need a better understanding of the end to end "best practices" of building web software. I know we need some source control in place, but I'm unsure how that trickles down to effect everything else. Should each developer have their own development environment, and if so what policies should I put in place to minimize conflicts? Having a master repository should make deploying (and rollback) of features easier, right? Should I look at adopting a PHP framework? What things should I know about that I have no idea exist?
The Joel Test is pretty good and outlines the (bare) necessities of running a sane software development team.
As for recommendations for actual methodologies and best practices, I find that it depends on a myriad of factors like:
* How large is your team?
* Do you work for a large organization or are small firm?
* What's the nature of your product(s)?
* Your customers and users, are they individuals or organizations?
* How much money and time can you spend of figuring out the most reasonable development approach for you?
posted by Foci for Analysis at 9:07 AM on February 14, 2012
As for recommendations for actual methodologies and best practices, I find that it depends on a myriad of factors like:
* How large is your team?
* Do you work for a large organization or are small firm?
* What's the nature of your product(s)?
* Your customers and users, are they individuals or organizations?
* How much money and time can you spend of figuring out the most reasonable development approach for you?
posted by Foci for Analysis at 9:07 AM on February 14, 2012
You need source control. Like yesterday.
Opinions differ on everything else. People do everything from continuous deployment to months of careful QA and UAT before anything is "promoted".
I am of the opinion that developers should have their own environment, this will allow them to work on branches without impacting everyone else.
I tend to check in per feature. I don't check in every file I touched that day in one lump. I don't check in random stuff like formatting changes and code changes together. I check in one feature (or part of a feature) at a time.
You are almost always better off working on a branch than the trunk. If I am working on a branch that means I am not checking random changes into the trunk. If don't complete something, or have to back something out for a release I am covered.
Branch when you release, that means you have a clean base for any hotfixes or patches. I have seen people release the trunk, go back to hacking away on it, and then have to back out changes 2 weeks later for a hotfix. Not fun.
I almost always have 2-3 branches going. Current iteration tasks, long term(experimental) tasks and maybe a hotfix branch.
You need to just pick a day an start integrating stuff. We just figure out when we have a QA drop and merge into the trunk, build and push to QA.
CI may be something you want. I don't have it right now. This causes the issue that if I need to get something to testers I have to do it "by hand".
the rest may be useless to you:
I use very rudimentary DI , and it is only on the code I write personally.
I tend to use factory patterns even though I am writing c# because I can swap shit in an out whenever I want. If someone calls me up and says "we need to do xyz with abc data" i write a new implemetation and swap a few things and I am good to go.
I now use decoupled async queues for almost everything. Need to write a log line ? I put it in rabbitMQ. I don't want my app pausing, or god forbid breaking, because of some logging issue. I can have multiple listeners on the other end of the queue processing log data in any way I want.
If you are thinking about putting in a comment, don't. Put in a log line. These will be 1000% times more useful when you are trying to fix an issue at 2am. You can never have too many log lines.
Collect performance metrics. "performance is a feature". log all your performance metrics in a good usable format. I have 10 servers sending performance metrics via rabbitMQ, we can use excel to generate any kind of crazy graphs management wants. If they say "it seems slow" we can prove them wrong.
I will stop there, Hopefully some of this is useful.
posted by Ad hominem at 9:16 AM on February 14, 2012
Opinions differ on everything else. People do everything from continuous deployment to months of careful QA and UAT before anything is "promoted".
I am of the opinion that developers should have their own environment, this will allow them to work on branches without impacting everyone else.
I tend to check in per feature. I don't check in every file I touched that day in one lump. I don't check in random stuff like formatting changes and code changes together. I check in one feature (or part of a feature) at a time.
You are almost always better off working on a branch than the trunk. If I am working on a branch that means I am not checking random changes into the trunk. If don't complete something, or have to back something out for a release I am covered.
Branch when you release, that means you have a clean base for any hotfixes or patches. I have seen people release the trunk, go back to hacking away on it, and then have to back out changes 2 weeks later for a hotfix. Not fun.
I almost always have 2-3 branches going. Current iteration tasks, long term(experimental) tasks and maybe a hotfix branch.
You need to just pick a day an start integrating stuff. We just figure out when we have a QA drop and merge into the trunk, build and push to QA.
CI may be something you want. I don't have it right now. This causes the issue that if I need to get something to testers I have to do it "by hand".
the rest may be useless to you:
I use very rudimentary DI , and it is only on the code I write personally.
I tend to use factory patterns even though I am writing c# because I can swap shit in an out whenever I want. If someone calls me up and says "we need to do xyz with abc data" i write a new implemetation and swap a few things and I am good to go.
I now use decoupled async queues for almost everything. Need to write a log line ? I put it in rabbitMQ. I don't want my app pausing, or god forbid breaking, because of some logging issue. I can have multiple listeners on the other end of the queue processing log data in any way I want.
If you are thinking about putting in a comment, don't. Put in a log line. These will be 1000% times more useful when you are trying to fix an issue at 2am. You can never have too many log lines.
Collect performance metrics. "performance is a feature". log all your performance metrics in a good usable format. I have 10 servers sending performance metrics via rabbitMQ, we can use excel to generate any kind of crazy graphs management wants. If they say "it seems slow" we can prove them wrong.
I will stop there, Hopefully some of this is useful.
posted by Ad hominem at 9:16 AM on February 14, 2012
The number one need is to get everyone invested and on-board as to their role. Some pretty primitive processes can work when everyone is taking personal responsibility to keep an eye on all the moving parts, conversely a really slick process will fail if people don't understand it, why they are doing it, and take responsibility for the whole as well as just their little part.
Just throwing that in there so you don't lose track of the human element. It sounds like the problems are well recognized in your group, so you'll have that extra leverage to get people to invest in your solution.
How much discretion do you have to 'spend' time of those in your group getting them together to brainstorm solutions. An open dialogue with those impacted by whatever changes you propose can go a long way.
posted by meinvt at 9:18 AM on February 14, 2012
Just throwing that in there so you don't lose track of the human element. It sounds like the problems are well recognized in your group, so you'll have that extra leverage to get people to invest in your solution.
How much discretion do you have to 'spend' time of those in your group getting them together to brainstorm solutions. An open dialogue with those impacted by whatever changes you propose can go a long way.
posted by meinvt at 9:18 AM on February 14, 2012
process improvement is an iterative process. Do one thing, get it going well, evaluate, and then plan the next thing.
I personally like CM Journal for lots of little, focused articles that can give me good ideas on what to attack next.
The other piece of advice I can give you is that if you know your pain points, try to relieve them.
posted by Mad_Carew at 9:30 AM on February 14, 2012
I personally like CM Journal for lots of little, focused articles that can give me good ideas on what to attack next.
The other piece of advice I can give you is that if you know your pain points, try to relieve them.
posted by Mad_Carew at 9:30 AM on February 14, 2012
Yeah, start with source control (git, not hg) and tagged builds.
Once you've got that, you can update your build system so it accepts a tag and an environment, and deploys one to the other. Take a look at Jenkins and its ecosystem. Deploy to a new directory for each release, and symlink to it. The old builds give you a (small) safety net.
The tools are pretty easy, in my experience the difficulty comes with making people stick to the process. If you're used to just editing a file on live, the whole "test, commit, tag a build, release to staging, release to live" just looks like so much hassle.
I'm not going to explain this too well, but I'd centre my thinking around releases, and making it easy to generate releases. That is, you want a branch which is always "ready to be released", doesn't have lots of half-finished work hanging around in it. Work in feature branches and when that work is complete fold it into the main branch. Set a deadline (a week, two weeks) and aim to have some work completed, tested and ready to be pushed, even if only to a server where stakeholders can see it. 10% of the work finished and released is better than 50% of the work half-done. Regular releases mean you don't diverge too far from what's on live... I've seen plenty of projects where everyone's too scared to release to live because of the divergence.
Previously
posted by Leon at 9:32 AM on February 14, 2012
Once you've got that, you can update your build system so it accepts a tag and an environment, and deploys one to the other. Take a look at Jenkins and its ecosystem. Deploy to a new directory for each release, and symlink to it. The old builds give you a (small) safety net.
The tools are pretty easy, in my experience the difficulty comes with making people stick to the process. If you're used to just editing a file on live, the whole "test, commit, tag a build, release to staging, release to live" just looks like so much hassle.
I'm not going to explain this too well, but I'd centre my thinking around releases, and making it easy to generate releases. That is, you want a branch which is always "ready to be released", doesn't have lots of half-finished work hanging around in it. Work in feature branches and when that work is complete fold it into the main branch. Set a deadline (a week, two weeks) and aim to have some work completed, tested and ready to be pushed, even if only to a server where stakeholders can see it. 10% of the work finished and released is better than 50% of the work half-done. Regular releases mean you don't diverge too far from what's on live... I've seen plenty of projects where everyone's too scared to release to live because of the divergence.
Previously
posted by Leon at 9:32 AM on February 14, 2012
1) Source control. Go with Git or Mercurial. CVS and SVN are bad. Here's Linus Torvald explaining why they're bad. http://www.youtube.com/watch?v=4XpnKHJAok8. Branching and merging is easy in distributed version control systems. It's not so easy in SVN. Branching gives the local developer the chance to experiment offline without having to push non production releases back into the central server.
2) You should have a developer, test, and production environment. The developer environment doesn't need to be regulated, but developer should match their systems to the test environment when they're compilation is ready. There shouldn't be any differences between test and production environments.
posted by DetriusXii at 9:33 AM on February 14, 2012
2) You should have a developer, test, and production environment. The developer environment doesn't need to be regulated, but developer should match their systems to the test environment when they're compilation is ready. There shouldn't be any differences between test and production environments.
posted by DetriusXii at 9:33 AM on February 14, 2012
As I'm fond of saying to our product guy when he moans about something- creating software is a process, and you're never finished.
I haven't used Mercurial, but we use Git and it's just awesome (we switched to it after using VSS, then SVN previously). Seriously, it'll change your coding life. You'll never fear checkins again.
I heartily recommend getting some kind of issue tracker. We use FogBugz and it's good for defect tracking, and a good starting point for release management. If you need to move away from scheduled "point-release" deployments into something more agile, though, it's rather constraining. They key point here is to keep issues and status centralized- none of that "I emailed you about this bug last week" bullshit anymore.
Learn about unit testing. Everyone's got an opinion on it and why yours is insufficient, but at the very least it should cover regression testing for your code, so that changes in one place don't break functionality elsewhere.
I used to hate frameworks, since I came of age as a web developer when there were none, and many of the early ones were terrible. But, there are some fairly mature ones out there for PHP (Zend, Cake) that you should definitely investigate. If nothing else, they'll school you in a way of coding you may not have considered, and open your eyes to better development processes. Try to avoid the "hold your hand" style frameworks that isolate you from the code by generating templates/controllers/etc. via macros.
posted by mkultra at 9:37 AM on February 14, 2012
I haven't used Mercurial, but we use Git and it's just awesome (we switched to it after using VSS, then SVN previously). Seriously, it'll change your coding life. You'll never fear checkins again.
I heartily recommend getting some kind of issue tracker. We use FogBugz and it's good for defect tracking, and a good starting point for release management. If you need to move away from scheduled "point-release" deployments into something more agile, though, it's rather constraining. They key point here is to keep issues and status centralized- none of that "I emailed you about this bug last week" bullshit anymore.
Learn about unit testing. Everyone's got an opinion on it and why yours is insufficient, but at the very least it should cover regression testing for your code, so that changes in one place don't break functionality elsewhere.
I used to hate frameworks, since I came of age as a web developer when there were none, and many of the early ones were terrible. But, there are some fairly mature ones out there for PHP (Zend, Cake) that you should definitely investigate. If nothing else, they'll school you in a way of coding you may not have considered, and open your eyes to better development processes. Try to avoid the "hold your hand" style frameworks that isolate you from the code by generating templates/controllers/etc. via macros.
posted by mkultra at 9:37 AM on February 14, 2012
Thanks for all the input so far everyone! Some extra details for people: It's a small team, just 3 developers including myself. We just started using Zoho for project management and issue reports. We're a small advertising/marketing start-up. We've got pretty good communication amongst the team, which is how we've managed to not kill each other not having source control yet, but we'll be growing soon.
And another add-on questions, what's the best way to mange changes to the database schema (new tables, new columns on existing tables)?
posted by borkencode at 10:24 AM on February 14, 2012
And another add-on questions, what's the best way to mange changes to the database schema (new tables, new columns on existing tables)?
posted by borkencode at 10:24 AM on February 14, 2012
For database changes, we have a set of baselined flat files that can create our database and each release between the baselines consists of a series of scripts run in a particular order. We also keep a schema revision ID in our database so that the scripts can tell if they are needed or not. We have 3 scripts for each change: install_schema_change_121, validate_schema_change_121, and rollback_schema_change_121.
This works, but will eventually not scale.
posted by Mad_Carew at 10:35 AM on February 14, 2012
This works, but will eventually not scale.
posted by Mad_Carew at 10:35 AM on February 14, 2012
borkencode: "And another add-on questions, what's the best way to mange changes to the database schema (new tables, new columns on existing tables)?"
Many frameworks provide the ability to write your migrations in code (alternately, most languages have libraries that accomplish the same thing). The idea is that while you can run them independently, once you graduate to an automated build environment (oooooooooh), these scripts run automatically when you push out a new build. Typically they'll include code for an "Up" as well as "Down" migration for your rollbacks.
posted by mkultra at 11:17 AM on February 14, 2012
Many frameworks provide the ability to write your migrations in code (alternately, most languages have libraries that accomplish the same thing). The idea is that while you can run them independently, once you graduate to an automated build environment (oooooooooh), these scripts run automatically when you push out a new build. Typically they'll include code for an "Up" as well as "Down" migration for your rollbacks.
posted by mkultra at 11:17 AM on February 14, 2012
Software developers will often argue points ideologically. When it comes to business value, sometimes you have to settle (for at least some period of time) with good enough when it comes to developing standards or process. Also, no matter how much you discuss things, you will inevitably make a bad design decision for process. I agree with one of the above posters that process should be revisited repeatedly over time to work for your business and your team.
Each process needs to be weighed against the business value it provides. If a process is providing little to no business value, stop doing it.
I would start by outlining the pain points your team has right now and the obvious pain points you and your team will probably have within the next year. Create and prioritize tasks that can managed to reduce these pain points weighed against the money and time you actually do have.
Like others have mentioned above, step #1 is a source control management system for the developers and a system that backs up the code nightly. The code is the crown jewels as it is what makes your business money. Take care of it.
posted by seppyk at 11:19 AM on February 14, 2012
Each process needs to be weighed against the business value it provides. If a process is providing little to no business value, stop doing it.
I would start by outlining the pain points your team has right now and the obvious pain points you and your team will probably have within the next year. Create and prioritize tasks that can managed to reduce these pain points weighed against the money and time you actually do have.
Like others have mentioned above, step #1 is a source control management system for the developers and a system that backs up the code nightly. The code is the crown jewels as it is what makes your business money. Take care of it.
posted by seppyk at 11:19 AM on February 14, 2012
« Older Things learned by reading biographies | The city of Vancouver illegitimately towed my car... Newer »
This thread is closed to new comments.
http://www.joelonsoftware.com/articles/fog0000000043.html
You'll have to adopt them slowly, but obviously source control is the priority for your team.
posted by chrillsicka at 8:56 AM on February 14, 2012