submoduleにGitHubのprivate repoがある場合、Herokuへのデプロイがさくっといくかと思ったらガツッとハマったので、メモとして残しておきます。
ちなみに、以下はRailsアプリでの例です(他のフレームワークでも応用が効くとは思いますが、効かないかもです)。基本的にはHerokuの公式ドキュメントを見ていただければ載っているので、それで事足りそうな方はそちらに飛んでください。
まず、ローカルで幸せに開発していたときは、githubにある他のrepoをsubmoduleとしてaddするときは以下の様なコマンドでやってました。ここでは、アプリフォルダの中のvendorの中にprivate repoなgemたちを突っ込んでいる感じです。
$ git submodule add git@github.com:keiko713/some_gem.git vendor/some_gem
この場合は、GitHubのSSHキーがローカルのマシンに登録してあれば、some_gemがprivate repoであろうがなかろうが、submoduleとしてvendor/some_gem以下に登録されます。GitHub上で見てもその部分はリンクになっていて、クリックするとそのrepoにジャンプできます。
ここでHerokuにアプリをデプロイしたい場合、もしaddしたsubmoduleがprivate repoでなければ、git push heroku masterの結果は次のようになり成功します(以下はdeviseをsubmoduleとしてaddした例)。
$ git submodule add git://github.com/plataformatec/devise.git vendor/devise
-----> Git submodules detected, installing Submodule 'vendor/devise' (git://github.com/plataformatec/devise.git) registered for path 'vendor/devise' Initialized empty Git repository in /tmp/build_1qsjqayd6a5g6/vendor/devise/.git/ Submodule path 'vendor/devise': checked out '7c8f636b98810c21c339df484258c0b1446c0d43'
しかし、これがprivate repoの場合、残念なことに次のようなエラーが出ます(以下はprivate repoであるsome_private_repoをaddした例)。
$ git submodule add git://github.com/keiko713/some_private_repo.git vendor/some_private_repo
-----> Git submodules detected, installing Submodule 'vendor/devise' (git://github.com/plataformatec/devise.git) registered for path 'vendor/devise' Submodule 'vendor/some_private_repo' (git@github.com:keiko713/some_private_repo.git) registered for path 'vendor/some_private_repo' Initialized empty Git repository in /tmp/build_3lbuhu9ljt94n/vendor/devise/.git/ Submodule path 'vendor/devise': checked out '7c8f636b98810c21c339df484258c0b1446c0d43' Initialized empty Git repository in /tmp/build_3lbuhu9ljt94n/vendor/some_private_repo/.git/ Host key verification failed. fatal: The remote end hung up unexpectedly Clone of 'git@github.com:keiko713/some_private_repo.git' into submodule path 'vendor/some_private_repo' failed ! Heroku push rejected, Submodule install failed
今回は、Resolving Application Dependencies with Git Submodulesのドキュメントの中にあるProtected Git submodulesを参考にしてみました。
まず、今追加してしまった分のsome_private_repoを削除します(参考: Stack Overflow)。
- .gitmodulesの中の該当submoduleの部分を削除
- .git/configの中の該当submoduleの部分を削除
- git rm –cached vendor/some_private_repo(後ろにスラッシュはつけない)
- コミットして、untrackedになっているvendor/some_private_repoフォルダを削除
次に、対象のprivate repoにアクセス可能なユーザー名とパスワードを付けて然るべき手順でsubmoduleをaddしていきます。
$ git submodule add https://username:password@github.com/keiko713/some_private_repo vendor/some_private_repo
-----> Git submodules detected, installing Submodule 'vendor/devise' (git://github.com/plataformatec/devise.git) registered for path 'vendor/devise' Submodule 'vendor/some_private_repo' (https://username:password@github.com/keiko713/some_private_repo) registered for path 'vendor/some_private_repo' Initialized empty Git repository in /tmp/build_3dbb0x2kdopen/vendor/devise/.git/ Submodule path 'vendor/devise': checked out '7c8f636b98810c21c339df484258c0b1446c0d43' Initialized empty Git repository in /tmp/build_3dbb0x2kdopen/vendor/some_private_repo/.git/ Submodule path 'vendor/some_private_repo': checked out '7c8f636b98810c21c339df484258c0b1446c0d43'
成功!ということでちょっとした変更で簡単に立ち上がりました。
ここで注意したいのが、この方法でデプロイをすると、.gitmodulesファイルにusernameとpasswordが残ってしまうという問題です。.gitmodulesはたいていrepoに上げていると思うので、public repoでこれをしてしまうとパスワード等がバレバレです。そもそもprivate repoなgemを使っている時点で、アプリ側のrepoもprivateであることが想像されるので、Herokuデプロイ用のユーザーなどを作ればいいかもしれませんが、セキュリティ的に許容しがたい場合は他の方法を探ってください。
Herokuのドキュメントの中には他にVendoringとPrivate dependency repositoriesの方法が載っていましたが、前者は試行錯誤の上残念ながらうまく行かず、後者は試していません。他にもStack OverflowにGemfile中でやりくりする方法(ENVを使ってusername/passwordを設定するのでよさげだった)やここを参考に生成したOAuth tokenを使ってやる方法も載ったりしていましたが、なんだかうまく行かず、結局上記の方法が一番シンプルでサクッと出来ました。
もっといい方法が見つかったらまた追記したいと思います。(その前にHerokuじゃないところにデプロイすることになりそうだけど…)
ではでは
Leave a Reply