<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>This blessed sip of life,
is it not enough?

  
    var quotes = [
      'This blessed sip of life, is it not enough?',
      'The future is no place to place your better days'
    ];
    (function() {
    debugger;
    var quotetag = document.getElementById('dmbquote');
    quotetag.innerHTML = quotes[Math.floor(Math.random()*2)];
    })();
  

  var _gaq = _gaq || [];
  _gaq.push([‘_setAccount’, ‘UA-22736487-1’]);
  _gaq.push([‘_trackPageview’]);

  (function() {
    var ga = document.createElement(‘script’); ga.type = ‘text/javascript’; ga.async = true;
    ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;
    var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(ga, s);
  })();</description><title>Rock Hymas</title><generator>Tumblr (3.0; @rockhymas)</generator><link>http://thoughts.rockhymas.com/</link><item><title>Tweaking Teaching Math</title><description>&lt;p&gt;So my wife started  homeschooling our older two boys in September after we’d recovered from the  summer vacations a little bit. She likes to write about their escapades on &lt;a href="http://kamadawn.blogspot.com/"&gt;her blog&lt;/a&gt;, and they’re doing a great  job. In deciding to start homeschooling we had planned to have me help by  teaching them math, but then decided before our “first day of  school” that I was too busy with work, a long commute and Cub Scouts to  do that. So for the last two months Kami has been teaching them using a  combination of the &lt;a href="http://saxonpublishers.hmhco.com/en/sxnm_home.htm"&gt;Saxon  Math&lt;/a&gt; program and the &lt;a href="http://www.khanacademy.org/"&gt;Khan Academy&lt;/a&gt;,  and I haven’t been all that involved, other than as a spectator on the  sidelines and someone that Kami can bounce her ideas and concerns off of.&lt;/p&gt;
