<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title type="text">Effectif Development</title>
  <generator uri="http://nestacms.com">Nesta</generator>
  <id>tag:effectif.com,2009:/</id>
  
  <link href="http://effectif.com/" rel="alternate" />
  <subtitle type="text">(agile web development and consultancy)</subtitle>
  <updated>2013-04-15T00:00:00+00:00</updated>
  <author>
    <name>Graham Ashton</name>
    <uri>http://effectif.com</uri>
    <email>graham@effectif.com</email>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/effectif-development" /><feedburner:info uri="effectif-development" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Silky Markdown editing on Mac</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/uBmyXLjYcV4/easier-markdown-editing-on-mac" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2013-04-15:/mac-os-x/easier-markdown-editing-on-mac</id>
    <content type="html">&lt;p&gt;If you write in Markdown on a Mac you'll no doubt have dabbled with TextMate at some point. If you did, perhaps you discovered some of TextMate's marvellous Markdown mode commands, such as "Google for the highlighted text, and convert it to a link to the first search result" (if memory serves, it was Cmd-Alt-Ctrl-L)?&lt;/p&gt;

&lt;p&gt;Editor support like that makes writing in Markdown very productive, but these days I tend to pen my blog posts in simpler editors. Luckily, with &lt;a href="http://brettterpstra.com/projects/markdown-service-tools/"&gt;Markdown Service Tools&lt;/a&gt; you can now setup similar keybindings that work in any app built on top of Cocoa (which is pretty much all of them).&lt;/p&gt;

&lt;p&gt;It's pretty easy to do.&lt;/p&gt;

&lt;h2&gt;Step 1 - install Markdown Service Tools&lt;/h2&gt;

&lt;p&gt;Grab the &lt;a href="http://brettterpstra.com/projects/markdown-service-tools/#download"&gt;zip file&lt;/a&gt; and uncompress it into your &lt;code&gt;~/Library/Services&lt;/code&gt; folder (you may need to create it).&lt;/p&gt;

&lt;h2&gt;Step 2 - setup a keybinding&lt;/h2&gt;

