GitLab CIを触って暫くたったので雑な感想

いろいろどっかにGitlabCIについての知見をまとめてたはずなんだけど、なくしてしまったので書くのに時間がかかってしまった。

とりあえずどんな感じなのか雑に眺めたい方もいることなので、雑にまとめた。

Gitlab CI 3行まとめ

  • Gitlab CIはGitLabで使える。CircleCIみたいなもん。最初にちょっとセットアップすれば、Jenkinsより簡単・便利。カバレッジとか成功時にデプロイとか出来る。
  • GitLab RunnerというCIで使うコンテナを動かすサーバーの構築が必要になるが、必要な作業は大体これだけ。あとはアプリケーション側で設定する。
  • GitLab使ってたら使っていいと思う(特にアンチJenkins)

GitLab CIについて

  • Ruby + Go, Dockerを使っている
  • 8.2位からGitLabの機能に統合された。
  • .gitlab-ci.ymlにcircle.ymlっぽいDSLを書いていく
  • Push/MergeRequestをきっかけにCIが勝手に走る。
  • 後述する、GitLab Runnerの構築が必要になる。

GitLab CIで Railsプロジェクトをテストするまで

GitLab Runnerの構築

GitLab RunnerはCircle CIやTravis CIでいうところのコンテナを動かすサーバみたいなもん。 GitLabと連携して使う。

今回は、GitLabとは別のVPSサーバにRunnerを構築するという構造を想定している。

ほとんど手順に書いてあるまんま作業した。 gitlab.com

気をつけないといけないのはGitLabとGitLab Mulit Runnerの紐付け位なので、ここの解説だけしておく。

sudo gitlab-ci-multi-runner register

# Runnerを使用したいGitLabのURL + /ci を入力する。
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci ) 
https://gitlab.example.com/ci

# https://gitlab.example.com/admin/runners にRunnerに対して入力するTokenが存在するのでそれを入力
Please enter the gitlab-ci token for this runner 
xxx

# Runnerの説明を入力する。
Please enter the gitlab-ci description for this runner 
my-runner

INFO[0034] fcf5c619 Registering runner... succeeded
Please enter the executor: shell, docker, docker-ssh, ssh? # 実行方式を選択する
docker

# デフォルトで使用するDocker Imageを入力する
Please enter the Docker image (eg. ruby:2.1):
ruby:2.1

これでGitLab Runnerの設定は完了。 GitLabのAdminAreaにさっき構築したRunnerが表示されてればOK。 今回は説明は割愛するけど、リポジトリ専用で使用するRunnerを作成したりということも可能。

これは別のサーバにRunnerを構築するときの手順だけど、GitLabが入っているサーバにRunnerを構築することも可能だと思う。

並列実行とかについてはよくわからない。

GitLab CI Multi Runnerの設定は /etc/gitlab-runner/config.toml にはいってるので、なにか変更したいときは覗いてみよう。

Railsアプリケーション側の設定

構成としては自分が身近に使っている Rails(4.2.4) + mysql (5.6)+ rspec(3.4)という感じでとりあえずテストできるようにするところまでをまとめた。 GitLab CIに関わる設定・実装以外は割愛しています。

正直、mysqlに接続できないところで一番はまってたので、多分これ見てやればハマらないかと。

  1. CI用に config/database.ci.ymlを作成しておく。
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# (確かこの辺はDocker Imageに依存している設定。)
test: &test
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: sample_repo
  host: mysql
  port: 3306
  database: sample_repo

production:
  <<: *default
  database: db/production.sqlite3
  1. .gitlab-ci.ymlを以下の内容で作成。
image: ruby:2.2

services: (ここに使用するミドルウェアのDocker Image等を書いていく)
  - mysql:5.6

variables: (ここでDocker ImageのMysql Root Passwordを設定するようなイメージ)
  MYSQL_ROOT_PASSWORD: sample_repo

before_script:
  - cp config/database.ci.yml config/database.yml
  - bundle install --jobs $(nproc) --path=/cache/bundler

test:
  script:
    - bundle exec rake db:setup RAILS_ENV=test
    - bundle exec rspec
  tags:
    - ruby
    - mysql

あとは、コミットして、Pushすればよい。 既に連携されているので、実況状況や結果もすぐに眺めることが出来る。

あとは、カバレッジなんかも計測できる。 これはリポジトリの設定画面かなんかで設定するものだった気がするけど。

commit messageに [ci-skip]って入れとくとCIが走らないようにもなっている。

bundle installのところでおまじないチックなコマンド書いてるけど、これはbundle installの結果をcacheさせるため。 Gemfile.lockが更新されているときはちゃんとアップデートしてくれる。

あとのやりたいことはドキュメント見ればなんとなくわかるので、こちらを参照して欲しい。 GitLab Documentation

herokuのデプロイ例なんかも載っているし、EngineYardでもCapistranoでも問題ないと思う。

Jenkinsと比べた時によいところ

良かったところは、Jenkinsを使ってDockerを使ってクリーンな環境でテストがやりたい時にちょっと面倒だったのが、 これだとパッケージインストールするのと少しの設定だけであっさり出来てしまうこと。