&lt;p&gt;&lt;img alt="She's not learning math ... yet." src="http://media.tumblr.com/tumblr_luqf4hVqSX1qbpnbq.jpg" width="500"/&gt;&lt;br/&gt;&lt;em&gt;She’s not learning math … yet.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Since then, she’s  been constantly tweaking things as she goes. She honed how she taught them  math over the last couple of months. First, she went back and forth between  teaching Reagan and Cade together or separately. Though they can both handle  the third grade material fine, she found that trying to teach them together  just led to goofing off. They devolved into performing for each other, rather  than thinking about and learning the material. So she settled on teaching them  separately, but that did take more time. Each day she would take about 45  minutes with each boy and go through the Saxon math lesson for the day, the  daily “meeting”, and help them with worksheets, if they needed it.  While one boy was doing this with Mom, the other one did some personal  worksheets and then got to work on Khan Academy exercises, usually doing  whichever ones he wanted to.&lt;/p&gt;
&lt;p&gt;While this  generally worked ok, there were two challenges that regularly came up.&lt;/p&gt;
&lt;p&gt;First, the amount  of repetition in the Saxon math curriculum was sometimes boring, both for her  and for the kids. Though repetition is good, once the kid is comfortable with  the material it can be too easy to be fun. Also, the boys like to brag to Dad  at dinner about what they learned each day, and there would be weeks where I’d  only hear about math once. And my wife wants you to know that it wasn’t  because they weren’t doing it!&lt;/p&gt;
&lt;p&gt;Second, the hour  and a half of math time was a big chunk of the homeschooling day, and it was  regularly interrupted by the younger kids, our three and a half year old Levi  and newly-walking Liberty. This wasn’t as bad with other subjects, where it  was  usually easier to recover from  interruptions, or they didn’t take as long, or they could be done with both  boys and sometimes the younger ones too.&lt;/p&gt;
&lt;p&gt;Both of these  challenges point to deeper issues, which we discussed occasionally over the  last two months. Many of you might have responded to the first concern by  saying “Throw out the Saxon Math!” or “Just skip the parts that  were repetitive!” Both responses discount the value of repetition in  learning. Even if they didn’t, you’d have to consider that Saxon math makes it  fairly easy for someone who never felt comfortable in the world of math (my  wife) to teach her kids. But skipping parts of the curriculum brought back  Kami’s discomfort of trying to figure out what was important to repeat and  what wasn’t, without feeling like she had a good idea of what they would need  later on.&lt;/p&gt;
&lt;p&gt;The second  challenge doesn’t provoke such simplistic responses. You wouldn’t say  “Well, you just got to get rid of those two younger kids,” or  “Math isn’t that important, just spend less time on it.” Actually,  we could spend less time on math, but only if we felt there were another way  to teach them that would be as effective. But the fact is that we’ve got four  kids. Life has been getting easier with four over time, as the older kids  become more capable of helping and the younger ones get better at playing on  their own, but that’s also not an issue that is going away in the short term.&lt;/p&gt;
&lt;p&gt;So rather than try  to eliminate those challenges, we’re going to sidestep them using an ingenious  plan: I’ll teach them math. Ok, so it’s not ingenious. It’s not novel, or  newfangled, or noteworthy. But it directly addresses the issues. I’m much more  comfortable experimenting with the curriculum than Kami was. I’ll start  simply, just doing what Kami was doing, but plan to change things up based on  the needs and abilities of the boys. Besides that, I’m curious about how best  to teach math, not just in a generic sense (what works for everyone), but also  in a specific sense. What works for Reagan? What works for Cade? Why? We will  work towards a method that gets them learning, gets them involved, and doesn’t  take any longer than our current one.&lt;/p&gt;
&lt;p&gt;This also helps  with the challenge of homeschooling with toddlers as well. I’ll be teaching in  the evenings, after the younger two go to bed. That means the house is  quieter, it helps the boys wind down after their active afternoons, and Kami  can deal with the interruptions most days. Another awesome benefit is that she  and the kids just got an extra hour and half each day. Some of that extra time  can still be spent by the boys doing Khan Academy exercises and math  worksheets. But the rest can be used to learn about other stuff, play, relax,  run errands, do housework, etc. Basically, it gives Kami more flexibility  during the day, which reduces her stress level, and it gives us some more  structure to our evenings, which is important when trying to get kids to  actually go to bed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Compared to this kid, math is easy." src="http://media.tumblr.com/tumblr_luqf93YxLO1qbpnbq.jpg" width="500"/&gt;&lt;br/&gt;&lt;em&gt;Compared to this kid, math is easy.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Of course, it’s not  all unicorns and bacon. This new schedule does stretch me a little bit. I’ve  sacrificed some of my commute on the train so I can think about the work of  teaching math. I tend to be pretty wiped out once the kids go to bed, so I  haven’t been able to get as much done on weeknights. And I do still have my  other responsibilities: Cub scouts, my job, and finding time to play with my  younger two kids. Much to Kami’s chagrin, I haven’t done the dishes much this  week. And when I have other responsibilities in the evenings, it can mean we  do some schedule juggling. Though Reagan seems to do fine learning math in the  evenings, Cade can be a bit more goofy at that time of day. Those challenges  won’t just go away, and I’m sure we’ll continue making adjustments to how we  balance everyone’s different needs.&lt;/p&gt;
&lt;p&gt;All that said, our  first week on the new schedule has gone surprisingly well. Since we started on  Monday, I come home to a much happier wife and kids, because they’ve all had  more time to do other things. The “perfect homeschooling day” is  something rarely seen even among experienced homeschoolers, but Kami’s been  really happy with every day this last week. She’s also more relaxed about  school, which is good for her and for the kids. The older boys get more  one-on-one time with Dad, which they really like, and makes me a feel a little  bit better about the long commute.&lt;/p&gt;
&lt;p&gt;There are certainly  disadvantages to homeschooling (it can get expensive), but one of the  advantages we have it that we can be way more flexible. I like to think of our  little homeschool as a small startup amidst the mega-corporations known as  public education and private schools. Our market is significantly smaller –  just four kids, two of which wouldn’t be served by the megacorps anyway – so  we can understand their needs and meet them much more directly. And we can  respond more nimbly to those needs as they change. This change in how we teach  math is really just one of the larger changes amidst a constant stream of  tweaks to the way we teach our kids. Some of them work, some of them don’t,  but it’s easy to see the successes and failures and respond quickly.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/12864858895</link><guid>http://thoughts.rockhymas.com/post/12864858895</guid><pubDate>Tue, 15 Nov 2011 21:46:01 -0500</pubDate></item><item><title>The Most Awesome Weekend Release Ever</title><description>&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Hey, I have to tell you about the most awesome weekend release ever. It happened last Saturday, and –”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Weekend Release?”, you ask, incredulous. “Aren’t you supposed to be doing &lt;a href="http://bitquabit.com/post/midnight-deploys-are-for-idiots/"&gt;weekday deploys&lt;/a&gt;?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Yeah, yeah, I know. We agree, and we’ve taken a break recently as we make changes that involve enough risk that we don’t feel comfortable doing them during the week. But that’s not the point of this story. What I really wanted to tell you is about my crazy night trying to –”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“But everyone agrees that &lt;a href="http://briancrescimanno.com/2011/09/29/why-are-you-still-deploying-overnight/"&gt;deploying at night doesn’t make sense&lt;/a&gt;, right?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Um, yes. Well, not everyone. But we do, and that’s also on our radar. So, we had to update some test accounts to test some new performance improvements this coming week –”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Wait, so your test accounts are on your production servers? Don’t you have a staging environment?”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“AARGH! Will you just let me tell my story?! And, yes, we know we need to build out a staging environment. It is one of our &lt;a href="http://blog.fogcreek.com/build-and-release-report-card/"&gt;top priorities&lt;/a&gt; at the moment.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Ok, ok, sorry. Go ahead with your story.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt; &lt;/span&gt;“Thank you.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So last week we got a FogBugz release ready with some bug fixes and performance improvements. The plan was straightforward: deploy it to our production servers on Saturday night and upgrade our test accounts so that QA could bang on it for a week. Barring release blockers, we could upgrade everyone the following Saturday.&lt;/p&gt;
&lt;p&gt;On Saturday, while I was out running errands, it started to snow. I &lt;a href="https://twitter.com/#!/rockhymas/status/129664205396787200"&gt;love&lt;/a&gt; &lt;a href="https://twitter.com/#!/rockhymas/status/130289295096414211"&gt;the&lt;/a&gt; &lt;a href="https://twitter.com/#!/rockhymas/status/130306712212209665"&gt;snow&lt;/a&gt;, and thought, “That’s cool, my boys will enjoy playing in the snow and it should all be melted by Halloween when we go trick-or-treating.” Those tweets and that thought apparently jinxed me. Once I was done with my errands in the early afternoon, I drove home through near-blizzard conditions only to get a text from my wife that the power had gone out. She also mentioned that a bunch of trees were down on our street. As I got off the freeway and drove down the hill towards home, I was following a bus that was swerving all over the road to avoid low-hanging branches and a tree that had fallen across half the road.&lt;/p&gt;
&lt;p&gt;&lt;img height="349" width="500" alt="Our releases don't usually look like this" src="http://i42.photobucket.com/albums/e305/baldaltima/clash_of_the_titans.jpg"/&gt;&lt;br/&gt;&lt;em&gt;Our releases don’t usually look like this&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After a few hours it became apparent that we wouldn’t be getting power back in time for me to login to our VPN and take care of the release. So I started contacting some friends from church to find someone who had power and wifi and the willingness to put me up for an hour or so at 10pm. Brandon, Ian, and John all said they could, but Brandon was first, so I let our sysadmins know the release was still on (they like to be alerted to these things, you know). It got dark at about 7, and we put the kids down early, wrapping our one-year-old Liberty up in a snowsuit so she’d be warm enough all night. At 9:30, I packed up my laptop and went out to make the 15 minute drive to Brandon’s home.&lt;/p&gt;
&lt;p&gt;As I left I had two roads I could take: the freeway, which involved some pretty steep hills; or driving through town (three towns, actually) along a road with no significant hills. Because the snow was still coming down hard and sticking pretty well I decided to avoid the hills. That was a mistake. The first few minutes were pretty uneventful, but it was fun to drive through downtown Berkeley Heights and into New Providence in complete darkness. No streetlights, no traffic lights, no homes lit up, no businesses, no grocery stores. Ninety percent of the other vehicles on the road were snow plows (doing a great job, by the way).&lt;/p&gt;
&lt;p&gt;The drive through town was also along a heavily tree-lined road, which made the darkness creepy in a “Halloween is cool” kind of way. But as I travelled this road it became clear that I had taken the wrong road. Trees had fallen across the road at pretty regular intervals. The snow plows (or kind citizens) had cleared a single lane path where these had happened, though it was often just barely wide enough for my compact Honda Civic. I went ahead and drove past a few road closed signs and one unmanned roadblock.&lt;/p&gt;
&lt;p&gt;&lt;img height="333" width="500" alt="Not in New Jersey, but you get the picture" src="http://farm7.static.flickr.com/6092/6298756981_3f787b1b35.jpg"/&gt;&lt;br/&gt;&lt;em&gt;Not in New Jersey, but you get the picture&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Soon after that I realized why they were closed: The downed power lines. Most didn’t block the road at all, but one was just hanging directly in my path and scraped over my car before I had time to notice it and react. That got my adrenaline running. At another point I got to play chicken with a snow plow that was driving the wrong way in my lane.&lt;/p&gt;
&lt;p&gt;I finally made it into Summit, where there was power in some parts of town, and pulled into Brandon’s driveway, but of course, the car got stuck as soon as I left the road, so I was blocking the exit for both him and his neighbors. He and I puzzled over that for a couple seconds, then realized his neighbors wouldn’t be crazy enough to go driving in the storm. He set me up in his basement, his wife Becki offered me something to drink, and they went back to watching TV.&lt;/p&gt;
&lt;p&gt;After a little over an hour the release was done, and it was time to head back home. This time, I’d learned my lesson. Throughout my drive to Brandon’s the roads had been clear, thanks to the plows, so I knew that it would be an easy ride home on the freeway.&lt;/p&gt;
&lt;p&gt;And it was.&lt;/p&gt;
&lt;p&gt;Until I got off the freeway.&lt;/p&gt;
&lt;p&gt;I took an exit that would avoid the steepest hill, just in case. Turns out that was a good choice, as I found out Sunday that it was completely blocked by fallen trees. It did mean I had a bit further to drive through town, maybe a mile and half instead of just a mile.&lt;/p&gt;
&lt;p&gt;And that’s when the fun really started.&lt;/p&gt;
&lt;p&gt;The off ramp had a tree across it that had obviously been chain-sawed through in the last couple hours. Just around a bend, I came across a cop car with lights flashing, blocking the road I would have taken. So I decided to risk a side road to get around the blocked off section. Now I really was in rural New Jersey, and now I got to drive over some branches that weren’t quite big enough to block my Civic. I finally made it back to the road leading home (less than a mile to go!), but just a couple blocks further ran into a road block that wasn’t one I could drive around. Power lines and police tape were draped across the road right at car level.&lt;/p&gt;
&lt;p&gt;So it was off into side streets again, on the very steep hills I had wanted to avoid. I still wasn’t slipping around on the snow much, but had to take a couple detours anyway (trees across the road). Finally I started heading back down the hill.&lt;/p&gt;
&lt;p&gt;The end was in sight!&lt;/p&gt;
&lt;p&gt;So, of course, I got stuck.&lt;/p&gt;
&lt;p&gt;One more downed tree. At the worst spot. The snow was deep enough that turning around wasn’t an option. Backing up didn’t work. I’d finally gotten my Civic stuck in the snow only about half a mile from home.&lt;/p&gt;
&lt;p&gt;Fortunately, I’d left home with a flashlight (so I could see in the garage). I broke that out, bundled up, and started the hike home. My flashlight was pretty weak compared to the car headlights, though, so I just barely avoided walking into a downed power line on the hike down the hill. Once down the hill, I got to pass a powwow of power crews and cop cars at the last intersection before my home where they guided me past more downed lines. From there on out I walked down the middle of the street in complete darkness illuminated only by my flashlight.&lt;/p&gt;
&lt;p&gt;Once home, after taking over an hour to make the 15 minute drive, I jumped in the shower to warm my toes back up before getting under the heaps of blankets my wife had piled on our bed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow-up (Monday):&lt;/strong&gt; The power is still out, and the city is telling us they can’t even give us an estimate for when we’ll get it back. On Sunday we drove for a few hours into southern New Jersey to get the last remaining generator at the only Home Depot who hadn’t sold out the first hour they were open. We’re now using it to power our fridge, freezer, and DSL modem, so I can work from home, since the trains into New York aren’t running. Kami and the kids are doing homeschool in the dark, which the kids think is just awesome. I’m writing this post in a room that is about 60°F, while listening to the dulcet roar of our generator right outside my window.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow-up (Friday):&lt;/strong&gt; The power finally came back on Thursday evening at about 5pm. We spent the evening cleaning up our home, doing laundry, and generally trying to get our lives back in order. And guess what? I’ve got another release to do on Saturday!&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/12349091234</link><guid>http://thoughts.rockhymas.com/post/12349091234</guid><pubDate>Fri, 04 Nov 2011 21:07:44 -0400</pubDate></item><item><title>What ever happened to all that talk about build and release management?</title><description>&lt;p&gt;Well, I collected them into a &lt;a href="http://thoughts.rockhymas.com/post/12014744973/build-and-release-management-series"&gt;series&lt;/a&gt; and added a &lt;a href="http://blog.fogcreek.com/build-and-release-report-card/"&gt;report card&lt;/a&gt; over on the &lt;a href="http://blog.fogcreek.com/"&gt;Fog Creek blog&lt;/a&gt;. I plan to continue adding to the series going forward.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/12287157013</link><guid>http://thoughts.rockhymas.com/post/12287157013</guid><pubDate>Thu, 03 Nov 2011 12:39:24 -0400</pubDate></item><item><title>Build and Release Management Series</title><description>&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/926705619/what-is-build-and-release-management"&gt;What is build and release management?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/931921833/can-you-build-your-product-with-one-command"&gt;Can you build your product with one command?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/938040895/where-do-developers-keep-their-checked-out-source-code"&gt;Where do developers keep their checked-out source code?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/942491472/how-do-i-eliminate-absolute-paths-from-my-code-and"&gt;How do I eliminate absolute paths from my code and build scripts?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/947094911/do-your-builds-have-other-hard-dependencies"&gt;Do your builds have other hard dependencies?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/967321250/you-keep-talking-about-hard-dependencies-are-there-any"&gt;You keep talking about hard dependencies. Are there any soft dependencies?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/998963539/how-are-build-and-deploy-scripts-different"&gt;How are build and deploy scripts different?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1011476205/what-should-you-include-in-machine-setup-scripts-for"&gt;What should you include in machine setup scripts for dev and build machines?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1093701227/can-you-deploy-your-product-with-one-command"&gt;Can you deploy your product with one command?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1098426283/are-your-build-scripts-crusty-and-old"&gt;Are your build scripts crusty and old?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1121349192/why-should-my-build-and-deployment-scripts-be-separate"&gt;Why should my build and deployment scripts be separate?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1132377519/can-you-build-all-possible-configurations-using-command"&gt;Can you build all possible configurations using command line parameters?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1138167537/do-you-have-an-official-build-machine-or-set-of-build"&gt;Do you have an official build machine or set of build machines?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1167543667/do-you-save-your-old-builds"&gt;Do you save your old builds?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1210746386/do-you-store-built-binaries-in-your-vcs"&gt;Do you store built binaries in your VCS?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1553192919/do-you-have-different-build-scripts-for-different"&gt;Do you have different build scripts for different configurations of your build?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/2624391100/do-you-have-different-build-scripts-for-official-builds"&gt;Do you have different build scripts for official builds vs. dev builds?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;More to come!&lt;/p&gt;
&lt;h4&gt;Related Posts&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://thoughts.rockhymas.com/post/1365832676/deploying-fogbugz-8-and-kiln-2"&gt;Deploying FogBugz 8 and Kiln 2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.fogcreek.com/build-and-release-report-card/"&gt;FogBugz and Kiln Build and Release Report Card&lt;/a&gt;&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/12014744973</link><guid>http://thoughts.rockhymas.com/post/12014744973</guid><pubDate>Thu, 27 Oct 2011 21:25:00 -0400</pubDate></item><item><title>"Have you been flossing regularly?"</title><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Have you been flossing regularly?” - Your Dentist&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Don’t you hate it when you go to the dentist and, while the dentist is digging around in your mouth, he asks if you’ve been flossing?&lt;/p&gt;
&lt;p&gt;“Huh-mhqhg,” you respond, hoping that all the fingers in your mouth made your negative answer sound like a “Yes, sir”&lt;span&gt;  &lt;/span&gt;on the way out. But no; dentists (and their assistants) have an uncanny ability to understand the most garbled language correctly. Either that, or they’re just really good at reading the guilty look in your eyes.&lt;/p&gt;
&lt;p&gt;And then the kicker comes:&lt;/p&gt;
&lt;p&gt;“Yeah, I could tell by the profuse bleeding that happens when I start jabbing your gums with this sharp metal instrument of torture.” Ok, so the dentist doesn’t actually say that, but hey, if he can hear what he wants in my garbled mumblings, I should be able to hear his words the way I want to, right?&lt;/p&gt;
&lt;p&gt;Anyway, let’s assume he’s probably right, and that regular flossing would actually eliminate the need for blood transfusions after each visit to replace all that was lost. From the scattered times in my life when I’ve been able to keep up flossing for a week or two, I know that after the first few days the bleeding &lt;span&gt;does&lt;/span&gt; go down significantly. So maybe the dentist has a point, and not just at the end of those instruments of torture.&lt;/p&gt;
&lt;p&gt;But how do you go from a lifetime of flossing for a week or two after each dentist visit and then forgetting about it completely until the next one, to actually making it something that you do each day without thinking much about it?&lt;/p&gt;
&lt;p&gt;The trick is building a habit. No, it’s not easy. Yes, it will take time. If you need help, I recommend following these &lt;a href="http://6changes.com/post/288484241/quickstart"&gt;basic steps&lt;/a&gt;. There is no easy way to build a good habit, but you can make it easier. Choose a &lt;a href="http://6changes.com/post/288258857/triggers"&gt;trigger&lt;/a&gt;, make it &lt;a href="http://6changes.com/post/405755848/progress"&gt;public&lt;/a&gt;, keep it &lt;a href="http://6changes.com/post/288275436/why-you-should-only-do-one-habit-at-a-time"&gt;simple&lt;/a&gt;, build &lt;a href="http://6changes.com/post/296037328/anticipation"&gt;anticipation&lt;/a&gt;, take your &lt;a href="http://6changes.com/post/296024368/life"&gt;time&lt;/a&gt;, report to &lt;a href="http://6changes.com/post/284561373/accountability"&gt;others&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I went through these steps over the last month or so, and now I’m flossing daily, even under the dental wire that is the last, permanent reminder that I had braces as a kid. Yeah, I was even more nerdy back then.&lt;/p&gt;
&lt;p&gt;Anyway, I’m writing up this post because my next dentist visit isn’t coming for a few months. But if I tell my small corner of the internet how that visit will go it will help me stick to my habit until then.&lt;/p&gt;
&lt;p&gt;So now, the next time my dentist asks, “Have you been flossing regularly?”, I’ll have a better answer for him:&lt;/p&gt;
&lt;p&gt;“Huh-mhqhg”&lt;/p&gt;
&lt;p&gt;Ok, you might not be able to tell the difference, but somehow the dentist will see the gleam in my eye, and know it is not the glint of guilt he saw at my last visit. &lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/11296828139</link><guid>http://thoughts.rockhymas.com/post/11296828139</guid><pubDate>Mon, 10 Oct 2011 20:44:00 -0400</pubDate></item><item><title>In Which I Defend the C Standard for Interviews</title><description>&lt;p&gt;In &lt;a href="http://blog.bitquabit.com/2011/04/13/drowning-in-a-c-of-interviews/"&gt;Drowning in a C of Interviews&lt;/a&gt;, Benjamin points out that he doesn’t see much value in doing interviews exclusively in C. Additionally, he believes that “we’re making candidates nervous about how well they know C, and focusing too much on how well they understand C’s semantics, but not really getting any meaningful indicators back in return.”&lt;/p&gt;
&lt;p&gt;I have a different take on our interviews. Though I haven’t done as many interviews here at The Creek as Benjamin, throughout the last intern hiring seasons I saw a sum total of one candidate that actually suffered in an interview from not feeling comfortable with C. While I agree with Ben that allowing the candidate to code in the language they are most comfortable with won’t really change how many candidates get the “hire” decision, I do think there are some benefits to interviewing in C that we might lose.&lt;/p&gt;
&lt;p&gt;It will help to step back and consider what we are looking for at Fog Creek. Our listing for a &lt;a href="http://www.fogcreek.com/Jobs/Dev.html"&gt;software developer position&lt;/a&gt; has this to say about what we’re looking for:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Right now we use C#, JavaScript, XHTML, CSS and even Wasabi (an in-house .NET language) to develop FogBugz. Kiln uses C#, JavaScript and Python, Copilot uses C, C++ and Objective C, and we have some legacy code written in VBScript. Tomorrow we may be using something completely new.&lt;/p&gt;
&lt;p&gt;Whatever technologies, languages, or development environments you’ve been using, we expect you have mastered them in depth, and we expect that you will be able to master any technology, language, or development environment that we need in the future.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So we’re really looking for two things. First, do they code enough to have mastery in the languages they are most comfortable with. And second, can they use an understanding of broader principles to quickly learn new languages and technologies.&lt;/p&gt;
&lt;p&gt;If we always let candidates code in their language of choice, we’ll be testing more for first quality. As such, we’ll want to dive deep into the way things are implemented, different ways of using the language to tackle the problem presented, and we’ll expect that the code is both syntactically and semantically correct. We would only get indirect hints as to the second quality - if the candidate can handle the problem itself then it means they can learn quickly on a small scale, and it most likely means they have a good grasp of the principles required to quickly get up to speed on a new language. But that’s not a guarantee.&lt;/p&gt;
&lt;p&gt;If we did all our interviews in C, then, for most candidates we’ll be testing for the second quality - their ability to get up to speed in a language they don’t use on a regular basis quickly. They may be familiar with C, or may not, but they know we interview in C, so they can prepare for it. I specifically request that candidates code in C or C++, and while it is generally easy to see who is comfortable with it, it’s also fairly easy to tell who picked it up recently and didn’t have any problems with the question. I get excited about these candidates, because I know they can pick up new technologies quickly. I get (slightly less) excited about the ones who are obviously comfortable with C and do well on the actual question.&lt;/p&gt;
&lt;p&gt;I can think of two interesting third alternatives to the “all in C” vs “pick your language” debate. One would be to work for a good mix of interviews in a language the candidate chooses with interviews in C, the “&lt;a href="http://www-cs-students.stanford.edu/~blynn/c/ch01.html"&gt;desert island language&lt;/a&gt;”. That would allow candidates to show off mastery of their tools of choice as well as the ability to work well outside of those tools. And since Ben stopped doing his interviews in C, I guess I’ll have to keep doing mine in C. Especially since his blog post will probably convince a couple other guys here to give up the C requirement. And besides, it makes life easier for me.&lt;/p&gt;
&lt;p&gt;Another option would be to use a relatively obscure language, or one we make up (&lt;a href="http://www.joelonsoftware.com/items/2006/09/01b.html"&gt;Wasabi&lt;/a&gt;, anyone?), in place of C for part of our interviews. We could test for mastery of the tools they use by having them code up the solution to a problem their own language of choice. Then we give them a different language, possibly with a fundamentally different paradigm (OO vs functional vs procedural, etc.), and have them code it up again. At this point, they understand the problem and solution fairly well, so they’ll be more fully demonstrating their ability to learn a new language and write code in it.&lt;/p&gt;
&lt;p&gt;I’m not totally happy with either of these options, but they can certainly add to the discussion we’re having at Fog Creek about how to find and interview developers who want to help all developers &lt;a href="http://www.joelonsoftware.com/items/2009/11/01.html"&gt;make better software&lt;/a&gt;.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/4580899270</link><guid>http://thoughts.rockhymas.com/post/4580899270</guid><pubDate>Wed, 13 Apr 2011 11:07:00 -0400</pubDate></item><item><title>Do you have different build scripts for official builds vs. dev builds?  </title><description>&lt;p&gt;I hope you don’t have one script or set of scripts for dev builds and a separate script for official builds. For teams that have made the good step of setting up a dedicated build machine, this form of build script decay is probably more common than &lt;a href="http://thoughts.rockhymas.com/post/1553192919/do-you-have-different-build-scripts-for-different"&gt;having different scripts for different configurations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For example, you start getting close to shipping an actual product to actual customers, and so you setup a dedicated build machine. In getting build scripts to work you copy the build scripts the developers have been using, but you copy them, instead of just using them directly. This is because there are all kind of changes you need to make now that your code is being compiled and deployed to production, whether that is a web server, or wrapped up in a client installer, or copied to an embedded device. Once you get everything working, you then forget to refactor and move things back to a single script. In the best case, your official build script just calls the development build script. In the worst case, they both do a ton of similar, or exactly the same, things. But now you have to manage both scripts.&lt;/p&gt;
&lt;p&gt;Even in the best case, where the official build script calls the development build script, there are probably improvements you can make. There may be steps in the official script that would be useful and/or necessary for developers to run also. Maybe not for every build, but probably for some builds. Taking some of what was done for the official build script might also improve developers life’s by making it easier for them to have multiple installations on their development box with less overhead work on their part.&lt;/p&gt;
&lt;p&gt;Of course, in the worst case, with tons of duplicated script code, you’re going to have issues when developers fix the development build script but forget to fix the official one.&lt;span&gt;  &lt;/span&gt;And vice-versa. But if you fix the scripts by combining them, and using appropriate command line parameters for any differences that absolutely need to exist, you get developers to help you maintain the official build scripts for free. By combining them you also encourage &lt;a href="http://thoughts.rockhymas.com/post/1121349192/why-should-my-build-and-deployment-scripts-be-separate"&gt;separation of deployment and build scripts&lt;/a&gt;, which will further improve your process.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/2624391100</link><guid>http://thoughts.rockhymas.com/post/2624391100</guid><pubDate>Thu, 06 Jan 2011 11:54:07 -0500</pubDate></item><item><title>Do you have different build scripts for different configurations of your build? </title><description>&lt;p&gt;One of the most natural ways that build scripts decay is when you create create separate scripts for different configurations of your build. This typically does not happen when configuration just means “debug” or “release”. That’s usually handled quite well with compiler and/or linker flags, or just using command line parameters or other ways of modifying run-time behavior. I’m referring instead to different configurations that you actually ship to customers. Here at Fog Creek we have hosted FogBugz and Kiln as well as licensed FogBugz and Kiln. Other products might have both “lite” and “pro” editions. Or maybe you have a separate configuration of your product for each customer. Or you’ve got an internal app that needs to be a little different at each of the company offices.&lt;/p&gt;

