名もなき未知

エンジニアリングとか、日常とかそういうのをまとめる場所。

Herokuでサブディレクトリをデプロイできるらしいのでメモ

qrunchから移してない記事の移植その2

結構前の情報なので、最新情報出ないことは注意されたし。なお、現状もこれで正しいのかはちょっとわからんので、もっと良い方法があれば知りたいところ。

要約

ディレクトリ構成が

Repository
├── README.md
├── app(ここにRubyOnRailsのファイルが入ってる)
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── Rakefile
│ ├── app
...

git subtree push --prefix api/ heroku master

でよい。

https://codenote.net/heroku/3442.html を参照した。

https://stackoverflow.com/questions/7539382/how-can-i-deploy-push-only-a-subdirectory-of-my-git-repo-to-heroku/10648623#10648623 更にもとはここを参照してたらしい。

背景

なんかいまさらお前チュートリアルやってるのかよーってなってるけど、新しくアプリケーション作りたいって人がいるので、どういう作りなのかなーと思い、やっています。

それにしても環境構築周りは辛いですね。前回どうやって動かしたのか完全に忘れました。(どこかにメモがあるのかもしれない)

ところで、HerokuにデプロイするっていうのがRailsチュートリアルには存在しています。

https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_commands

ここで git push heroku master するもうまく動かないので、ちょっと原因を探っていました。

git push heroku master がうまくいかない理由

2つの原因があることがわかりました。

名前の登録し忘れ

このようなエラーが出る場合は、git remote の宛先がおかしい可能性が高い。

$ git push heroku master 
fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

heroku git:remote あぷり名 でアプリ名を登録してあげるとうまくゆく。

アプリ名は heroku create したときにURLとか、リポジトリ名に入っている名前になる。(Heroku上から変更することもできるらしいが、やっていない)

ディレクトリ構成の問題

ところで、このようなエラーが出る場合はディレクトリ構成の問題が考えられる。

$ git push heroku master 
Enumerating objects: 114, done.
Counting objects: 100% (114/114), done.
Delta compression using up to 4 threads
Compressing objects: 100% (98/98), done.
Writing objects: 100% (114/114), 26.45 KiB | 1.06 MiB/s, done.
Total 114 (delta 16), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote:  !     No default language could be detected for this app.
remote:             HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
remote:             See https://devcenter.heroku.com/articles/buildpacks
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to あぷり名.
remote: 
To https://git.heroku.com/あぷり名.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/あぷり名.git'

どうやらサブディレクトリに切っているとうまくいかないらしい。(ルートに設定ファイルがいろいろおいてある構成が想定されてるらしい)

これは次のコマンドでデプロイできる。

$ git subtree push --prefix デプロイしたいディレクトリ/ heroku master

※デプロイしたいディレクトリと、アプリ名は必ずしも一致しませんので要注意。

で、remote でうんたらかんたらし始めたら多分うまくデプロイされてるはず。

お疲れ様でした。

コマンドが覚えられないので

適当にコマンド実行用のコードを書いた。普段Ruby書いてない人のコードなので、微妙なのはご愛嬌で。

require 'optparse'
require 'json'

option = {}
OptionParser.new do |opt|
  opt.on('-d dirname', 'input deploy target dirname') {|v| option[:d] = v}
  opt.on('-f', 'force deplhy target dirname') {|v| option[:f] = v}

  opt.parse!(ARGV)
end

if option[:d]
  dir_name = option[:d]
  force_flag = option[:f]
  map_data = Hash.new
  File.open('map_data.json') do |j|
    map_data = JSON.load(j)
  end
  site_name = map_data[dir_name]
  if force_flag or site_name
    puts "try build #{dir_name}"
    result = `git subtree push --prefix #{dir_name}/ heroku master`
    if $? == 0
      puts site_name ? "show page: https://#{site_name}.herokuapp.com/" : "build success"
    else
      puts "Error, #{$?}"
    end
  else
    puts "Error: not found #{dir_name}"
  end
end

ruby build_cmd.rb -d hello_app みたいな感じでデプロイできるようにしてる。

map_data.json の中身はこんな感じ。

{
    "ディレクトリ名": "アプリ名"
}

追記(2018/12/26)

https://stackoverflow.com/questions/13756055/git-subtree-subtree-up-to-date-but-cant-push

これを見た感じデプロイスクリプトのここを変えるべき

-    result = `git subtree push --prefix #{dir_name}/ heroku master`
+    result = `git push heroku \`git subtree split --prefix #{dir_name} master\`:master --force`

気になること

別のブランチを強制的にpushするような作りもできるっぽいので、ちょっと気になってる。(これはグッドプラクティスなのかはわからない)

https://qiita.com/wroc/items/d15b1015c899b0cf77da