CIとGitLabとの連携も、GithubとCircleCIのそれよりは面倒だけど、Jenkinsより圧倒的にラク。 介護する人は必要かもしれないけど、Jenkinsより管理コストは低い気がする。

総括

正直なところ、おすすめできるかどうかは微妙。 使ってて壊れたり、ハマったりっていうのは今のところ無いけど、壊れない保証はない。0.7.xでまだまだ開発中だし。 僕はこれを結構気に入ってて(選択の余地なくて)、人柱になってますが。

不安定な可能性があることが問題ないと思えて、GitLabを使ってて、CIに凝った設定とかしてなければマジでオススメ。 管理しなきゃいけない項目もそんなに無いし。

知見はそこまで無いけど、Docker知ってる人がいれば大体大丈夫だと思う。 正直なところ、なにかコンテナ関連でハマるとすれば、凝ったテストとかをやりだそうとした時だと思う。

初めてCodeIQをやってみた感想。

前提条件

  • 24歳文系エンジニア
  • Javaの授業の時にJavascriptやってるような、ゴミみたいな専門学校卒。
  • 運用系の仕事をやってたので、2年くらいブランク期間あった。
  • いまは一応仕事でもやっているということにしている。
  • エンジニアに向いてないって言われたこともあるくらいのポンコツ
  • 最近Ruby入門したばっかり。
  • コードが汚いことで定評がある。
  • CodeIQとか、課題を解く感じのWebサービスは知ってたけど、どうせ時間かかるし、解けないし敬遠してた。

ということで、まずはめっちゃ簡単そうなのからはじめてみた。

挑戦した問題

https://codeiq.jp/q/2495

やってみた感想

  • とりあえず、解くことができた。けど、時間は確実に20分くらいはかかっていた。(未計測)
  • 自動採点では正解してたけど、もしかすると不正解な可能性ある。
  • やっぱりポンコツエンジニアなので、Specやtestファイルを事前に準備してあると、今後回答していくうえで時間短縮できると思うけど、チートなんじゃね?
  • Rubyメソッドでやりたいことがわからなくて、ググってしまってつらい。
  • これを2分位で解くことが出来るスーパーウェッブエンジニアになりたい。
  • 週に1回くらい、気分転換を兼ねてこういう問題を積極的に解いていきたい。
  • でも、できそう、できないで取捨選択しがちなので、自動でこれやれーってアラートしてくれる方が、エンジニア的には嬉しいのかなぁと思ったり。
  • 現実的な問題として避けてきてた部分だったけど、これを続けることで自分の良くないところがはっきりすると思うので、辛くなっても歯をくいしばって頑張ってみる。

酒をやめてから1ヶ月くらいたった

酒をやめてから1ヶ月とちょっとになる。

webuilder240.hatenablog.com

もともとそこまで飲んでなかったのだけど、 すこし変化があったのでなんとなく書いてみる。

1.酒の席では意外と平気だった。

実は禁酒宣言したすぐあとに、2回ほどお酒の席があったのだけれども、 ふつーに断れました。 1回めは会社の人達と飲みに出かけるみたいな感じだったので、そこまで心配でもなかったけど、 2回目は初めての人・久しぶりの人がいる中での飲み会みたいな感じだったので、 どうかな、大丈夫かなと思ったけど、事情説明したら全然大丈夫だった。 でもまぁ、こんなところですいません。みたいなこと言われて、ちょっと申し訳無さあったけど、気にしないで行くことにした。 飲み会自体は楽しかったですよ。とても。 向こうはどう思っているかしらん

2 .なんか心配されるようになった

なにかあったの? 彼女にフラれたのか? 酒で失敗でもしたのか? 今やっている案件がうまく回るまでお酒我慢しているのか?

といらん心配されるようになった。

なにもないし、彼女にフラれてないし、酒で失敗は夏に1回しかしてないし、仕事と酒は関係ないし でいちいち説明する手間があるのがちょっと。。というところ。

3.夜にじっくり時間を使えるようになった

でもこれはデメリットでもあって、 飲みに行ってもはやく寝る理由もないので、 夜の時間を活かしてだんだんと夜行性になっている感じがするので、これはメリットでもあり、デメリットでもあるかなと。 最近は顕著で、寒いこともあってかどんどん朝が遅くなっていっている。

それでも時間がもったいないと思うことはなくなったので、これはいい方向に行っているということにしておく。

4.ポテチをたまに食べたくなるのでやっぱりやめられない。

お酒は関係なかった。 これから買いに行く。

[WIP] 弱小Railsアプリケーションで日毎のコメント数やユーザー数をなるべく重くない・お手軽な方法で集計したい

TODO

  • 日付毎の投稿数とかコメント数とか集まったいいね数の集計とって、ダッシュボードつくりたい。
  • できればコメント投稿された時にダッシュボードの情報が更新されてて欲しい。
  • グラフを出力するので0件だった時に0件って出て欲しい