&lt;p&gt;The obvious problem with having separate build scripts for each configuration is that you then have to remember to change multiple scripts when something common to all of them changes. And the common stuff will change more than the differences will. When your scripts are used to build every configuration, then you know going into a change that you need to consider each configuration. For example, it may very well be that you’re making a change that will only affect “pro” users, but then you’ll remember that you need to properly disable the feature in the “lite” edition.&lt;/p&gt;

&lt;p&gt;Like most cases of repeating yourself, it’s fine to do it once, to understand the differences, for example when you first add a new configuration. But then you should refactor, eliminating the repetition by using common build scripting technology. Whether you’re using msbuild, make, ant, maven, or whatever, it’s quite straightforward to have a single script deal with multiple different configurations of the build, even when fairly major differences arise between them. Often, the largest differences between configurations are not build-related but deployment-related. So if you’ve &lt;a href="http://thoughts.rockhymas.com/post/1121349192/why-should-my-build-and-deployment-scripts-be-separate"&gt;separated your build and deployment scripts&lt;/a&gt; you’re already halfway there.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1553192919</link><guid>http://thoughts.rockhymas.com/post/1553192919</guid><pubDate>Fri, 12 Nov 2010 11:43:51 -0500</pubDate></item><item><title>Deploying FogBugz 8 and Kiln 2</title><description>&lt;p&gt;&lt;a href="http://www.twitter.com/benmcfc/status/25289114230"&gt;&lt;img src="http://media.tumblr.com/tumblr_lan2l3Gly21qbpnbq.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Of the many positive comments about the new FogBugz and Kiln releases, that was my favorite. Not so much because we did anything better than Twitter, as I haven’t heard of any problems with the rollout of their new version, but mostly because it meant…we did it! As the new build and release manager for Fog Creek, it was satisfying to get to this point—to have shipped two new major releases simultaneously with some interesting changes to our deployment process to handle new releases mixed in along the way.&lt;/p&gt;
&lt;p&gt;I’ve mentioned before that your deployment scripts may have many different &lt;a target="_blank" href="http://thoughts.rockhymas.com/post/1093701227/can-you-deploy-your-product-with-one-command"&gt;deployment targets&lt;/a&gt;: developer machines, the QA team, internal users, beta testers, and finally a full release. I’d like to document some of our processes here at Fog Creek for deploying FogBugz and Kiln. There are some things we do well…really well. And there are some things we’re still working to improve. Though my focus will be on deploying (rather than building) our products, I will mention our build processes when they affect deployment, and discuss some of the improvements we could make there too.&lt;/p&gt;
&lt;p&gt;It’s worth mentioning now that all of the credit for what works in our build and deployment process goes to the great Fog Creek developers that set up this process over the last few years. And one of the reasons our releases went so smoothly this time around is because the current FogBugz and Kiln teams did a great job squashing all of the bugs that our QA team did a great job finding. Besides storing away knowledge in hopes of making some improvements going forward, I didn’t do much more than run a few script files. If that sounds exciting to you, read on.&lt;/p&gt;
&lt;h4&gt;Dev Deployment&lt;/h4&gt;
&lt;p&gt;Before anyone else can deploy a new version of FogBugz or Kiln, the FogBugz and Kiln developers do. Work began in earnest for FogBugz 8 and Kiln 2 when our summer interns arrived in late May and early June. Each of them needed to get FogBugz built and deployed on their machine and the Kiln interns needed to get Kiln deployed.&lt;/p&gt;
&lt;p&gt;The set of steps a new intern goes through to get their FogBugz and/or Kiln deployments up and running is, sadly, not short. And it’s all manual. It involves getting the source code in the correct directories, installing a large number of tools (all at the correct version for development, of course), setting up virtual directories, preparing the database, building everything, etc. This whole process typically took one or two days, and not all setups were the same—something that occasionally bit our interns. Typical problems included getting the wrong version of some build tool, setting up the databases using the wrong named db instance, naming directories incorrectly, etc. As you might expect, once everything is set up, you don’t want to change anything, because it can be painful.&lt;/p&gt;
&lt;p&gt;On the other hand, once everything &lt;span&gt;is&lt;/span&gt; set up, doing daily development is pretty darn easy. Building FogBugz or Kiln in place will update your locally hosted instance of that application. There really aren’t any ongoing deployment needs, except when new features necessitate them. If you want two different development environments to make it easier to switch between bug fixing and feature development (we use one repository for the currently shipping version—bugfixes, and another for the “next” version—new features), you have to go through the same steps to create a new deployment as you did for your initial set up. It is no fun repaving your machine, but that’s not something the interns needed to worry about too much, and only occasionally causes problems for us full-time developers.&lt;/p&gt;
&lt;p&gt;It’s worth noting here that development deployments most closely resemble a “licensed” deployment (i.e., the type of installation a customer uses when they install FogBugz or Kiln on their own servers). Setting up a development machine to behave like our “hosted” environment (i.e., the type of installation used for our FogBugz On Demand service where Fog Creek hosts everything for you) is much more complicated both to set up in the first place, as well as to update with new code. And honestly, doing the same for Kiln is almost unheard of.&lt;/p&gt;
&lt;p&gt;In summary, initial deployment to development machines can be somewhat painful, but ongoing deployment of changes for testing purposes is easy and relatively painless. We can work to make initial deployment more automated, as long as we preserve the ease of ongoing deployment. There are additional development deployment features we could also add, such as deploying to multiple virtual directories from a single copy of the source, scripted deployment to virtual machines, and scripted deployment to a test hosted (as opposed to licensed) environment.&lt;/p&gt;
&lt;h4&gt;Ourdot&lt;/h4&gt;
&lt;p&gt;After two to three weeks of intense development, code reviews, and hallway usability discussions, it was time for the interns to show off what they had done to the rest of the company. First, they did demos of their features after lunch one day. We got to see the first iterations of cool new features like Kiln search, the new FogBugz wiki editor, all the wiki navigation changes, repository aliases, “big files” support in Kiln, as well as the much-improved FogBugz permissions model. The more important aspect of their demo was deploying their code to the FogBugz and Kiln instance we use internally, so that everyone else in the company could start using it on a daily basis…and start reporting bugs on a daily basis. This install of FogBugz and Kiln is affectionately known as “ourdot”.&lt;/p&gt;
&lt;p&gt;Deployments to ourdot are unique. Unlike deployments to customers, our QA team, or dev machines, a separate set of scripts handles the work of building and deploying both products to ourdot, though they have much in common with our other build/deploy scripts. The ourdot install is a kind of cross between our licensed and hosted environments, and it’s often used as a testing ground for build and deployment changes as well as new features.&lt;/p&gt;
&lt;p&gt;We continued deployments to ourdot every two weeks during major feature development and then more frequently as the interns transitioned into bug fixing mode in preparation for the beta release. At the start of the summer, deploying both FogBugz and Kiln to ourdot was a very manual process. Scripts did much of the work of building and copying files, but modifying the configuration on the servers in order to handle a new build had to be done manually, and involved 5-10 manual steps for both products. One of my first projects after taking over build and release responsibilities was to get both of these scripts running completely autonomously. All that I have to do now is just kick off the build and deploy process, and then deal with failures if they occur, which is quite rare.&lt;/p&gt;
&lt;h4&gt;Generations&lt;/h4&gt;
&lt;p&gt;In preparation for our first beta release, we needed to make sure that everything was working correctly in our hosted environment. The hosted servers use an extension of &lt;a target="_blank" href="http://martinfowler.com/bliki/BlueGreenDeployment.html"&gt;blue-green deployment&lt;/a&gt; to manage the switchover of accounts from one version to another and also to support having different accounts running different versions at the same time. Each version deployed to our hosted servers becomes a “generation” and each account is running on a specific generation. Individual accounts can be moved from one generation to another (later) generation, and scripts make it easy to move some subset of accounts or to change the default generation. Changing the default generation upgrades accounts on the old default generation and ensures that new accounts are created on that generation.&lt;/p&gt;
&lt;p&gt;The reasons this deployment process works is because 1) deploying a new generation to the servers does not affect anyone on existing generations and 2) moving accounts from one generation to another does not affect other accounts. So we don’t have to deploy new generations at horrible hours of the night, or warn all accounts about downtime when only some are actually being upgraded.&lt;/p&gt;
&lt;p&gt;While this process works quite well from our users’ standpoint, there are important changes we can make to improve our efficiency. The scripts that build both FogBugz and Kiln for deployment to our hosted servers are not the same scripts that do builds and deployments for ourdot, licensed, or dev machine installs. However, they do share a lot of common functionality that could be consolidated (and will be, in time). Another improvement we’re looking at is combining our generation numbers with our version numbers, so we don’t have to track two different numbers when filing bugs and discussing changes to the software. Moving accounts to a new generation can be surprisingly quick, but deploying a new generation still takes too long, and is something we want to improve. Also, FogBugz generations and Kiln generations are unrelated, despite the tight integration between the two products.&lt;/p&gt;
&lt;p&gt;And now, back to the story of deploying FogBugz and Kiln! We went through a few deployments of new generations to get all the bugs worked out of the hosted deployment scripts. These “bugs” were typically things that had changed due to new features being added, but that had not yet been incorporated into our deployment scripts. Once we had a generation that built and deployed cleanly, we moved some testing accounts over so that our QA team could hammer it, and then proceeded to move alpha accounts over. Once the alpha accounts had been using the new code for a while we were ready to give the new version to beta customers.&lt;/p&gt;
&lt;h4&gt;Beta&lt;/h4&gt;
&lt;p&gt;As Joel described in &lt;a target="_blank" href="http://www.joelonsoftware.com/articles/BetaTest.html"&gt;Top Twelve Tips for Running a Beta Test&lt;/a&gt;, one key to a great product launch is a successful beta program. And the first thing you need for a good beta program are willing guinea pigs…um…I mean, users. For this rollout, we used an old web app that had been coded up for collecting beta applicant information for previous versions of FogBugz and Kiln. While not pretty, it got the job done, and when it didn’t we could always go straight to the beta applicant database and enter things directly if needed.&lt;/p&gt;
&lt;p&gt;Another important aspect of running a successful beta is getting the word out, so we gradually let our customers know with announcements on the &lt;a target="_blank" href="http://fogbugz.stackexchange.com/"&gt;FogBugz&lt;/a&gt; and &lt;a target="_blank" href="http://kiln.stackexchange.com/"&gt;Kiln&lt;/a&gt; support sites, email, announcements on the blog, and via Twitter. We spaced these out with the goal of having applicants come in at about the same rate that we were approving them, in hopes that no one would have to wait too long before being accepted into the beta. The beta application allowed anyone to sign up for the hosted beta, and all current licensed customers to sign up for the licensed beta.&lt;/p&gt;
&lt;p&gt;Once we had a stable generation for our hosted beta users to try out, we moved just 3 customer accounts to that generation and started watching for bug reports, support questions, etc. This may seem like an awfully small number, but we targeted customers who were already active on the support sites in hopes of getting good feedback. As that feedback started to come in and we were able to iterate on the issues raised, we slowly at first and then more quickly added more and more beta customers, roughly doubling the number each week until we had around 150 hosted beta accounts active, including some of our biggest customers.&lt;/p&gt;
&lt;h4&gt;Licensed Beta&lt;/h4&gt;
&lt;p&gt;Our licensed beta deployment process is probably the weakest link of our entire launch process. It did not break or cause major problems at any point, but it is almost completely manual. Basically, customers who signed up for the licensed beta are added to a list of potential beta users. We can then email any of these users with a unique download link that they can use to access the installer. The process of deploying a new installer involves manually copying each installer to the right location on our web servers, modifying the beta applicant database with the filename and size of each installer, manually verifying that the download links work for each installer, and then emailing all accepted beta customers a notification that the beta installer has been updated, and adding any new beta applicants to the beta.&lt;/p&gt;
&lt;p&gt;Overall, the first step in improving this process was just to automate it. Since we were only accepting existing licensed users, we could also improve it by integrating it with our existing shop website (the website that tracks orders, maintenance contracts, etc.), where these customers were already able to download copies of the installer they had purchased.&lt;/p&gt;
&lt;p&gt;Despite being so manual, and offering such obvious areas for improvement, we really had no major problems releasing licensed beta installers to our customers. Yes, it was kind of a pain, but it didn’t happen too often, and could have been a lot worse. Just as with the hosted beta, we initially informed just a few licensed beta applicants of the new download. Then as we received bug reports and fixed issues, we updated the download with new builds and informed more and more beta applicants until we had roughly 40 accounts using the new release, putting our total beta accounts (i.e., both hosted and licensed) at almost 200. At this point, the developers and QA staff on both the FogBugz and Kiln teams were feeling ready to start shipping to customers who had not applied for the beta. The final release was about to begin!&lt;/p&gt;
&lt;h4&gt;Leaking&lt;/h4&gt;
&lt;p&gt;Just as with the beta release, it’s helpful to roll out the final release to our hosted customers in stages. We call this “leaking the release,” which sounds kind of gross, but I like to think of it like sugar water leaking out of a bird feeder rather than, …well, you can come up with an appropriately negative metaphor yourself. The birds love it. As before, this gradual process helps us to catch issues before they have a chance of affecting everyone. Now that we’re dealing with 2-3 orders of magnitude more customers, it’s much more likely that we’ll run into performance problems with the new code. One serendipitous benefit of this type of release was that buzz about the new versions progressively increased over the course of the month leading up to the full rollout.&lt;/p&gt;
&lt;p&gt;Initially we bumped 5% of our hosted customers up to the new release generation. In doing so, we found some performance issues in the background processes that do maintenance work on the FogBugz database. Taking that back to the FogBugz developers, they were able to quickly come up with a fix, and we verified it a week later when we bumped to 15% of customers using the release generation. The rest of the generation bumps went flawlessly up to 65% of customers on the new version just a few days before our final 100% bump was scheduled. Once two thirds of our customers had the new versions of FogBugz and Kiln we saw a noticeable increase in comments on Twitter and other outlets about the new version.&lt;/p&gt;
&lt;p&gt;Even though there was still deployment work to do, this felt like a turning point to me. More of our hosted customers were using FogBugz 8 and Kiln 2 than were using versions 7 and 1 (respectively). Deployments had gone surprisingly well, with very few &lt;a target="_blank" href="http://www.fogcreek.com/FogBugz/docs/40/Articles/BugzScout.html"&gt;BugzScout&lt;/a&gt; reports popping up. The performance issues had been squashed, and no major hiccups occurred. If anything, it almost felt &lt;em&gt;too&lt;/em&gt; easy. We did the bump to 65% on a Wednesday night. Thursday’s project was a big one: deploy the new website, release our licensed installer, and update our shop website to handle purchases of and upgrades to the new licensed version.&lt;/p&gt;
&lt;h4&gt;The Big Switch&lt;/h4&gt;
&lt;p&gt;Deploying changes to our website is a fairly straightforward process, though it does (currently) take too long. A simple script is run that re-indexes the site, copies the files to our webservers, updates the server configuration, and then checks a few key files to make sure nothing broke. It takes over an hour to run; about two thirds of which is spent copying the files over to the web servers.&lt;/p&gt;
&lt;p&gt;But before we could pull the trigger, we needed to make sure that our shop website could handle purchases of the new versions of FogBugz and Kiln. Because major versions of our software are released relatively infrequently, this process has not yet been automated. So I got to get down and dirty with the shop database in order to add the necessary information about the new FogBugz and Kiln licensed products (and the various platforms they operate on). As part of this process we got the actual licensed installers for both products copied over to the web servers.&lt;/p&gt;
&lt;p&gt;These installers had gone through the normal beta process described above, and additionally had been hit pretty well by our QA team. With the changes to our shop website tested by doing some fake purchases, we were ready to actually deploy the website…which went off without a hitch. It was fun to announce to the company that the fancy new website (designed by &lt;a target="_blank" href="http://shipordie.com/"&gt;Jason&lt;/a&gt; and the rest of our design team) was up and to hear the excitement from everyone in the office. Although we weren’t totally done, this was the day that it felt like we had really shipped the product. New licensed customers were getting the new version, the website was up, and life was good.&lt;/p&gt;
&lt;h4&gt;100%&lt;/h4&gt;
&lt;p&gt;…but we weren’t really done…at least not yet. We still had one more generation bump to do for our hosted customers in order to get the remaining 35% of accounts using the new versions. This bump went even more smoothly than our previous ones. It felt so good to look at a simple DB query that showed all of our active accounts on the latest generations and know that we had shipped. It also felt pretty cool to know that we had done so by using the &lt;a target="_blank" href="http://www.fogcreek.com/FogBugz/"&gt;bug tracking abilities of FogBugz&lt;/a&gt; and the &lt;a target="_blank" href="http://fogcreek.com/kiln/"&gt;great source control provided by Kiln&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This final bump to 100% of hosted customers to the new version also bumped our new signups to start getting the new version as well. One thing we really want to fix the next time around is to decouple that switch so that new customers can start getting the new version earlier on in the release process. As things stood, there were three days when new hosted customers were getting the old versions of FogBugz and Kiln despite the fact that we’d already updated our website and were actively promoting the new versions.&lt;/p&gt;
&lt;h4&gt;Final Notification&lt;/h4&gt;
&lt;p&gt;Once more, it was time to iteratively “leak” the new version of FogBugz and Kiln–this time by notifying our licensed customers that there was a new version available for them to download and install. True, some of them would notice it on their shop page after having read or heard about the new version online. But most will just wait for the notification in FogBugz, then go to our website to download the new installers and upgrade. Those who don’t have support contracts will need to &lt;a href="http://www.fogcreek.com/FogBugz/PriceList.html"&gt;pay for the new version or get their support contracts up to date&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, we notified some percentage of our licensed customers every couple of days over the next two weeks until we had 100% of them notified by early October. This helped to spread out the bandwidth load from customers downloading the rather large installer files, and allowed us the same wiggle room to fix any bad bugs in the installers or any licensed-specific code issues before it got out to all of our customers.&lt;/p&gt;
&lt;h4&gt;Final Thoughts&lt;/h4&gt;
&lt;p&gt;With all that done, we’ve already shipped our first set of bug fixes to customers—within a &lt;em&gt;week&lt;/em&gt; of finishing the process of notifying our customers about the new versions. This is the low-hanging fruit that was important to fix, but not so important as to delay shipping FogBugz 8 or Kiln 2 to our customers. It’s easy at the end of a cycle to get caught up in perfectionism and think that every bug absolutely needs to be fixed, but after a certain point it’s more important to get it to your customers and find out which bugs they are actually seeing (you might be surprised). And besides, your customers might find much worse bugs to focus on that you never would have found in-house. Or they might just want some small feature that didn’t manage to make its way into the initial launch release.&lt;/p&gt;
&lt;p&gt;As I said earlier, everything good about this process is credited to the entire FogBugz and Kiln team that got it in place over the past few years and many releases. &lt;a target="_blank" href="http://benkamens.com/"&gt;Ben Kamens&lt;/a&gt; owned all of this process before handing it off to me, and did a great job getting me up to speed as I tried to digest all of the new information.&lt;/p&gt;
&lt;p&gt;And now that we’ve shipped, we’re already working to improve the way we work internally so that we can get bug fixes and new features to our customers more quickly. You know you work with a great team when an impromptu post-ship meeting where the only agenda item is “Congratulations for the team!” turns into a great technical discussion about next steps to improve the product because everyone is so geared up about making it even better.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1365832676</link><guid>http://thoughts.rockhymas.com/post/1365832676</guid><pubDate>Thu, 21 Oct 2010 08:32:22 -0400</pubDate></item><item><title>Do you store built binaries in your VCS?</title><description>&lt;p&gt;Do not store the output of a build in your version control system along with your code. Period. If you work on an interesting product, it is bound to be comprised of multiple components that all fit together in interesting and complex ways. For reasons you may have had no say in, some of those components are built and checked into the source code for use in building a larger product. Do not do this. It will bite you in the end.&lt;/p&gt;

