Archive Page 2

継続的インテグレーションのススメ Jenkinsでテスト結果を表示

前回のお話でJenkinsとGitHubによる継続的インテグレーションの開発環境の設定を行いました。

GitHubとJenkins連動 自動デプロイ 開発環境設定編

今回は、継続的インテグレーションを行うにあたり実際にJenkinsでテストを実行した際に
「どんなテスト結果を表示してくれるのか?」ということをご紹介したいと思います。

現在FuelPHPを用いて開発を行なっているためここでのテストの実行にはPHPUnitを使用して行っています。

JenkinsとPHPUnitでテスト実行

ちなみに余談ですが, Jenkinsってイギリス人の執事をイメージした名前だそうです。
プロジェクトに優秀な執事がいるような思いが込められてこの名前が付けられたと言われています。

参考:Jenkinsで始める継続的インテグレーション

Jenkinsはイギリス人の執事

では、JenkinsというよりはPHPのUnitテストでどんなレポートを表示してくれるのか?

たくさんあるのですが、大きく5つ紹介します。

  1. テスト結果の表示
  2. コードカバレッジの表示
  3. バグになりそうな箇所や実装上の問題・無駄を検出
  4. 冗長化したコードを自動で検出しコードの最適化
  5. ドキュメントの自動生成

大きくこれら5つについての説明とJenkinsで表示した際の表示内容を見て行きましょう。

テストの結果の表示

テストの結果は、その名の通り成功したテストや失敗したテストの一覧を表示してくれます。

テスト結果の推移

失敗

コードカバレッジの表示

コードカバレッジとは、作成したテストがテスト対象コードのうちどのくらいテストしているかを表している率のことを言います。
コードカバレッジが高いほどテストコードがしっかり書かれていて、品質の良いコードを保つことが出来ています。

コードカバレッジ全体

ちなみにコードカバレッジの表示では、カバレッジ率の表示だけではなく、テストがされている行とされていない行を視覚的に分かりやすく表示することができます。
テストの状況は、テストが実施されたファイル、クラス、行数と細かく表示されます

テストの状況をファイル別に表示

テストがされた行とされていない行
テストがされている行は緑色、されていない行は赤色で塗られています。

テストがされた行とされていない行

バグになりそうな箇所や実装上の問題を検出

3のバグになりそうな箇所や実装上の問題を検出については、独自のルールを取り入れることも出来、反していれば警告を表示するといった設定も行うことができます。下記の例では使われていない変数があるため 「UnusedLocalVariable」 と表示されています。

PMD警告

使っていない変数

独自のルールの詳しい設定などについては次回以降の記事で紹介します。

冗長化したコードを自動で検出しコードの最適化

4の冗長化したコードを自動で検出しコードの最適化については、フォルダ内の各ファイルの重複度合いがグラフで表示されます。
そのため共通化出来るところなどが視覚化されコードの最適化につなげることができます。

ドキュメントの自動生成

5のドキュメントの自動生成については、作成しているクラスのリファレンスを自動で生成してくれるものになります。

検索も可能であり、正しいフォーマットで記述することにより作成したメソッドの説明や引数などの情報をリファレンスとしてまとめてくれます。

自動生成されたPHPDocumenter

このように、PHPUnitで用意されている機能をJenkinsで実行するこによりテストの結果を見やすく表現してくれます。

これらは品質の良いコードを保つきっかけになり、品質の良いサービス作りへの第一歩であると思います。

