[Linux][Mastodon] カスタマイズしたMastodonインスタンスをバージョンアップする

カスタマイズしたMastodonインスタンスのバージョンアップは容易ではない

Mastodonインスタンスのバージョンアップ、純正品から一切のソースを弄ってない場合(通称「バニラ」と言われるみたい)は比較的手順は簡単で、参考情報として「さくらインターネットさんの情報」が役に立ちます。が、以下のようなカスタマイズを施している場合、そうは行かなくなります。

  • ログイン画面の象さんロゴを変更した
  • v2.0.0から登場したテーマ選択機能を実装し、カスタマイズテーマを適用した
  • 過去投稿した「アカウント削除時の影響を緩和する手法」の様に、master適用外となったパッチを適用した

この時、単純にバージョンをあげようとすると以下のようなエラーが出ます。

$ git checkout v2.1.0rc3
error: Your local changes to the following files would be overwritten by checkout:
 config/locales/en.yml
 config/locales/ja.yml
Please, commit your changes or stash them before you can switch branches.
Aborting

$ git merge v2.1.0rc3
error: Your local changes to the following files would be overwritten by merge:
 config/locales/en.yml
 config/locales/ja.yml
Please, commit your changes or stash them before you can merge.
Aborting

こんな風に、checkoutしようとしても、mergeしようとしてもカスタマイズしようとした箇所が競合し、適用ができませんで、どうしたもんかと悩みました。

対処方法

で、調べた所、あすりあさんの「初心者向けマストドン改造メモ」と言う情報が非常に役立ちました。コレを元に、以下方針で対処を行いました。

  • github上にアカウントを作成する
  • 本家のリポジトリから分岐して作成した自分用のリポジトリを使うようにする
  • 以降、バージョンアップが必要となった場合は、本家リポジトリからmergeし、必要に応じてソースの修正を実施する

内容的には、先述した改造メモ記載の3項と4項の手順を組み合わせた形になりますね。

大前提:githubアカウントの作成

細かく書くのは流石に割愛するんですが、githubアカウントを作成します。サインアップすると、確認メールが届きますので、メール内のリンクをクリックし、サインアップを完了させてください。

サインアップが完了しないと、本家リポジトリからのforkができません。

リポジトリからforkすると、forkしたリポジトリのURLは

https://github.com/<登録したユーザ名>/mastodon

となります。

リポジトリの切り替え

まず、

$ git remote add bluecore-stg https://github.com/localyouser/mastodon.git

次に、

$ git branch MastodonBluecore

ブランチの確認をします。現状本家リポジトリになっていると思います。

$ git branch
* (detached from v2.0.0)
 MastodonBluecore
 master

作成したブランチにチェックアウトし、ブランチを切り替えます。

$ git checkout MastodonBluecore
M config/locales/en.yml
M config/locales/ja.yml
M config/themes.yml
Switched to branch 'MastodonBluecore'

結果をgit branchで確認します。

$ git branch
* MastodonBluecore
 master

カスタマイズされたローカルデータのcommit

カスタマイズされたローカルデータを正とすべく、commit処理を実行しました。

$ git commit -am 'base-v2.0.0'
[MastodonBluecore a00be2e] base-v2.0.0
 3 files changed, 4 insertions(+)

本家リポジトリのバージョン追従

本家リポジトリからの情報をmergeし、バージョン追従を行います。が、そんなに事は単純ではなかったです。ある程度はmergeが効くようなのですが、今回一部処理のmergeに失敗しました。

$ git fetch --tags origin

$ git merge v2.1.0rc3 -m "Merge Commit for v2.0.1rc3"
Auto-merging spec/models/home_feed_spec.rb
Auto-merging config/locales/ja.yml
CONFLICT (content): Merge conflict in config/locales/ja.yml
Auto-merging config/locales/en.yml
Removing config/initializers/rabl_init.rb
Removing app/views/well_known/webfinger/show.json.rabl
Auto-merging app/services/suspend_account_service.rb
CONFLICT (content): Merge conflict in app/services/suspend_account_service.rb
Auto-merging app/services/batched_remove_status_service.rb
Automatic merge failed; fix conflicts and then commit the result.

ざっと見る限りこんな感じのようです。

  • config/locales/ja.ymlの競合:テーマ機能を使用したことによる影響
    • Automergeを実行され、解決しているようです。
  • config/locales/en.ymlの競合:ja.ymlと同様の影響によるものでした
    • Automergeが実行され、解決しているようです。
  • app/services/suspend_account_service.rbの競合:アカウント削除処理のカスタマイズによる影響によるものです。
    • Automergeしきれずに失敗となっています。

Automergeしきれなかった箇所の手動マージ作業

Automergeしきれなかった所については、その対象コードの中で差分について以下のように表現されます。

<<<<<<< HEAD ★
 def purge_content
 @account.statuses.reorder(nil).find_in_batches(batch_size: 100).with_index(1) do |statuses, batch_index|
 BatchedRemoveStatusService.new.call(statuses, batch_index)