&lt;p&gt;First, you have the problem of interfaces. These components interact with the large product through an interface of some sort. Since you’re building the component and the larger product you control that interface. But if a developer has to build the component and check it in for it to be included in the larger product you can get into situations where the interface changes, but the component hasn’t been updated. Oh sure, you can setup rules that remind developers to rebuild and checkin a component if it’s interface changes, but now your developers just have one more thing to remember - and they will forget. Do not do this. It will bite you in the end.&lt;/p&gt;

&lt;p&gt;Second, you have the problem of repository size. True, this isn’t as much of an issue for a CVCS such as Subversion. But for a DVCS, which you should be using to store your code anyway, this can cause problems over time. And if you’re patting yourself on the back for using a CVCS, just wait, you’ll come around eventually. And when you do, you’ll care about the size of your whole repository, not just a single revision. Cloning large repositories, made large by many large binary checkins, can take large amounts of time. Do not do this. It will bite you in the end.&lt;/p&gt;

&lt;p&gt;Finally, you have the problem of build processes. Because of the need for built binaries to create your entire product, it only makes sense to checkin the binaries for a component once they’ve been built. But now your build scripts are doing more than just building. And you need to make sure the scripts aren’t checking in the binaries each time a developer runs the build on his or her box. And if you have a single script that actually builds the entire product, it is either lying (i.e. you still need to build and checkin the component first), or it’s doing more work than it need to (i.e. you are building the component, checking it into source, then checking it out again). Do not do this. It will bite you in the end.&lt;/p&gt;