制約

  • Rails + Mysql
  • PV月の1万〜2万くらい
  • リリースして1ヶ月ちょっとくらい。
  • 弱小Webアプリケーションだし、変にミドルウェア増やしたりとかでお金かけたくない。なるべくめんどうな方法はとりたくない
  • そこまで解析するデータも全然無いので(一番レコード数多いので1000件とか)有料サービスとかもったいないのでなるべく使わない。

とりあえず、ミドルウェアを追加とかしないで、なるべく他のものを使わず、なんとかできないか試行錯誤してみた。

やったこと

雑にActiveRecord使う

daily_comment_counts = Comment.where(created_at: from..to)
  .group("YEAR(created_at)")
  .group("MONTH(created_at)")
  .group("DAY(created_at)")
  .count()

コメントが存在するときは良いのだけど、データが0件だったときに歯抜けが生じてしまう。(弱小なのでコメントが無い日ももちろんあるのです…) グラフを表示する上で0件だった時に0件って出て欲しいので、却下。

SQL書いた

この辺を参考にして、やってみた。

http://symfoware.blog68.fc2.com/blog-entry-1713.html

あらかじめテーブルを作っといて、それをjoinするみたいな感じ。

これだとデータに歯抜けは生じない。 が、SQLに処理を書きすぎてしまってて、めっちゃ重い。 あと、そこまでSQL力無いので、これをメンテする自信ないし却下。

集計のバッチ書いて、別の集計用のModelに保存しておく

今度試してみる。 ただ、コメントを増えた直後にデータが連動しない。 ダッシュボードのデータがバッチ処理待ちになってしまう。 余裕あれば、AmazonのLambda使ってみたい。

別に集計用のモデル用意して、コメントが追加・削除された時に、集計用のModelの指定の日付のカウント数をインクリメント・デクリメントする

そこまでユーザーいないならって前提で、バイト先の人に聞いたら上記のバッチ処理にするかこの方法にするかのどっちかが良いとかえってきた。 いまはこの方法で進めている。

とりあえず、after_saveとかでモデルの保存や変更にHookして、 指定の日付とアクションに対してのレコードを別の集計用のModelに作っておいて、そこのカウント数をインクリメント・デクリメントしてあげればよいという雑な実装。 あとで理由は書くけど、更新するレコードがない場合は作成するように考慮してあげないといけない。

デメリット

  • とりあえず、できそうだけどなんか納得できてない部分がある。
  • コメント投稿・いいねがされる度に、データベースに対して、Updateがかかるようになってしまっている。
  • もっと他にいい方法があるはず、としか思えない。
  • やっぱり0埋めできないんじゃないの?

0埋めの件

これでやっても、投稿がなければ作成されない。 なので、0埋めをするには前もってレコードを作っておくしか無くて、cronで1日に1回、0時とかに予め更新用のレコードを追加してあげる必要がある。

0時とかの処理中にコメント数とかが増えても困るので、レコードが既に作ってあったら作成しない様にする、

筋が悪い実装かもしれないのでどうにかしたいけど。

稼働中のサービスに対しては?

歯をくいしばってRakeタスク書いて実行するしか無い。

途中から集計するものを増やす場合は?

歯をくいしばってRakeタスク書いて実行するしか無い。

途中からカウントする条件とかを変更する場合は?

歯をくいしばってRakeタスク書いて実行するしか無い。

弱小じゃなくなったらどうするの??

その時は資金力も出るくらいには間違いなくなっているし、リソース割けると思うし、 トレジャーデータなり、ビッククエリなり、スケールしやすそうのを使えばいいのではないでしょうか。 その段階まで来たら、歯をくいしばってRakeタスク書きたくない。

結論

  • ビッククエリとかそこまでしなくてもいいようなサイトさんの泥臭い知見もっと欲しい
  • もちろんこれは不正解な実装な気がするので、もっと詳しい人に話伺いたい。
  • 多分一番良いのはバッチ処理だと思っている。
  • 安くて柔軟に集計とかとれるいいもの・方法を誰か知りませんか?

trelloからリリースノートのテンプレートを雑に作るRubyスクリプト

弊社では全体のタスク管理にTrelloを使用してて、 アップデートの一覧もそのままTrelloにまとめている。 なので、リリースノートをそのままTrelloから吐き出せれば便利だと思ったので作ってみた。

Apiキーの確認やtokenの取得方法についてはこの記事を参照されたし。

qiita.com

雑なテンプレートのルール


# Release for {指定したTrelloのボードの名前} {リスト名}

## {カードの名前}  [カードにつけているラベルの一覧]

こんな感じにしてる。 簡易的なものなので、内容に関してはカード名だけで完結するようにした。

サンプルデータ

f:id:oh240:20160111005610p:plain

この内容はFirefoxのリリースノートから拝借しました。

実行結果

gistbb1fc797632db799cfeb

雑なスクリプト

実行前に"ruby-trello"をインストールしておいてください。(僕はbunlder使いましたが。)

gem install "ruby-trello"

gist1b1549869dd85b7ef17e

この雑なスクリプトに対して、

 ruby script.rb test_application 1.0.0

と実行してあげれば良い。