RubyKaigi2020 用に準備してた資料の供養として発表させていただきました。
僕が知ってるCIの知見や2020年時点でのCIのトレンドはだいたい詰め込めたと思っています。
RubyKaigi2020 用に準備してた資料の供養として発表させていただきました。
僕が知ってるCIの知見や2020年時点でのCIのトレンドはだいたい詰め込めたと思っています。
condo3 で app.yaml
内に Cloud KMS で暗号化した秘匿値を埋め込みやすくするために作ったモジュールをライブラリ化しました。
とはいえGoogle App Engine専用というわけではなく、GCP + GoであればCloud Functionsとかでも使えるはずです。
READMEからかいつまんで説明すると下記
gcloud kms encrypt
で暗号化してBASE64に変換KMS_ACCESS_TOKEN
のように KMS_
を先頭に付けた環境変数として登録
GetFromEnvOrKms
で呼び出す
KMS_
は不要本番環境ではKMSで暗号化された値を使いたいけどローカルでは暗号化していないプレーンな値を環境変数で渡したいことがよくあるので、暗号化していないプレーンな環境変数とKMSで暗号化した環境変数を透過的に扱えるようにしています。( os.Getenv
と似たようなインターフェースにしたのも同じ理由)
以前社内に書いたポエムなんだけど年に1回くらい引用したくなるので公開した
テンプレ
【質問内容】 【やりたいこと or 今困ってること or 質問の意図】
って感じに、質問をする動機としてまず やりたいことありき のはずなので、それを提示すべきです
質問される側(以下回答者)は質問内容がふわっとしていると色々なケースを想定して回答を組み立てます *1
例「Aの場合は~だけど、Bの場合は~」
こういう場合回答者は質問者のやりたいことを想像しながらいろんな場合分けをする必要があるので、頭を使うので疲れるし、回答を組み立てるのに時間もかかります。
酷い場合だと5つくらい場合分けして回答したことがあります。
こういう時、僕は自分の中で 超能力で回答 という言葉を使ってます。(自分以外で使ってる人は見たことないので同意は得られないことは覚悟してます)
超能力を発揮するのは疲れます。
僕も色々質問を受ける立場ですがゴールが明示されてた方が圧倒的に回答しやすいです。
初心者によくありがちなのですが、やりたいことに対して質問内容が的外れということが往々にしてあります。
はっきり言ってこういうのは時間の無駄なので先にやりたいことを明示してもらえれば
って感じで時間のロスを防げます
質問する側は質問内容に関して長時間思考してるのでコンテキストを理解しています。
しかし回答者はそうとは限らないので可能な限り詳しく書くべきです。
実行したコマンドと実行結果を全て書くくらいが丁度いいと思ってます。
質問内容や人によってはヒアリングしながらコンテキストを少しずつ理解するというのもありそうですが、僕は圧倒的に最初にコンテキストを詳しく書くしそういう風に質問された方が嬉しいです。
チャットとかだと横で見た人が回答しやすいってのもあります。
あと質問内容をまとめる段階で頭の中で問題が整理されるので、質問するために文章を書いてたら答えが分かるという副産物もあります。
これはどっかのOSSのissueテンプレートで見たことあるやつ。
質問内容によっては「こういうことをやっててこういう結果になってほしいんだが全然違う結果になるんだが理由がよく分からん」ってことがあると思います。
そういう場合には期待してた結果と実際の結果を書くと質問文も組み立てやすいし、回答者も回答しやすいです
ブコメレス
“こういう場合回答者は質問者のやりたいことを想像しながらいろんな場合分けをする必要がある” それならそこで聞き返せばいいんでないの?そういうことができない状況を想定しているのだろうか?
すぐ後に
質問内容や人によってはヒアリングしながらコンテキストを少しずつ理解するというのもありそうですが、僕は圧倒的に最初にコンテキストを詳しく書くしそういう風に質問された方が嬉しいです。
って書いているように好みの問題だと思います。
チャットだと非同期でのやりとりになってすぐに返信が返ってくる(返せる)とは限らないという理由で、僕は最初にまとまって書かれている方が嬉しいです。
このブログ主は自分視点で考えてるが、相手視点で考えると全く違った発想になる。この本がためになるはず。"「良い質問」をする技術" 是非読んでみて。
Kindle版ポチりました!
ブコメレス
ググれカス、一人で生きていけるようになれ、とか、そんなこと聞くな、とか言われ続けた結果なのかな。 人から与えられた経験とか。交渉とか。
「質問する時はちゃんと準備することでお互いに円滑にコミュニケーションが進むよ」っていうのがこのエントリの主題です。そんなことは一言も言っていないしそんな経験もしたこともないです。
根拠もなく勝手な想像をするのはやめてください。
rubocop-itamae (0.1.3): Code style checking for itamae recipes https://t.co/CkdL2YXE3g
— rubygems_news (@RubygemsN) 2020年7月12日
https://github.com/sue445/rubocop-itamae/blob/master/CHANGELOG.md#v013
rubocop 0.87.0で v1 Upgrade Notes が出ていたので自分のcopでもv1形式のシンタックスに追従。
rubocopのカスタムcopを作ってる人はv1 Upgrade Notesを読んで対応しといた方がよさそう。
rubocop_auto_corrector (0.4.1): Run `rubocop --auto-correct && git commit` with each cop. https://t.co/9EOblqZOLO
— rubygems_news (@RubygemsN) 2020年7月10日
https://github.com/sue445/rubocop_auto_corrector/blob/master/CHANGELOG.md#v041
同じくrubocop 0.87.0関係の対応。
v1 Upgrade Notesだとカスタムcopでautocorrectを実装する時に autocorrect
メソッドを実装するのではなく AutoCorrector
moduleを extend
するようになるのですが *1、そういうcop*2がいる場合にWeekly buildがコケてたので対応。
rubocop_auto_corrector (0.4.0): Run `rubocop --auto-correct && git commit` with each cop. https://t.co/9EOblqIdUg
— rubygems_news (@RubygemsN) 2020年7月7日
rubocop v0.87.0で --auto-correct
の挙動が変わったのと、 --auto-correct-all
が追加されたので追従。( rubocop_auto_corrector --all
で各cop単位で --auto-correct-all
する)
https://github.com/sue445/rubocop_auto_corrector/blob/master/CHANGELOG.md#v040
詳しいこと
GitLabでPostgreSQLを使う時にPgBouncer経由でDBに接続してる(database.ymlにpgbouncerの接続先を書いている)のですが、 その状態で rake db:migrate
すると下記のようなエラーが出ます。
ActiveRecord::ConcurrentMigrationError: Failed to release advisory lock from active_record/migration.rb:1385:in `with_advisory_lock' from active_record/migration.rb:1229:in `migrate' from active_record/migration.rb:1061:in `up' from active_record/migration.rb:1036:in `migrate' from active_record/tasks/database_tasks.rb:238:in `migrate' from active_record/railties/databases.rake:86:in `block (3 levels) in <top (required)>' from active_record/railties/databases.rake:84:in `each' from active_record/railties/databases.rake:84:in `block (2 levels) in <top (required)>' from rake/task.rb:273:in `block in execute' from rake/task.rb:273:in `each' from rake/task.rb:273:in `execute' from rake/task.rb:214:in `block in invoke_with_call_chain' from monitor.rb:235:in `mon_synchronize' from rake/task.rb:194:in `invoke_with_call_chain' from rake/task.rb:183:in `invoke' from rake/application.rb:160:in `invoke_task' from rake/application.rb:116:in `block (2 levels) in top_level' from rake/application.rb:116:in `each' from rake/application.rb:116:in `block in top_level' from rake/application.rb:125:in `run_with_threads' from rake/application.rb:110:in `top_level' from rake/application.rb:83:in `block in run' from rake/application.rb:186:in `standard_exception_handling' from rake/application.rb:80:in `run' from bundle/ruby/2.6.0/gems/rake-12.3.3/exe/rake:27:in `<top (required)>' from bundle/ruby/2.6.0/bin/rake:23:in `load' from bundle/ruby/2.6.0/bin/rake:23:in `<main>'
https://docs.gitlab.com/omnibus/update/README.html に
If you’re using PgBouncer:
You’ll need to bypass PgBouncer and connect directly to the database master before running migrations.
とあるように db:migrate
する時だけPgBouncerを使わず直接PostgreSQLにつなぐのが大正解です。
しかし
という理由で、今のデプロイフローをなるべく変えずにどうにかdb:migrateの時だけ自動で接続先を切り替える方法がないか考えました。
モンキーパッチを作るにあたって下記のような縛りプレイの条件がありました
このようなモンキーパッチを
version: '3.7' services: gitlab: volumes: - "./monkey_patch/db_migrate_monkey_patch.rake:/home/git/gitlab/lib/tasks/db_migrate_monkey_patch.rake:ro"
のような感じでDockerコンテナ内にmountして使っています。
rake db:migrate
実行中にpumaやunicornをrestartすると意図しない設定が読み込まれるので注意してくださいrake taskの実体は Rake::Task
のインスタンスで、rake task実行時には Rake::Task#invoke
が呼ばれます。
そのため Rake::Task["db:migrate"].invoke
という特異メソッドに対してモンキーパッチ用のmoduleを prepend
することで rake db:migrate
実行時のみに特定の処理を差し込んでいます。
Rake::Task["db:migrate"].enhance(["db:migrate:before"]) do Rake::Task["db:migrate:after"].invoke end
みたいな感じで db:migrate:before
でdatabase.ymlを書き換えて db:migrate:after
で元に戻すという方法もあったのですが、これだと db:migrate
でエラーになった時に db:migrate:after
が実行されずにdatabase.ymlが元に戻せなくなる不具合があるのでボツになりました。
そのため、上の方で書いているように Rake::Task["db:migrate"].invoke
に対してモンキーパッチをあてるしかないと思ってます。
begin Rake::Task["db:migrate"].enhance(["db:migrate:before"]) ensure # ロールバック処理 end
これだとrake taskの定義時に ensure
が評価されてrake taskの実行時には ensure
は評価されないので意図通りに動かないです。
島改装前のスクショがこれしか残ってなかった。改装直前は建物の他に橋や坂も結構設置してました
頑張って作った割には似てないorz
下のスクショはswitch版のDQ3のものです
動かせる建物は全部動かしたので2~3週間くらいかかってます
街の南西に自宅
北西にルイーダの酒場(博物館)
酒場なので仲間が待機してます
ちょい東に道具屋(タヌキ商店)
写真の左下が宿屋で右下が武具屋(仕立て屋)
橋を渡って池の中にあるのがお城(案内所)
どうでもいいですが島の名前がキュアスカーレッ島なので キュアスカーレット の旗です。
城下町の南西に井戸
城下町の北東に教会
教会なので賛美歌が流れてます
街を全部配置した時に住民の家が1件だけ余ってしまったので岬の洞窟の位置に置いてます
村の入口。主人公の上にあるのが道具屋
道具屋の隣の家と池
北東の家には馬がいます
村の南側の宿屋と武具屋
南東部の岩
いざないの洞窟の南の祠(キャンプサイト)
いざないの洞窟
これは完全に偶然なんですが今日ドラクエ1の誕生日でした。おめでとうございます!
34年前の今日、5月27日は『ドラゴンクエスト』の発売日でした! #DQ1 #ドラクエの日 pic.twitter.com/gHMdkJ0IRD
— ドラゴンクエスト宣伝担当 (@DQ_PR) 2020年5月26日
*1:これを言いたかっただけ