&lt;p&gt;So what do you need to do to solve this problem? First, make sure your build scripts are doing more work than they need to - build all components, checkin, checkout. Then, remove the checkin/checkout steps.&lt;/p&gt;

&lt;p&gt;Of course, this does raise some issues. Now developers who could blithely ignore the component in question will need to make sure they have the code for it, so the build scripts will be able to operate correctly. If you’re doing daily builds, and storing the built files, you can optimize your build scripts in development environments to grab the built components from storage if they don’t have the code. This will work fine for developers who don’t change the interface between the two components. Developers who do change the interface will need the code for the component anyway. And of course, if it builds quickly, all developers can just clone the code and build it.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1210746386</link><guid>http://thoughts.rockhymas.com/post/1210746386</guid><pubDate>Wed, 29 Sep 2010 11:35:02 -0400</pubDate></item><item><title>First very cool facetime call - watching my daughter sitting in a bumbo for the first time. Complete...</title><description>&lt;p&gt;First very cool facetime call - watching my daughter sitting in a bumbo for the first time. Complete with bobble-head effects.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1203287018</link><guid>http://thoughts.rockhymas.com/post/1203287018</guid><pubDate>Tue, 28 Sep 2010 02:08:25 -0400</pubDate></item><item><title>RT @FogBugz: FogBugz 8 is officially launched: http://bit.ly/c9D2Ki And Kiln 2 is out too:...</title><description>&lt;p&gt;RT @FogBugz: FogBugz 8 is officially launched: &lt;a href="http://bit.ly/c9D2Ki"&gt;http://bit.ly/c9D2Ki&lt;/a&gt; And Kiln 2 is out too: &lt;a href="http://bit.ly/9K1yEM"&gt;http://bit.ly/9K1yEM&lt;/a&gt; Get better at everythi …&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1203287011</link><guid>http://thoughts.rockhymas.com/post/1203287011</guid><pubDate>Tue, 28 Sep 2010 02:08:25 -0400</pubDate></item><item><title>RT @jonsagara: Installing the Kiln client. Impressed that it knew to install 64-bit TortoiseHg.</title><description>&lt;p&gt;RT @jonsagara: Installing the Kiln client. Impressed that it knew to install 64-bit TortoiseHg.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1179318576</link><guid>http://thoughts.rockhymas.com/post/1179318576</guid><pubDate>Fri, 24 Sep 2010 11:46:43 -0400</pubDate></item><item><title>Do you save your old builds? </title><description>&lt;p&gt;If you’re not currently saving your old builds, you should start now. Saving old builds can be very useful for a few reasons. First, it makes it quicker to start debugging problems that only shows up sin an old build. Second, it is insurance against the possibility of not being able to recreate your build environment correctly.&lt;/p&gt;