なんか、これらを見ると早くテストを書きたくなってきませんか(笑?

次回は、これらを表示するための設定について書いて行きたいと思います!!

GitHubとJenkins連動 自動デプロイ 開発環境設定編

前回の記事でGitHubとJenkinsを用いた自動デプロイ環境の概要をご説明しました。

GitHubやJenkinsと連携した開発環境作成でのrsyncとの出会い

今回は、その環境を実現するための設定手順を書いて行きたいと思います。

大きく4つの手順があります。

  1. Jenkinsのインストール
  2. Apacheの設定
  3. JenkinsとGitHubの連携
  4. 自動デプロイ設定

開発環境

・CentOS 6.2
・Apache がインストール済み

Jenkinsのインストール

まずは、Jenkinsのインストール
通常ならば、運用するサーバとJenkinsが動いているサーバを分けるべきですが、サーバコストの都合などで今回は同一サーバ上で動かすことにします。
ApacheサーバとJenkinsサーバが同じport80で待つことはできないので、jenkinsをport:8080で動かすことにします。

1台のサーバにApacheとJenkinsを起動

また、セキュリティ上必要最低限以外のportを開放したくないため、80番ポートのみ開放して内部的に8080に変換する方法をとります。仕組みとしては、port:80番で「あるURL」にアクセスが来た場合に、内部でport:8080に変換してアクセスするという方法です。この仕組みをリバースプロキシーと言います。

リバースプロキシでJenkinsにアクセス

まずは、この形を目指して設定していきます。
前置きが長くなりましたが、早速Jenkinsのインストール
Jenkinsは、yumでインストールしますが、まずはyumでインストール出来るようリポジトリに追加してから行います。

適当なフォルダ(通常 /tmpかな?)で


  sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins- ci.org/redhat/jenkins.repo sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

を実行後


  sudo yum install jenkins

次にJenkinsを実行するにはJavaが必要であるため、JDKがインストールされていない場合はインストールします。


  sudo yum list \*java-1\* | grep open
  sudo yum install java-1.6.0-openjdk.x86_64
  sudo yum install java-1.6.0-openjdk-devel.x86_64

参考:http://kumagonjp2.blog.fc2.com/blog-entry-103.html

次に『http://ホスト名/jenkins』でアクセスするとJenkinsにアクセス出来るように設定します。
/etc/sysconfig/jenkinsファイルを編集しましょう!

vim /etc/sysconfig/jenkins

デフォルトでは、PORTは8080になっているので、prefixの設定のみ行う


  JENKINS_PORT="8080"

  JENKINS_ARGS="––prefix=/jenkins"

これでJenkins側の設定は終了です。

Apacheの設定

Apacheで起動する際には、バーチャルホストの設定を行ってください。(必須ではありません)
バーチャルホストについては、こちらを参考に...
http://www.atmarkit.co.jp/flinux/rensai/apache08/apache08a.html

Jenkinsにアクセスするためにリバースプロキシの設定を行います。

/etc/httpd/conf/httpd.conf/ か バーチャルホスト別にファイルを分けている場合はそのファイルに下記の内容を追記する


  <VirtualHost *:80>の中に記載
    ...省略...
    
    #jenkinsへアクセス出来るように
    ProxyRequests Off
    ProxyPreserveHost on
    ProxyPass /jenkins http://127.0.0.1:8080/jenkins
    ProxyPassReverse /jenkins http://127.0.0.1:8080/jenkins
    <Proxy http://localhost:8080/jenkins*>
        Order deny,allow
        Allow from all
    </proxy>
  </VirtualHost>

Apacheの再起動!


  sudo service httpd restart

jenkinsの起動


  sudo service jenkins start

注意
※Apacheの開放しているポートに8080が無いことを確認する
※もし8080を開放しているのであれば、コメントアウトする
/etc/httpd/conf/httpd.confの


  Listen 80
  #Listen 8080

これで『http://ホスト名/jenkins』にアクセスして、Jenkinsが開くかどうか確認する。

jenkinsTOPページ

ついでに...

jenkinsの常駐化


  sudo chkconfig jenkins on

リストに入ったことを確認


  /sbin/chkconfig --list | grep jenkins

これで、ApacheとJenkinsが同じサーバで動き始めました!!

Jenkins参考:http://blog.livedoor.jp/tattyamm/archives/4147336.html

〜2013/01/25 追記〜

上記設定では、~~URL~~/jenkinseでアクセス出来ないとの声が多数上がっています。
多分何かの記入漏れだと思いますので、解決し次第追記させて頂きます。

〜2013/01/28 追記〜

上記問題についてですが、ファイアーウォールで8080ポートが解放されていると上手くつながらないそうです。
一度、ファイアーウォール(iptables)で8080ポートを閉じてみて、試してみて下さい。

JenkinsとGitHubの連携

ここからは、自動デプロイ環境構築に向けて、GitHubとの連携を構築していきたいと思います。
前回のおさらいで今目指している形は以下の図の通りです。

理想の開発環境

JenkinsとGitHubの連携を行うために、jenkinsでgit pluginをインストールします。
Jenkinsの管理->プラグインの管理->利用可能で検索してインストール

JenkinsでGit pluginのインストール手順

次にGitHubへは鍵認証が必要であるため、Jenkinsユーザで鍵の認証設定を行います。
Jenkinsをインストールした際に、Jenkinsユーザが既に作成されており、
Jenkinsユーザのホームディレクトリは /var/lib/jenkinsにあります。

では、jenkinsユーザでsshキーの作成を行います


  cd /var/lib/jenkins
  cd .ssh (なければmkdir .ssh)
  sudo -u jenkins -H ssh-keygen -t rsa -C jenkins@hoge.com
  chmod 744 ../.ssh

※パーミッションなどの問題が合った場合、root権限で鍵を作成し/root/.ssh以下に出来た鍵を
/var/lib/jenkins/.sshに移動しchownで所有者をjenkinsに変えるという方法でも大丈夫です。

これで、公開鍵(id_rsa.pub)と秘密鍵(id_rsa)の設定は終了。

次に公開鍵をGitHubに登録します。
プロジェクトごとのキーに設定すると重複してエラーなど出るのでユーザのSSHKeyとして登録する

GitHubに公開鍵の登録

ここで、先ほど作成した公開鍵(id_rsa.pub)の中身を貼り付ける。Titleは好きな名前で良い。

次に大事なのは、GitHubにアクセスできるよう初期アクセスを行うことです。
以下のコマンドでGitHugにアクセス出来るかどうか確認を行なって下さい。


  sudo -u jenkins ssh -T git@github.com
  (メッセージが出たらyesと入力)

最後にJenkinsのgit情報の登録を行う


  sudo -u jenkins git config --global user.email "jenkins@hoge.com"
  sudo -u jenkins git config --global user.name "jenkins"

とりあえずuser.emailは適当で大丈夫です。

次にJenkinsでGitHubからコードを取得するという設定を行います。
そのために、まずは、自動デプロイしたいプロジェクトを作成します。

新規ジョブ作成でフリースタイル・プロジェクトのビルドを選択し、ジョブ名を入力してOKを押します

Jenkins新規ジョブの登録

すると、設定画面が出てくるので中段付近にある「ソースコード管理システム」でGitを選択します。
(この項目が出ていない場合は、Gitプラグインを正しくインストールして下さい)
ここのRepository URLに自動デプロイしたいリポジトリのアドレスを入力して下さい。

JenkinsにgitリポジトリのURLを登録

ここで入力するURLは、http://から始まるURLではなくgit@github.com:から始まるURLを入力して下さい。
これで保存を押して、Jenkinsの初期設定は終了です。

GitHubの設定

次にGitHubへpushしたタイミングで最新のコードをpullしてくる設定を行いたいと思います。
これには、フックという仕組みを利用します。

簡単に説明すると何かアクションが起きたタイミングで、なんらかの処理を行う仕組みのことを言います。
ここでは、GitHubへpushされたタイミングで、Jenkinsがコードをpullしてくるということを実装したいと思います。

フックの仕組み

ここでは、GitHubのService hooksという仕組みを使用します。
Service hooksの設定には、Jenkinsの「ビルドを実行」というところのURLが必要になるためこのURLをコピーしておきます。

ビルド実行URLコピー

右クリックでリンクアドレスをコピーします。

次にGitHubのページへ行き、自動デプロイしたいリポジトリのsettingからService hooksの設定を行います。

GitHub Service Hooksの設定

ここのWebHook URLs に先ほどコピーしたURLを貼り付けて保存します。

これで、GitHubへPushしたタイミングで先ほど入力したURL(ビルドの実行)が呼び出され
最新のコードがJenkinsへpullされるという仕組みの実装が出来ました。

自動デプロイ設定

最後にWebサーバで公開しているディレクトリに最新のコードをデプロイする設定を行います。
ここからは、先日の記事に書いたrsyncを使用します。
rsyncについては、以前の記事を参考に
GitHubやJenkinsと連携した開発環境作成でのrsyncとの出会い

Jenkinsのジョブの設定->ビルドのプルダウンメニューからシェルの実行を選択

Jenkinsシェルの実行

空欄に


    rsync -vr --delete --exclude ".git/" /var/lib/jenkins/jobs/ジョブ名/workspace/ 公開しているディレクトリへの絶対パス

上記設定で、GitHubへpushしたタイミングで自動デプロイが実行され、またテスト用に直接ファイルをサーバにあげてテスト実行後GitHubへPushしたタイミングで公開ディレクトリがGitHubの最新のコードの状態に保たれるという自分にとっての理想の開発環境を構築することが出来ました。

ちなみに別サーバでJenkinsを動かし、そのサーバからrsyncを利用する場合は


    sudo -u user名 rsync -rlptgvC -e "ssh -i 公開鍵名"  /var/lib/jenkins/jobs/Job名/workspace/* user名@IPアドレス:公開ディレクトリ絶対パス

ってな感じで行けるはず,,,

Jenkinsさんは、他にもブランチを切って作業している場合にはブランチの指定やテストが通った場合のみテスト環境へアップさせるなど色々と出来るため、もっと勉強して活用して行きたいと思います!!

ご意見ご指摘、ご感想などありましたらコメント欄へどしどしお書き下さい。
勉強させて頂きます。

長々とありがとうございました!!

参考サイト

FuelPHPのORMでrelatedの注意点

FuelPHPのORMでrelatedを使用する際にlimitとwhere句を用いた場合の注意点です。

relatedでは、limit句が先に実行されその後にwhere句が実行されるため思った結果が返ってこない場合があります。

通常のlimitとwhere句では、先にwhere句が実行された後にlimit句が実行されるので問題ありませんが,,,

 

とりあえず、本日気がついたことなのでメモ程度に...

時間があるときに、再現してみたいと思います。

 

 

 

【勉強会】HTML5カンファレンス2012

2012年9月8日(土)に慶應義塾大学 日吉キャンパスで行われた「HTML5カンファレンス2012」に参加してきたときのメモです。

http://events.html5j.org/conference/2012/09/
HTML5カンファレンス2012のロゴ

既にまとめサイトが存在しておりますので、詳しくはそちらを御覧ください

 http://stocker.jp/diary/html5-conference-2012/

個人的に興味があった内容を下記に挙げていきます。

@yomotsu さんの発表でWebGL and Three.js

 http://www.slideshare.net/yomotsu/webgl-and-threejs
 ※HTML,JavaScript、CSSでここまで出来るのかと感動させられました。

mixiのあんどうやすしさんによるWebRTCとか勉強会

 https://docs.google.com/presentation/d/1MkvmX6Gvb1cRATdwF4RFBtol8NgdnblwlwikDnFhT10/present#slide=id.p

※ちなみに上記資料をもとに丸3日をかけて、WebRTCのまとめとデモを作りました!
 参考:http://megadreams14.com/?p=319
 ※残念ながら仕様変更によりデモは動いておりませんが、仕組みについてはほぼ同じなので参考になるかとは思います。

Hajime OgushiさんによるLT「ピンチとチャンス」

 http://www.slideshare.net/hajimeogushi/html5conference2012-lt
 デザイナーでノンプログラマーなHajime Ogushiさんのプレゼンのデザインセンスがうけました!分かる人にはわかるプレゼン資料です。

HTML5クイズ

 http://www.youtube.com/watch?v=4LBOZTtiEh8&feature=youtu.be
 某テレビ番組の大感謝祭のようなシステムでWebSocketやAjaxなどを使ってリアルタイムにクイズの集計を行い、HTML5カンファレンスの締めとしてふさわしい企画でした。

 こちら作成者様のブログで裏話なども見れるので良かったら是非
  http://georz.hatenablog.com/

 ※ちなみにこのシステムに憧れて自作でも現在作成中!
  Node.jsなどを使って裏側を作成しており残りは見た目と集計部分....
  出来上がったら公開します!!

とても刺激あるカンファレンスでした!
来年も是非!!

WebRTC GetUserMediaとPeerConnectionについて

WebRTCについて昨年9月にまとめた資料があったので公開しておきます。

現地点では仕様が変わっているようですが裏側で行なっていることは同じだと思うので参考になればどうぞ!

ちなみにNode.jsについても記載しておりますので、Nodeの環境構築など興味のある方は是非!

資料:WebRTCについてのまとめ http://peerconnection-video-chat.herokuapp.com/webrtc_report/webrtc_summary.html

FuelPHPのスキャフォールドとマイグレーションで作業効率化

フレームワークを使って開発を始めて約1ヶ月半。
フレームワークの便利さに感動する毎日が続いています。

そんな今日は,今流行のFuelPHPについて。

FuelPHPのロゴ

FuelPHPは、PHP5.3によるWebアプリケーション用のMVCフレームワークです。2010年位Dan Horrigan氏によって開発が開始されました。

PHPのフレームワークには、「CakePHP」や「Symfony」「Codelgniter」など様々なフレームワークがありますが、FuelPHPは軽いため高速な処理を行うソーシャルゲームなどの開発には向いているそうです!

そんなFuelPHPのスキャフォールド(scaffold)マイグレーション(migration)がとても便利なので紹介したいと思います。

scaffoldとmigration

スキャフォールドについて

スキャフォールドとはRuby on Railsで導入された機能で、MVCフレームワークでCRUD操作を行うための枠組みを自動生成する仕組みのことです。

ちなみにCRUDとは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)の頭文字をとった言葉で、データベースの基本的な操作のことを指します。

CRUDの説明

スキャフォールドによって、モデル(DBに接続、SQLの実行など)、ビュー(表示、編集登録、削除画面)、コントローラ、マイグレーションが一括して生成されます。※マイグレーションについては後ほど...

ようするに、スキャフォールドをすることによって、一覧表示画面、データ新規登録画面、データ編集画面、データ削除機能などが一瞬で出来てしまうということです!

FuelPHPでのスキャフォールドのコマンドは、


 php oil g scaffold demo_scaffold title:varchar[50] content:text id:int

上記のコマンドで、文字列で50文字までのtitleカラムとcontentカラム,整数型のidカラムのモデルが出来上がり、同時に表示編集登録削除のコントローラーも出来上がります。

超便利!!

マイグレーションについて

マイグレーションとは、データベースのテーブル構造を管理するものです。
マイグレーションを実行することで、作成したモデルをDBに反映させることが可能です。
FuelPHPでは、fuel/app/migrations以下のファイルを読み込むことで実行されます。

コマンドは、


 php oil refine migrate

上記コマンドを実行することで、作成したモデルがDBに反映されました!

ただし、この状態でファイルにアクセスしても以下のようなエラー画面が出ます。

Orm Model not Found!

これは、configファイルにModelを読み込む設定をしていないためなので、
fuel/app/config/config.phpのreturn array()の中に下記の情報を付け加えてあげましょう!

    'always_load'  => array(
            'packages'  => array(
                'orm',
                'auth',
            ),            
    ), 

そうするとページが表示出来るようになります。

scaffoldで作成した画面

編集画面

scaffold編集画面

削除機能もあり

scaffold 削除画面

これからフレームワークを使って開発を行う際には、スキャフォールドとマイグレーションは使用して行きましょう!!

GitHubやJenkinsと連携した開発環境作成でのrsyncとの出会い

社会人1年目のエンジニアにおいて開発環境の構築にはかなり時間がかかるもの。
わけの分からないエラーと戦ったり、他の人の環境では動いても自分の環境では動かないなどそういう経験がある人も多いのではないでしょうか?

今回は、GitHubやJenkinsと連携した開発環境を構築する上で出会ったrsyncコマンドとの出会いについてお話したいと思います。

まず、rsyncコマンドとは、ファイルなどのバックアップや同期を行うために使用されるコマンドで、変更分を検出して差分のみを転送することができ、cpコマンドと違って効率的なバックアップを行うことができます。また、ネットワーク経由でもバックアップや同期が行えたり、sshなどのリモートシェル経由でも利用が可能であるためとても便利なコマンドだそうです!

rsyncコマンドロゴ

このrsyncコマンドを知った瞬間、自分たちが構築したい環境を簡単に出来るではないか!と凄く感動しました!

まずは、使いたいと思った背景をご説明したいと思います。

目指すべく開発環境は、ソースコードをGitHubで管理し、継続的インテグレーションを導入するためにJenkinsを利用してサーバへ自動デプロイされる仕組みを構築することです。

理想の開発環境

上の図のようにローカル環境で実装し、ある機能が実装されるとcommitしてGitHubへpushします。
その後GitHubからJenkinsへデプロイされテストが実行されます。
テストが正しく通ればサーバへ反映されるという仕組みです。

しかし、ローカル環境だけではテストが出来ない場合もあるため、テストサーバへはFTPを使ってファイルをあげてサーバ上でもチェックが出来る環境を構築したいと考えていました。

テスト環境に直接ファイルをあげる

しかし、テスト環境にFTPでファイルをあげた際にずっとそのファイルが残り続けるのは良くないため、ローカルからGitHubへpushされJenkinsが動いた時には、サーバにあるコードは全てGitHubにcommitされている最新版へ戻すような設定を行いたいと思っていました。

デプロイ後gitHubの状態にする

それを実現するためにjenkinsでGitHubからとってきたファイルをコピーする方法やそもそもテストサーバのファイルもgitで管理しちゃおうなど色々考えました。

1:ファイルをコピーして同期
 jenkinsはテストを行う前にgitHubから最新版のデータをpullしてきます。その時には/var/lib/jenkins/以下にworkspaceというディレクトリが出来、そこにソースコードがpullされる仕組みになっています。そのファイルをサーバで設定されているドキュメントルート以下にコピーしようという考えです。

 しかし、コピーをするだけだと
 ・不必要なファイルは消えずに永遠に残ってしまう
 ・毎回変更がないファイルもコピーされるので処理が重くなる
 などの問題があったため断念....

2:テストサーバ側もgit管理してしまう
 git stashコマンドを使おうという考えです。git stashは,変更を一時的に退避させるコマンドであり実行するとcommitされたところまで状態を戻すことが出来ます。

git stash

しかし,この方法も本来のgit stashの使い方に則していなったり(感覚的に)、なんか気持ち悪いため断念....

他にも色々考えましたが,なかなかいい方法が思いつかない時に、先輩から「rsyncコマンドを使えば」 とアドバイスを頂いたのがrsyncとの初めての出会いです。

rsyncコマンドでは、コピー元ディレクトリとコピー先ディレクトリでの差分だけをコピーし、またコピー元ディレクトリになくてコピー先ディレクトリにあるファイルを削除するといったことも出来るため,まさに自分たちがやりたいと思っていたことを実現できる!魔法のコマンドです(笑)

いやぁrsyncコマンド最強ですね!!

使い方はこんな感じ

 rsync -avr --delete --stats pre/ next/ 

オプションの説明についてはこちらを参考にどうぞ:
はじめてrsyncを使う方が知っておきたい6つのルール

上記の例だとpreディレクトリ以下にあるファイルをnextディレクトリに同期させるコマンドになります。
–deleteオプションをつけることでnextディレクトリにはあってpreディレクトリにないファイルを削除することができます。

rsyncコマンドの説明

これをJenkinsに設定することによって目指すべく開発環境を構築することが出来ました!!
「rsync最強っす!!」

rsyncコマンドロゴ

次回は、これらの開発環境を整えるための手順を書いていきたいと思います。