&lt;p&gt;Open System Preferences and head to the keyboard shortcuts pane. You should find a bunch of services with names that start with "md" (you may also have to wait a minute or so while your Mac reindexes your services before opening the preferences pain or they won't show up).&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/0r3r2O2j0t3u2y12260Z/keybindings-for-services.png" alt="Mac Keyboard Shortcuts" /&gt;&lt;/p&gt;

&lt;p&gt;Setup a key binding, and off you go...&lt;/p&gt;</content>
    <published>2013-04-15T00:00:00+00:00</published>
    <updated>2013-04-15T00:00:00+00:00</updated>
    <category term="mac-os-x" />
  <feedburner:origLink>http://effectif.com/mac-os-x/easier-markdown-editing-on-mac</feedburner:origLink></entry>
  <entry>
    <title>Finding perpetual inspiration</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/BeOmwcG7ADI/maintaining-your-inspiration" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2013-02-28:/productivity/maintaining-your-inspiration</id>
    <content type="html">&lt;p&gt;I've been reading &lt;a href="http://executebook.com"&gt;Execute&lt;/a&gt; this week, a book about how we can act on inspiration to create great things, fast. It tells the story of how Drew Wilson conceived, &lt;strong&gt;built&lt;/strong&gt; and shipped a competitor to &lt;strong&gt;PayPal in a week&lt;/strong&gt; (as if to make the point, Josh Long and Drew Wilson wrote the book itself in a week). One of the ideas that has resonated most strongly with me is the "inspiration battery".&lt;/p&gt;

&lt;p&gt;It's all well and good getting pumped up and working hard when the inspiration from your latest great idea is fresh, but inspiration (and therefore motivation) comes and goes. We'd all get more done if we were &lt;strong&gt;perpetually inspired&lt;/strong&gt; to do great things, but it doesn't tend to work like that.&lt;/p&gt;

&lt;p&gt;The energy we get from feeling inspired can wane, but we can get it back (recharging the battery) by working on something that excites us. As Josh wrote:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Everyone of us has an element of what we do that we enjoy more than all of the others. For Drew, it's design. He loves it. [snip] Design recharges Drew.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;It's useful to acknowledge that we shouldn't always work on the next most important thing. Maintaining our energy (through enjoyment and satisfaction) is often a more important factor for the progress we can achieve on a project.&lt;/p&gt;

&lt;p&gt;Once you know which tasks recharge your batteries you can allow yourself to work on these things whenever you feel your motivation starting to wane.&lt;/p&gt;

&lt;p&gt;I've sometimes struggled to justify to others quite why I've prioritised a particular feature, knowing full well that I've chosen to work on something that will keep me excited. As a recent example, &lt;a href="https://www.agileplannerapp.com/tour"&gt;Agile Planner&lt;/a&gt; had a fully fledged &lt;a href="https://www.agileplannerapp.com/developers/api"&gt;REST API&lt;/a&gt; before I'd enabled sign ups to the free trial.&lt;/p&gt;

&lt;p&gt;I built the API earlier than necessary because I knew that I'd get fired up about the impact that it would have on the code, and would give me more opportunity to benefit from the &lt;a href="https://www.agileplannerapp.com/blog/building-agile-planner/refactoring-with-hexagonal-rails"&gt;hexagonal architecture&lt;/a&gt; that is evolving in Agile Planner.&lt;/p&gt;</content>
    <published>2013-02-28T12:00:00+00:00</published>
    <updated>2013-02-28T12:00:00+00:00</updated>
    <category term="productivity" />
  <feedburner:origLink>http://effectif.com/productivity/maintaining-your-inspiration</feedburner:origLink></entry>
  <entry>
    <title>Finding bugs with git bisect</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/824-ZU6S2JE/simple-approach-to-finding-bugs-with-git-bisect" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-11-21:/git/simple-approach-to-finding-bugs-with-git-bisect</id>
    <content type="html">&lt;p&gt;When a bug has crept in to your code that you're having trouble fixing, it
helps to know when it was introduced. If you can prove which code caused the
bug you can normally work out why. The &lt;code&gt;git bisect&lt;/code&gt; command is here to help you
track it down...&lt;/p&gt;

&lt;p&gt;It works like this. You tell git three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The SHA of the &lt;strong&gt;most recent good commit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The SHA of &lt;strong&gt;a bad commit&lt;/strong&gt; that you know has the bug.&lt;/li&gt;
&lt;li&gt;A command that git can run that will exit with a non-zero exit status when
the bug is present (in other words, you &lt;strong&gt;tell it how to run your tests&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Setting up the bisect&lt;/h2&gt;

&lt;p&gt;Early today I managed to introduce a bug somewhere in my topic branch, while
doing some copy writing and tidying up my sales pages. I hadn't edited any real
code, but my tests were failing anyway. I had no idea why.&lt;/p&gt;

&lt;p&gt;I quickly ran the tests on the &lt;code&gt;master&lt;/code&gt; branch to prove that it wasn't a
problem with my environment. They passed – the problem was definitely in one of
the commits on my topic branch.&lt;/p&gt;

&lt;p&gt;I knew that my &lt;strong&gt;last good commit&lt;/strong&gt; was &lt;code&gt;master&lt;/code&gt;. The &lt;strong&gt;earliest bad commit&lt;/strong&gt;
that I'm aware of is the head of my topic branch.&lt;/p&gt;

&lt;p&gt;This is how you pass that information to git:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git bisect start [&amp;lt;bad&amp;gt; [&amp;lt;good&amp;gt;]]&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So in my case, I typed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git bisect topic-branch master&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Testing all the commits&lt;/h2&gt;

&lt;p&gt;To kick things off you give git the name of a command to run. It needs to exit
with an exit status of 0 if the commit is good, and non-zero if it's a bad one.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git bisect run &amp;lt;command&amp;gt;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My command was a simple one; I just ran some of my tests.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git bisect run ruby test/functional/activities_controller_test.rb&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My computer churned away for a bit, continually re-running the tests on
different commits. Rather than just running the tests against each commit on
the branch, it's smart enough to optimise the full run by selecting which
commit to test next with a binary chop.&lt;/p&gt;

&lt;p&gt;When it finished I checked the output of &lt;code&gt;git bisect log&lt;/code&gt; to see the results.
Look towards the bottom of the output and find the last commit marked as bad.
In my case, it looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# bad: [61a0e9249a2ef2b1a1cb31562782bf2de05c782c] Added pricing page with the Early Adopter plan.&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adding a new page seemed pretty innocuous, but finding the problem was pretty
straightforward when I looked at the diff. An innocent change to the routes
file had uncovered a badly written (unrelated) test that started failing as a
side effect.&lt;/p&gt;

&lt;h2&gt;Cleaning up&lt;/h2&gt;

&lt;p&gt;When you know where the problem came from, a quick reset will get you back
to the head of your branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git bisect reset&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;</content>
    <published>2012-11-21T21:00:00+00:00</published>
    <updated>2012-11-21T21:00:00+00:00</updated>
    <category term="git" />
  <feedburner:origLink>http://effectif.com/git/simple-approach-to-finding-bugs-with-git-bisect</feedburner:origLink></entry>
  <entry>
    <title>Testing IE on development sites</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/FLYo5dNqDlk/testing-ie-on-development-sites" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-11-13:/automation/testing-ie-on-development-sites</id>
    <content type="html">&lt;p&gt;When was the last time you finished some web development work (on your shiny, modern operating system) only to find that it didn't work in IE8. Or in IE9. Or a reasonably recent version of Opera. If you're developing web sites profesionally, you need to test them in multiple browsers running on multiple operating systems. I used to maintain virtual machines running Windows that could connect to my local dev server. These days I use BrowserStack.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.browserstack.com"&gt;BrowserStack&lt;/a&gt; gives you access to a long list of different web browsers, running on a wide selection of operating systems. It works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A virtual machine running the browser of your choice is fired up for you on demand.&lt;/li&gt;
&lt;li&gt;You use the remote browser to connect to your site, satisfy yourself
that it works&lt;/li&gt;
&lt;li&gt;You tell BrowserStack to load the next browser.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here's a screenshot of the UI, showing which browsers are currently available for testing on Windows XP:&lt;/p&gt;

&lt;p&gt;&lt;img class="screenshot" src="/attachments/browser-stack-browsers.png"&gt;&lt;/p&gt;

&lt;p&gt;Now, because the virtual machine is running on BrowserStack's servers, the browser you're testing won't be able to access your local development server. To get around this, BrowserStack supports tunnelling. If you enable Java in your browser and (on Mac at least) configure the right security settings in your system's Java config, it works rather well.&lt;/p&gt;

&lt;h2&gt;Setup a tunnel from the command line&lt;/h2&gt;

&lt;p&gt;I'd rather not meddle with a browser plugin. Luckily BrowserStack has given us a rather nifty alternative, and we can setup a tunnel via the command line. Like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ java -jar BrowserStackTunnel.jar &amp;lt;key&amp;gt; &amp;lt;host&amp;gt;,&amp;lt;port&amp;gt;,&amp;lt;ssl-flag&amp;gt;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;BrowserStackTunnel.jar&lt;/code&gt; file can be &lt;a href="http://www.browserstack.com/BrowserStackTunnel.jar"&gt;downloaded here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only problem is, I'll never remember that incantation, and most of the time the settings I want to use are the same.&lt;/p&gt;

&lt;p&gt;Time for a little automation. I wrote a script that let's me setup a tunnel to a local Rails app like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ browser-stack-tunnel&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I'm usually testing a Rails app, that runs on port 3000 on my localhost. The script takes the port and hostname as optional arguments, so if I wanted to test a Sinatra app on port 9393 I could just type this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ browser-stack-tunnel 9393&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The hostname can be specified as a second optional argument. I'm unlikely to need to specify anything other than localhost, but I exposed it in case you do.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ browser-stack-tunnel [port] [hostname]&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's the script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh&amp;#x000A;#&amp;#x000A;# See http://www.browserstack.com/local-testing to get the jar file.&amp;#x000A;&amp;#x000A;KEY_FILE="$HOME/.browser-stack.key"&amp;#x000A;&amp;#x000A;if [ ! -f $KEY_FILE ]; then&amp;#x000A;    echo "Error: Can't find $KEY_FILE"&amp;#x000A;    exit 1&amp;#x000A;fi&amp;#x000A;&amp;#x000A;KEY="$(cat $KEY_FILE)"&amp;#x000A;PORT="${1:-3000}"&amp;#x000A;HOST="${2:-localhost}"&amp;#x000A;&amp;#x000A;java -jar /usr/local/share/BrowserStackTunnel.jar $KEY $HOST,$PORT,0&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You'll notice the &lt;code&gt;KEY_FILE&lt;/code&gt; variable. Every user has a different key, which BrowserStack needs in order to identify you. You can find it on the &lt;a href="http://www.browserstack.com/local-testing"&gt;local testing&lt;/a&gt; page. Add it to a file called &lt;code&gt;~/.browser-stack.key&lt;/code&gt;, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo 'YOURKEYHERE' &amp;gt; ~/.browser-stack.key&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also download the script &lt;a href="https://github.com/gma/gma-utils/blob/master/bin/browser-stack-tunnel"&gt;from GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What's the point?&lt;/h2&gt;

&lt;p&gt;Some might argue that the script is so simple that it's barely worth writing. But, lowering the barrier to testing my CSS in different browsers &lt;em&gt;while I'm writing the CSS&lt;/em&gt; has sped up my front end development. Layout bugs get less chance to creep in if I'm testing in IE every half hour, and that's definitely worth it!&lt;/p&gt;</content>
    <published>2012-11-13T17:00:00+00:00</published>
    <updated>2012-11-13T17:00:00+00:00</updated>
    <category term="automation" />
    <category term="software-testing" />
  <feedburner:origLink>http://effectif.com/automation/testing-ie-on-development-sites</feedburner:origLink></entry>
  <entry>
    <title>Printing discount codes on your business card</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/uXqG12YL26Q/printing-discount-codes-on-your-business-card" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-09-05:/startups/printing-discount-codes-on-your-business-card</id>
    <content type="html">&lt;p&gt;When you're running a startup you get asked for your business card. A
lot. While you're still in private beta and are controlling how many
people can access your app it's fairly common to send people an
invitation code, which they can use on your sign up page to get access
to your app. That's what I've done with &lt;a href="https://www.agileplannerapp.com"&gt;Agile Planner&lt;/a&gt;. Why not hand
out invite codes on your business card?&lt;/p&gt;

&lt;p&gt;I'm now using GraphicsMagick and &lt;a href="http://www.moo.com"&gt;Moo&lt;/a&gt; to print a unique invite code
on each business card, which provides everybody I hand my card to with
their own unique invite. It also makes my card more valuable than it
would be if it all it had on it were my contact details, which should
increase the likelihood that potential customers will visit the site and
join my mailing list.&lt;/p&gt;

&lt;p&gt;Here are the cards:&lt;/p&gt;

&lt;p&gt;&lt;img src="/attachments/business-cards.jpg"&gt;&lt;/p&gt;

&lt;p&gt;Fancy doing it yourself?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read more in &lt;a href="https://www.agileplannerapp.com/blog/building-agile-planner/moo-card-codes"&gt;the full blog post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Get the script from the &lt;a href="https://github.com/gma/moo-card-codes"&gt;moo-card-codes&lt;/a&gt; GitHub repository.&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2012-09-05T00:00:00+00:00</published>
    <updated>2012-09-05T00:00:00+00:00</updated>
  <feedburner:origLink>http://effectif.com/startups/printing-discount-codes-on-your-business-card</feedburner:origLink></entry>
  <entry>
    <title>Hiding data in Rails with default_scope</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/arZayWhZpfY/hiding-data-with-default-scope" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-08-06:/ruby-on-rails/hiding-data-with-default-scope</id>
    <content type="html">&lt;p&gt;One of active record’s less well known features is the &lt;code&gt;default_scope&lt;/code&gt; class
method. I've just added support for deleting cards to &lt;a href="https://www.agileplannerapp.com"&gt;The Agile
Planner&lt;/a&gt;. Rather than destroy users’ data
immediately when they click the delete button, I wanted to give them an
opportunity to recover from mistakes, but I didn't have time to implement a
full undo system right now.&lt;/p&gt;

&lt;p&gt;My solution was to hide cards from the user interface after they've been
deleted, and to write a cron job that will periodically remove old deleted
cards from the database.&lt;/p&gt;

&lt;p&gt;Yes, this is a bit basic, but it's not worth me adding full undo/redo support
yet, as there are plenty of more important things to work on. If a user deletes
a card by mistake, and they really need the data that's on it, they can always
ask me to restore it from backup. Rather than digging through my backups I'll
just be able to toggle a setting on the card to bring it back to life. And you
never know, accidental deletion might be a very rare event. I'll improve it if
I need to.&lt;/p&gt;

&lt;p&gt;The relevant sections of my ActiveRecord models look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Iteration &amp;lt; ActiveRecord::Base&amp;#x000A;  has_many :cards&amp;#x000A;end&amp;#x000A;&amp;#x000A;class Card &amp;lt; ActiveRecord::Base&amp;#x000A;  belongs_to :iteration&amp;#x000A;  default_scope where(deleted: false)&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So to find all the cards that belong to an iteration and haven't been deleted I
can just use the cards scope. It'll filter all the deleted cards out
automatically:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;iteration.cards  # &amp;lt;- no deleted cards here&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to get at the deleted cards, you can use the &lt;code&gt;unscoped&lt;/code&gt; method to
remove the default scope.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Card.unscoped { iteration.cards }  # &amp;lt;- also returns deleted cards&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's such a simple approach that it took me less than an hour to develop and
deploy the deletion of cards into production.&lt;/p&gt;

&lt;h2&gt;A warning&lt;/h2&gt;

&lt;p&gt;This isn't something that I'd advocate using very often. Opportunities for
misleading yourself and your co-workers are legion, but when it's a good fit
for a problem like this it comes in very handy. I really didn't want to trawl
round the app to find all of the methods that iterate over cards and manually
filter out the deleted ones.&lt;/p&gt;</content>
    <published>2012-08-06T09:30:00+00:00</published>
    <updated>2012-08-06T09:30:00+00:00</updated>
    <category term="ruby-on-rails" />
  <feedburner:origLink>http://effectif.com/ruby-on-rails/hiding-data-with-default-scope</feedburner:origLink></entry>
  <entry>
    <title>Heroku deploy script (for Rails)</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/xtSV_syc2Go/heroku-deploy" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-06-25:/ruby-on-rails/heroku-deploy</id>
    <content type="html">&lt;p&gt;On the face of it, deploying a Rails app to Heroku is very simple. You just push your Git repository to the master branch of your repository on Heroku, then sit back and watch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git push heroku master&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Heroku will detect that your repository contains a Rails app, do a bit of house keeping, and restart your web servers for you.&lt;/p&gt;

&lt;p&gt;But... (there's always a "but") Heroku won't run your migrations automatically. You'll need to do that yourself, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku run rake db:migrate&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if you need to run migrations, any requests that reach your app before the migrations have been run could fail when Rails fails to find the right things in your database. You'll want to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push the new code.&lt;/li&gt;
&lt;li&gt;Put the app into maintenance mode.&lt;/li&gt;
&lt;li&gt;Run the migrations.&lt;/li&gt;
&lt;li&gt;Disable maintenance mode.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;If you've setup a second Heroku app to serve as a staging server, things becomes even more complicated, as you'll need to specify which app to use for each Heroku command.&lt;/p&gt;

&lt;p&gt;And when deploying to production, wouldn't it be prudent to take a quick database snapshot first?&lt;/p&gt;

&lt;p&gt;Time to automate this, I think...&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;Grab the &lt;code&gt;deploy.sh&lt;/code&gt; script from the &lt;a href="https://github.com/gma/heroku-deploy-rails"&gt;heroku-deploy-rails repo&lt;/a&gt; and commit it to your Rails app's git repository.&lt;/p&gt;

&lt;p&gt;Then rename your Heroku remote to "production" (&lt;code&gt;deploy.sh&lt;/code&gt; will only make backups of your database for remotes named "production" -- if you don't want to rename it, just edit the script).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git remote rename heroku production&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You'll also want to configure the backup addon for your Postgres database:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku addons:add pgbackups:auto-month&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can take it for a spin.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./deploy.sh&amp;#x000A;Usage: [BRANCH=master] deploy.sh &amp;lt;remote&amp;gt; [no-migrations]&amp;#x000A;&amp;#x000A;        remote         Name of git remote for Heroku app&amp;#x000A;        no-migrations  Deploy without running migrations&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You have to specify the name of the remote (list your remotes with &lt;code&gt;git remote&lt;/code&gt;). The &lt;code&gt;no-migrations&lt;/code&gt; switch is optional; &lt;code&gt;deploy.sh&lt;/code&gt; will always put the app into maintenance mode and run migrations if you don't ask it not to.&lt;/p&gt;

&lt;p&gt;That's about it. Almost. I added a &lt;code&gt;git log&lt;/code&gt; command to show you which commits you're about to deploy...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./deploy.sh production&amp;#x000A;From heroku.com:theagileplanner&amp;#x000A;   c1ded52..63985ee  master     -&amp;gt; production/master&amp;#x000A;Undeployed commits:&amp;#x000A;&amp;#x000A;783e73d | 4 hours ago: Updated deploy.sh to latest heroku-deploy. (Graham Ashton)&amp;#x000A;8402bba | 81 minutes ago: Added cookieoi.eu JS to page. (Graham Ashton)&amp;#x000A;&amp;#x000A;Press enter to continue...&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Press Ctrl-C to abort deployment.&lt;/p&gt;

&lt;p&gt;:-)&lt;/p&gt;</content>
    <published>2012-06-25T09:00:00+00:00</published>
    <updated>2012-06-25T09:00:00+00:00</updated>
    <category term="automation" />
    <category term="ruby-on-rails" />
  <feedburner:origLink>http://effectif.com/ruby-on-rails/heroku-deploy</feedburner:origLink></entry>
  <entry>
    <title>Fun with Syck and Psych on Heroku</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/Rnx7pU8MoEk/syck-and-psych-yaml-parsers-on-heroku" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-06-15:/ruby-on-rails/syck-and-psych-yaml-parsers-on-heroku</id>
    <content type="html">&lt;p&gt;This is one of those posts that's inspired by a desire never to have to investigate the same bug again.&lt;/p&gt;

&lt;p&gt;I just deployed an app to Heroku that needs to read its data from a local YAML file in order to function. It runs fine on my Mac, but fails with this message on Heroku:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActionView::Template::Error (undefined method `downcase' for #&amp;lt;Syck::PrivateType:0x000000043df398&amp;gt;)&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ouch. I was supposed to be calling &lt;code&gt;downcase&lt;/code&gt; on a string. The YAML file on Heroku is identical to the one that I'm using on my Mac, so what's going on?&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="http://lost-in-code.blogspot.co.uk/2011/10/yaml-in-ruby-19.html"&gt;Alessandro Di Maria&lt;/a&gt;, I spotted that Heroku's Cedar stack is still using Sych to parse YAML, rather than the newer Psych. You can investigate what you're running like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rails console&amp;#x000A;Loading development environment (Rails 3.2.5)&amp;#x000A;irb(main):001:0&amp;gt; YAML::ENGINE::yamler&amp;#x000A;=&amp;gt; "psych"&amp;#x000A;&amp;#x000A;$ heroku run console&amp;#x000A;Connecting to database specified by DATABASE_URL&amp;#x000A;Loading production environment (Rails 3.2.5)&amp;#x000A;irb(main):001:0&amp;gt; YAML::ENGINE::yamler&amp;#x000A;=&amp;gt; "syck"&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Feck. Rails 3 will use Psych by default if it can find it. Psych will be enabled automatically if you compile Ruby with &lt;code&gt;libyaml&lt;/code&gt; installed, but (luckily) you can also add &lt;code&gt;psych&lt;/code&gt; to your &lt;code&gt;Gemfile&lt;/code&gt; to force it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo "gem 'psych' &amp;gt;&amp;gt; Gemfile" &amp;amp;&amp;amp; bundle&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Problem solved. Cheers Alessandro!&lt;/p&gt;</content>
    <published>2012-06-15T00:00:00+00:00</published>
    <updated>2012-06-15T00:00:00+00:00</updated>
    <category term="ruby-on-rails" />
  <feedburner:origLink>http://effectif.com/ruby-on-rails/syck-and-psych-yaml-parsers-on-heroku</feedburner:origLink></entry>
  <entry>
    <title>Write a quick draft while it's fresh</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/DFxWm0jy5Xo/blog-on-your-mobile" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-05-15:/writing-tips/blog-on-your-mobile</id>
    <content type="html">&lt;p&gt;As a bootstrapper, it's important that I spend enough time getting my
product's name out there. For me, that means blogging. I've recently
been writing a couple of paragraphs the instant that I have an idea for
a post. That usually means writing "on your mobile" (or in my case, on
my iPod).&lt;/p&gt;

&lt;p&gt;I used to capture a one line summary of an idea in my todo list, with a
view to writing the post up later. By the time I'd get around to it I'd
often struggle to recover my thoughts and the inspiration would be long
gone.&lt;/p&gt;

&lt;p&gt;In the last week I've written several 200 word drafts on my iPod.
They've since been edited into blog posts that I'm rather pleased with.
If you have an iOS device the iA Writer app (iPhone/iPod/iPad) is great.&lt;/p&gt;

&lt;p&gt;&lt;img src="/attachments/ia-writer-for-iphone.png" class="screenshot"&gt;&lt;/p&gt;

&lt;p&gt;In this screenshot of the iPhone version you can see iA Writer's
extended keyboard, with extra buttons for common punctuation marks, and
cursor keys for navigating left and right in your copy. The iPad version
(not shown) also has keys for jumping whole words at the time, which is
a significant improvement over the default iPad keyboard.&lt;/p&gt;

&lt;p&gt;I seem to write better with iOS than I do with a laptop, presumably
because I can't type as fast and that gives me a bit more space to
think. Maybe it's that, or maybe it's just because I'm using something a
bit different.&lt;/p&gt;

&lt;p&gt;Either way, iA Writer on your phone, sync'd with Dropbox is a great way
to write the draft. I edit later on the computer, then post it.&lt;/p&gt;

&lt;p&gt;Sent from my iPod&lt;/p&gt;</content>
    <published>2012-05-15T09:00:00+01:00</published>
    <updated>2012-05-15T09:00:00+01:00</updated>
    <category term="productivity" />
    <category term="writing-tips" />
  <feedburner:origLink>http://effectif.com/writing-tips/blog-on-your-mobile</feedburner:origLink></entry>
  <entry>
    <title>Securing Instiki with an SSH tunnel</title>
    <link href="http://feedproxy.google.com/~r/effectif-development/~3/RgzM7iA793s/securing-instiki-with-an-ssh-tunnel" rel="alternate" type="text/html" />
    <id>tag:effectif.com,2012-04-26:/system-administration/securing-instiki-with-an-ssh-tunnel</id>
    <content type="html">&lt;p&gt;I've been using a wiki a lot recently to keep track of my research. A wiki is the perfect tool for keeping track of all my notes, and the relationships between my ideas.&lt;/p&gt;

&lt;p&gt;I've been using &lt;a href="http://www.instiki.org"&gt;Instiki&lt;/a&gt;; the UI is clean and is built with familiar technology (it's written in Rails, and its early code was the app from which DHH extracted the Rails framework). As wikis go it takes a fairly low maintenance approach, and lets you concentrate on your content.&lt;/p&gt;

&lt;p&gt;Being a Rails app, you can run it with a standard Ruby web server such as Webrick. I started out running it locally on my desktop. When I started working more on my laptop I needed access to the wiki there too, so I moved the app's folder into Dropbox and synchronised the database that way (it uses a local SQLite database). That worked fine until I accidentally started it on both machines at once, and I lost a page of data.&lt;/p&gt;

&lt;p&gt;Clearly, I was going to have to host it properly.&lt;/p&gt;

&lt;p&gt;There is a fork of Instiki that &lt;a href="https://github.com/lazzarello/instiki-heroku"&gt;runs on Heroku&lt;/a&gt;. I'm sure it's awesome, but I'm often reluctant to use forks of apps that don't see a lot of use. You've no idea how long the fork will be maintained, and I don't fancy rolling my sleeves up when Heroku deprecate the stack that the port runs on.&lt;/p&gt;

&lt;p&gt;So I decided to host it on my VPS. In theory all I'd need to do is to &lt;code&gt;tar&lt;/code&gt; up my local instiki folder, copy it over to my server and untar it. After a quick &lt;code&gt;bundle install&lt;/code&gt; I should be good to go, and indeed, I was.&lt;/p&gt;

&lt;p&gt;I knocked up a quick init script to start/stop the app on bootup/shutdown, and all was well.&lt;/p&gt;

&lt;p&gt;Instiki was running unprotected on port 2500. All was not well.&lt;/p&gt;

&lt;h2&gt;So, what about security?&lt;/h2&gt;

&lt;p&gt;You really don't want a private wiki listening on an open port. Not only is your data unprotected, but somebody might find a vulnerability in the wiki software and login to your server.&lt;/p&gt;

&lt;p&gt;I had planned to filter port 2500 on my firewall, and configure Nginx to act as a proxy on port 80. This wouldn't prevent an attacker from accessing the wiki's home page, but I could secure it in Nginx with HTTP basic auth running over an SSL connection.&lt;/p&gt;

&lt;p&gt;How conventional. And what a faff!&lt;/p&gt;

&lt;p&gt;Instead, I've firewalled port 2500 on my server and connect to Instiki over an encrypted SSH connection. Better yet, it guarantees that only I can get at it, as only I can connect to my server with ssh!&lt;/p&gt;

&lt;p&gt;So now I access Instiki in the browser by connecting to &lt;code&gt;http://localhost:2500&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've put the ssh command that sets this up in a script, and run it whenever I want access to the wiki. At some point I'll probably run it automatically whenever I start my laptop, but for now I'm happy with running it when I need it.&lt;/p&gt;

&lt;p&gt;Here's the script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cat bin/instiki-tunnel&amp;#x000A;#!/bin/sh&amp;#x000A;&amp;#x000A;ssh -f my.server.com -L localhost:2500:my.server.com:2500 -N&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is what the ssh options are for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; – run in the background just before launching the command.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-L&lt;/code&gt; – forwards all connections to &lt;code&gt;localhost&lt;/code&gt; on port 2500 to port 2500 on &lt;code&gt;my.server.com&lt;/code&gt;, via an encrypted, authenticated SSH tunnel.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-N&lt;/code&gt; – prevents an actual command from being run on the server.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You've got to love SSH.&lt;/p&gt;</content>
    <published>2012-04-26T00:00:00+00:00</published>
    <updated>2012-04-26T00:00:00+00:00</updated>
    <category term="system-administration" />
  <feedburner:origLink>http://effectif.com/system-administration/securing-instiki-with-an-ssh-tunnel</feedburner:origLink></entry>
</feed>