&lt;p&gt;For hosted environments, where you control the deployment of the software, just keeping a couple of old builds around is probably enough. Being able to roll back if something goes horribly wrong can be a life-saver. For installed software, it’s important to keep all old builds that are still available in the wild or that customers might legitimately want for some reason. Practically, this works out to be all builds that you’ve released in some form to customers. During development, it can also be useful to have a few recent builds available that have only been released to the QA team to easily compare versions.&lt;/p&gt;

&lt;p&gt;As a simple first step, you can simply store old builds on a file share. It’s not too much more work to store them in a version control system. Make sure to use a VCS that can handle large binary files easily - SVN is a good choice currently - so that you don’t have to worry about performance issues in the future.&lt;/p&gt;

&lt;p&gt;Finally, when storing old builds, make sure to keep each configuration of the build. When a customer reports a problem in an old release, having a debug build of the code with symbols can rapidly decrease the time it takes to respond to their problem.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1167543667</link><guid>http://thoughts.rockhymas.com/post/1167543667</guid><pubDate>Wed, 22 Sep 2010 11:41:40 -0400</pubDate></item><item><title>Do you have an official build machine or set of build machines?</title><description>&lt;p&gt;An official build machine is an important tool for building and releasing software. If you don’t have a machine dedicated to that purpose, you have to worry about where each build and release comes from. Is the environment the same? Are all the dependencies the same? Which developer’s box do builds typically come from? What if he or she is out on vacation? Can you emulate that box enough to produce an equivalent build and release?&lt;/p&gt;

