using many Heroku accounts, or pushing under many GitHub accounts
General,Opus,Projects
It all starts with SSH. First of all make sure that for each account, you have its respective identity file at hand, preferably stored under ~/.ssh. Most code in this article derives from Aeonscope and this is an empirical reincantation of the article.
Overloading SSH: swizzling between accounts while pushing to Heroku using Git
Since it goes this way:
$ git push heroku master
and git push authenticates over SSH, who you are is determined by the key that your SSH agent sends abroad. To have git work with your desired credential, first create separate remote endpoints for each Heroku account that you plan to use, then edit ./ssh/config so that they are recognized by the SSH agent.
Creating separate git remote endpoints
Go to your repository, and edit .git/config. Create many remote endpoints. I’ll use one reposiroty of ours that recently got updated for example.
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git@github.com:iridia/redmine-heroku.git
…
[remote "heroku"]
url = git@heroku.com:keeper.git
fetch = +refs/heads/*:refs/remotes/heroku/*
[remote "heroku_base_iridia"]
url = git@base.iridia.tw.heroku.com:keeper.git
fetch = +refs/heads/*:refs/remotes/heroku/*
[remote "heroku_ev_iridia"]
url = git@ev.iridia.tw.heroku.com:keeper.git
fetch = +refs/heads/*:refs/remotes/heroku/*
Notice that the last 2 remotes have peculiar url configuration. In this case, we embed the respective Heroku account that we would like the push to be effective under into the host name. In that sense pushing to heroku_base_iridia would result in the credentials associated with base@iridia.tw to be used, and pushing to heroku_ev_iridia would show up as if ev@iridia.tw pushed it. The heroku endpoint which is associated with heroku.com was created by Heroku itself.
Creating separate host entries within .ssh/config
Now edit ~/.ssh/config and again we’ll have a working example.
Host ev.iridia.tw.heroku.com
HostName heroku.com
User git
IdentityFile ~/.ssh/ev@iridia.tw.identity
IdentitiesOnly yes
Host base.iridia.tw.heroku.com
HostName heroku.com
User git
IdentityFile ~/.ssh/iridia_id_rsa
IdentitiesOnly yes
Notice that for each pseudo-host, a real HostName is provided, and an IdentityFile is also provided. This tells the SSH agent that once we attempt to SSH to a listed Host, substitute that host with its real HostName, and authenticate using the IdentityFile associated with the host. Since Git usually pushes over SSH, combining this part with the former part allows an user to push to Heroku using any of her many Heroku accounts.
However, you’ll have to add the correct keys to their respective Heroku accounts, either from its administration interface, or from the command line after following the part that follows.
Overloading ~/.heroku/credentials: managing Heroku apps under many accounts
Since pushing is not where all the development happens, we’ll have to make Heroku’s gem ($ sudo gem install heroku) work with multiple accounts. (Un)fortunately, Heroku stores credentials in plain text under ~/.heroku/credentials, so swizzling it makes the gem work with multiple accounts. Check out hero.rb on GitHub.
For example, to add many keys to their respective Heroku accounts (assuming that you have got hero.rb and all the keys):
$ hero ev@iridia.tw
$ heroku keys:add ~/.ssh/ev_iridia_tw.identity.pub
$ hero base@iridia.tw
$ heroku keys:add ~/.ssh/base_iridia_tw.identity.pub
That’s it.