======= ★
 def purge_content!
 @account.statuses.reorder(nil).find_in_batches do |statuses|
 BatchedRemoveStatusService.new.call(statuses)
>>>>>>> v2.1.0rc3 ★

★マークの有るところが境目になっています。HEADとなっているところがローカルデータによるもの、=記号を挟んでその下がv2.1.0rc3のオリジナルのものになります。今回、ユーザ削除の処理体系についてはローカルデータの処理を継続させたい(というか、元の処理が変更されていないことが確認されたので、カスタマイズした処理を踏襲しても問題ないと判断した)ため、それ以外の箇所を削除するという対応を取りました。もちろん、処理体系が完全に異なる場合は、純正のコードを採択すべきと考えます。

対象箇所は以下のような感じにします。

 def purge_content
 @account.statuses.reorder(nil).find_in_batches(batch_size: 100).with_index(1) do |statuses, batch_index|
 BatchedRemoveStatusService.new.call(statuses, batch_index)

新規追加ファイルへの対応

また、カスタムテーマを有効にしたり、ログイン画面のロゴ変更を行ったため、app/javascript/styles/custom.scssファイルを追加しています。こうした追加ファイルはまだgitの管理下に置かれていないため、git addを使用してgitの管理下に置く必要があるようです。今回のケースでは、以下の通りカスタムテーマやロゴの画像ファイルをgit管理下に置きます。

$ git add app/javascript/styles/custom.scss
$ git add app/javascript/images/social.bluecore.net_img.jpg

ローカルデータのcommit

ローカルデータをcommitし、正式なデータとして確定させます。

$ git commit -am '<コミット内容など、コメント>'

後はビルドするなど

後はコードをビルドするなどしてください。その上で、正しく動作するソースかどうかを確認します。

$ gem install bundler
$ bundle install --deployment --without development test
$ yarn install
$ RAILS_ENV=production bundle exec rails db:migrate
$ RAILS_ENV=production bundle exec rails assets:precompile

なお、手動mergeが完了してない状態だと、最後のassets:precompileで失敗します。こうして修正漏れを防ぐことが出来るのかなと思います。

 githubにコードをアップする

リポジトリへコードをpushします。git pushコマンドを使用し、引数にはリポジトリ切替時に指定したサーバ識別子と、ブランチ名を指定します。この時、githubのアカウント名とパスワードを求められるので入力してEnterキーを押下します。

$ git push bluecore-stg MastodonBluecore
Username for 'https://github.com': localyouser ←github上のアカウント名を入力
Password for 'https://localyouser@github.com': ←github上のパスワードを入力
Counting objects: 22, done.
Delta compression using up to 2 threads.
Writing objects: 100% (10/10), 959 bytes | 0 bytes/s, done.
Total 10 (delta 8), reused 0 (delta 0)
remote: Resolving deltas: 100% (8/8), completed with 7 local objects.
To https://github.com/localyouser/mastodon.git
 4c20938..a94ac08 MastodonBluecore -> MastodonBluecore

他のインスタンスに自分のリポジトリ切り替え・適用をする場合

例えば私の環境の場合、本番インスタンスとステージングインスタンスが存在しており、ステージングインスタンスで修正したソースを本番インスタンスに適用する場合など、リポジトリの切り替えやソースの取り込みなどをすることで、「まずはステージングでバージョンアップ、問題なければ本番へ適用」みたいな真似ができるわけでして。

本記事の場合、何をトチ狂ったのか、「まず本番⇒続いてステージング」って感じで適用したので、サーバ識別子が「!?」てな感じになってますが、気にしないでください。

rc版のアップデートを繰り返す中で、何とか手順が整理できました。

リポジトリの切り替え

$ git remote add bluecore-promo https://github.com/localyouser/mastodon.git

切り替えたリポジトリからソースをpull

$ git pull bluecore-stg MastodonBluecore

ブランチ切り替え(初回だけ)

$ git branch MastodonBluecore

切り替えたブランチでチェックアウト(初回だけ)

$ git checkout MastodonBluecore

後は、いつものようにビルドすれば良いみたいです。

Gitって難しいっす

今回の記事、結構トライ&エラーを繰り返して対応したため、順序等誤りがあるかもしれません。そこは私用の備忘録として作ったものなんで、あくまで参考程度に見といてください。許して下さいませ。私自身、旧時代的な手作業管理(一部Subversion使うぐらい)の経験しかない・・という・・・

今や開発現場とかではgithubを使うのが当たり前ーぐらいの勢いになってるんですが、私自身こうした技術に関しては全く疎くかなーりハズい思いをしながらやりこんでました。いやぁ、この年になってそういうことも知らんのかと言われそうで情けなや(´Д`)ハァ…

でも、やっぱりこういうシチュエーションがないと、githubって使わないし、今回コレを通じて多くの学びがありました。やっぱり、かけらで良いので、少しでも知識があると、お客さんだったりインフラ外の部隊だったりに話を通しやすくなるので、それを踏まえて考えると良い機会だったように思います。

まだまだgitは理解できてない部分が多いので、継続して勉強していきたいと思います。