&lt;p&gt;The answers to these questions may vary from product to product and company to company. The simplest solution, however, is to have a dedicated build machine that has a known environment, has all of the correct dependencies set up, and can be used to cut official builds whenever necessary.&lt;/p&gt;

&lt;p&gt;This build machine (or set of machines, for larger products and longer builds) will be where official builds are created for release to internally, to beta users, and for customers. It can also be the machine that handles continuous integration or continuous deployment responsibilities. As such, it will not only be building the software, but running sets of tests, once it is built. Getting this machine up and running, and maintaining it as necessary, are the primary responsibilities of the a build and release manager.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1138167537</link><guid>http://thoughts.rockhymas.com/post/1138167537</guid><pubDate>Fri, 17 Sep 2010 12:58:14 -0400</pubDate></item><item><title>Can you build all possible configurations using command line parameters?</title><description>&lt;p&gt;It’s important that you have a &lt;a href="http://thoughts.rockhymas.com/post/931921833/can-you-build-your-product-with-one-command"&gt;single build script&lt;/a&gt; to build your product - every configuration of your product. Having a separate script for debug vs release, or x86 vs x64 architecture, is only going to cause problems. If the actual built files need to be different for different deployment target, then these targets also become build configurations, such as hosted vs installed. And the build script need to be able to build each of these configurations.&lt;/p&gt;

&lt;p&gt;The easiest way to do this is to have the build script take command line parameters that specify which configurations to build (or to build all of them). The command line parameters should be short, or have short versions, to make it easier to run the script frequently.&lt;/p&gt;

&lt;p&gt;Rather than specify that the script should build one configuration or another, it should be allowed to build multiple configurations. This requires that each configuration build to a different location. So you may have a build directory next to or within your source directory, that has a subdirectory for each configuration built. The simplest example of this is Visual Studio’s bin\Debug and bin\Release directories for it’s default projects.&lt;/p&gt;

&lt;p&gt;Obviously, you shouldn’t need to enter command line parameters. The defaults should be the configuration(s) that developers will use most often. It may be helpful to make it easy for developers to easily configure their defaults in a settings file, if different developers have different needs.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1132377519</link><guid>http://thoughts.rockhymas.com/post/1132377519</guid><pubDate>Thu, 16 Sep 2010 11:50:15 -0400</pubDate></item><item><title>Sped up our build today by detecting service stop rather than waiting five minutes (twice) in hopes...</title><description>&lt;p&gt;Sped up our build today by detecting service stop rather than waiting five minutes (twice) in hopes it had happened&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1126305064</link><guid>http://thoughts.rockhymas.com/post/1126305064</guid><pubDate>Wed, 15 Sep 2010 08:48:20 -0400</pubDate></item><item><title>Why should my build and deployment scripts be separate?</title><description>&lt;p&gt;You may ask this question when you notice that every time you build, you also deploy. What’s the point in keeping the scripts separate if they will always be run together? Before listing all of the reasons I can think of, let me tell you about a bug we recently had in our (currently combined) build and deployment script.&lt;/p&gt;

&lt;p&gt;The installer for our licensed FogBugz product is created by a single script that builds both the FogBugz binaries, as well as the installer program that includes all of the binaries in a zipped up cab file. The script first copies all of the files that will be needed in the cab to a specific directory, then builds them, then  adds everything in the directory to the cab file, and proceeds to build the installer. A developer recently noticed that certain files were not being included in the cab file that should have been. Closer investigation revealed that the step to create those files failed because the tool necessary to build them wasn’t one of the files copied into the directory to be zipped into the cab.&lt;/p&gt;

&lt;p&gt;Now obviously, a lot had to go wrong for this to happen. The build didn’t correctly report the failure to build those files. The build tool required was part of the code repository instead of being  placed in a common build tools repository. The build tool required was called via a path relative to the code, rather than relative to the build script. But the issue I’m looking at today is that we mixed up steps that were meant for the deployment with steps meant for the build.&lt;/p&gt;

&lt;p&gt;In this case, the deployment script was the script that took built FogBugz files and created an installer with them (deploying to a setup program, as opposed to deploying to the web). Because the steps were mixed together instead of strictly separated, the necessary build tool was not at the expected location, and the build failed (silently, unfortunately).&lt;/p&gt;

&lt;p&gt;There are obviously less architectural changes we could make that would have helped us identify and fix this issue more quickly - things like reporting all build errors, or calling the build tool with a path relative to the build script, not the code. But separating the build and deployment scripts would have prevented the bug from occurring in the first place.&lt;/p&gt;

&lt;p&gt;Keeping the scripts separate has the following advantages:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Bugs caused by mixing deployment steps into the build script go away.&lt;/li&gt;
&lt;li&gt;A single build can be used for multiple deployments (to an installer, to a web site, on a dev machine)&lt;/li&gt;
&lt;li&gt;Developers can use the build script on their dev machine, instead of doing the build manually or having a separate script that must be kept in sync.&lt;/li&gt;
&lt;li&gt;The development team can take ownership of the build scripts, without having to worry about the details of deploying, which can be left to system administrators and release managers.&lt;/li&gt;
&lt;/ol&gt;</description><link>http://thoughts.rockhymas.com/post/1121349192</link><guid>http://thoughts.rockhymas.com/post/1121349192</guid><pubDate>Tue, 14 Sep 2010 11:55:52 -0400</pubDate></item><item><title>Are your build scripts crusty and old?</title><description>&lt;p&gt;The other day I was trying to get one of our build scripts at work to run on a new build machine we’d brought up. Because all of our build scripts haven’t been actively maintained, they are very much tied to the environment and other hard dependencies of the existing build machine. And so getting them to work somewhere else (without modifying the script) involves a lot of work to setup all of these &lt;a href="http://thoughts.rockhymas.com/post/947094911/do-your-builds-have-other-hard-dependencies"&gt;hard dependencies&lt;/a&gt;. It’s good for me to do this so I can get a better understanding of everything our build scripts do, and why they do those things, and what could reasonably be changed.&lt;/p&gt;

&lt;p&gt;Anyway, so in this process I got to a step that was failing in the new build machine. It was trying to access an internal Subversion server for some files, but the new machine could not see the server because of our network configuration. Changing the network configuration wasn’t really an option, so at a bare minimum we’d have to make changes to the build script. After puzzling over it for a little while I finally realized that the step in question is no longer used or relevant at all (you probably guessed that when I mentioned Subversion, since we offer a competing product). It might as well be a no-op. Even better, the same step had caused failures on the official build machine in the past, failures which I worked with our system administrator to fix, so that our builds wouldn’t be broken. But we could have just as easily removed the failing step, instead of continuing to maintain rotting script code.&lt;/p&gt;

&lt;p&gt;It was humbling to realize I hadn’t found this issue when it broke on the official build machine. But it also made me realize that build scripts must be actively maintained. If they are not, they will rot. When they do, you’ll get random build failures at the most inopportune times, and you won’t have confidence in the fix, or even if the fix is necessary.&lt;/p&gt;

&lt;p&gt;In this particular case, it would be easy to fix it (by removing the dead code) and make no other changes to our process. Fixing it will certainly happen. But we really need to “fix it twice”, by going to the root cause and fixing that issue. The clearest way to do that, in our current situation, is to move forward with a  plan I already have - to refactor and combine our build scripts so that developers use the same scripts as the official build machine. Once that happens, we can move ownership of the build scripts back to the development team. Because they will no longer be tied to just one “official” build machine, they’ll naturally be fixed and cleaned up by the developers who use them on a daily basis to get their work done. As build manager, I’ll just need to make sure the scripts still work on the build machine.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1098426283</link><guid>http://thoughts.rockhymas.com/post/1098426283</guid><pubDate>Fri, 10 Sep 2010 15:58:43 -0400</pubDate></item><item><title>Do not intermix your deployment scripts with your build scripts. It only causes pain.</title><description>&lt;p&gt;Do not intermix your deployment scripts with your build scripts. It only causes pain.&lt;/p&gt;</description><link>http://thoughts.rockhymas.com/post/1094255523</link><guid>http://thoughts.rockhymas.com/post/1094255523</guid><pubDate>Thu, 09 Sep 2010 20:04:32 -0400</pubDate></item></channel></rss>

