Nginx の Webdav でデプロイ時のみパスワードが必要な Mavenリポジトリ を立てる
前回の記事で JitPack を使えば Mavenリポジトリ を立てる必要すらないっていう話を書いたのですが、 クローズドな環境では外部サービスの利用が難しい場合があります。
そこで、今回は Nginx を使ってサクッと Mavenリポジトリ を立ててみます。
さらにリポジトリは誰でも見られるようにして、デプロイ時はパスワード認証をかけます。
CentOS 7系でやってみましょう。
ここでは、使い捨てのDockerコンテナを立ち上げて試します。
docker run --rm -it -p 80:80 centos:7 bash
Nginxのインストール
CentOS 7 にインストールするためには、yumリポジトリを追加する必要があります。
vi /etc/yum.repos.d/nginx.repo
[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1
リポジトリを追加したら yum
コマンドでインストールしましょう。
yum install -y nginx
インストールをしたら起動します。 nginx
コマンドはバックグラウンドで実行されます。
nginx
Dockerコンテナでなく実際のサーバーで実行する場合は
systemctl start nginx
で開始することができます。
起動した状態で、ブラウザで以下にアクセスしてみましょう。
以下のような画面が表示されれば Nginx が起動しています。
確認が済んだらプロセスを終了します。
コンテナで起動している場合は pid
を取得して kill します。
ps x | grep [n]ginx | awk '{print $1}' | xargs kill
実際のサーバーの場合は以下で終了することができます。
systemctl stop nginx
Basic認証できるようにする
ライブラリの利用時は認証せず、デプロイ時にはユーザー名とパスワードで認証するようにします。
Nginx でBasic認証を利用する場合ために httpd-tools
をインストールします。
yum install -y httpd-tools
Basic認証のユーザーファイルを作成しましょう。
htpasswd -c /etc/nginx/.htpasswd ユーザー名
画面の指示に従ってパスワードを入力します。
作成された /etc/nginx/.htpasswd
がBasic認証用のファイルとなります。
Mavenリポジトリの設定を追加する
vi /etc/nginx/conf.d/maven.conf
server { # localhost でアクセスすると default.conf が優先される。 # 以下の設定で 127.0.0.1 にアクセスするとこちらが優先される。 listen 80 default; server_name _; # アクセスする際のパス 以下の場合 http://サーバー名/maven/ location /maven/ { # この場合 /var + /mavan/ で Mavenリポジトリの root は /var/maven root /var; # デプロイ時の一時ディレクトリ client_body_temp_path /tmp/maven; # ディレクトリを作成するか create_full_put_path on; # ブラウザでディレクトリにアクセスした際に一覧が表示されるようにする autoindex on; autoindex_exact_size off; autoindex_localtime on; # webav を有効にする dav_access group:r all:r; dav_methods PUT DELETE MKCOL COPY MOVE; # GET 以外に制限(Basic認証)をかける limit_except GET { auth_basic "Maven Repo"; auth_basic_user_file "/etc/nginx/.htpasswd"; } } }
設定を作成したら、必要なディレクトリを作成しましょう。
プロセスは nginx
ユーザーで実行されるため、作成したディレクトリのオーナーを nginx
に変更しておきます。
mkdir -p /var/maven /tmp/maven chown nginx:nginx /var/maven /tmp/maven nginx
/etc/nginx/conf.d/default.conf
は server_name localhost;
が設定されているため、
http://localhost/maven/ にアクセスしても default.conf
が適用されます。
よって、 404 エラーが返ってきてしまいます。
http://127.0.0.1/maven/ にアクセスすることで /etc/nginx/conf.d/macen.conf
が適用され、
/var/maven/
以下を参照することができます。
ライブラリをデプロイする
Maven
デプロイしたいプロジェクトの pom.xml
を編集します。
distributionManagement
にリポジトリ情報を追記します。
Dockerホストからデプロイする場合、 http://127.0.0.1/maven/ です。
webdav を利用してアップロードするので、 dav:http://127.0.0.1/maven/
となります。
<project> ... <distributionManagement> <repository> <id>docker.maven</id> <name>Maven Repo</name> <url>dav:http://127.0.0.1/maven/</url> </repository> </distributionManagement> ... <build> <extensions> <extension> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-webdav-jackrabbit</artifactId> <version>3.0.0</version> </extension> </extensions> ... </build> ... </project>
webadv で GET
以外のメソッドにはBasic認証をかけているので、
この状態では ` 401 Unauthorized デとなりプロイできません。
認証情報は $HOME/.m2/settings.xml
に記述します。
<settings> <servers> <server> <!-- pom.xml の distributionManagement/repositoryの id と一致させる --> <id>docker.maven</id> <username>ユーザー名</username> <password>パスワード</password> </server> </servers> </settings>
下記のコマンドでデプロイすることができます。
mvn deploy
Gradle
build.gradle
を編集します。
apply plugin: 'maven' configurations { deployerJars } repositories { mavenCentral() } dependencies { deployerJars 'org.apache.maven.wagon:wagon-webdav-jackrabbit:3.0.0' } uploadArchives { repositories.mavenDeployer { configuration = configurations.deployerJars repository(url: "http://127.0.0.1/maven/") { authentication(userName: "ユーザー名", password: "パスワード") } } }
コマンドは以下の通りです。
./gradlew uploadArchives
これによりJarファイル や pom.xml
も自動的に生成され、サーバーにアップロードされます。
ライブラリの利用
デプロイ後にブラウザでアクセスしてみると、ディレクトリが増えていると思います。
Mavenリポジトリは URL を指定するだけで追加できます。
リポジトリを追加したら、通常のライブラリと同じように dependency を記述します。
Maven
<project> <repositories> ... <repository> <id>maven.docker</id> <name>Maven Repo</name> <url>http://127.0.0.1/maven/</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-maven</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
Gradle
repositories { maven { url 'http://127.0.0.1/maven/' } } dependenciea { implementation 'com.example:example-maven:0.0.1-SNAPSHOT' }
おわり
Nginx で webdav を利用して Mavenリポジトリ を立てて、Basic認証でデプロイ(アップロード)を制限する方法を記述しました。
社内ネットワークでライブラリを配布したいけど、webdavでなんでもデプロイされるのはちょっと...ていう場合には使えるかもしれないです。かなりニッチ...
お試しが終わったらコンテナを終了させましょう。
最初の docker
コマンドで --rm
オプションを指定しているので、コンテナから抜ければ自動的に削除されます。
まっさらな環境で試す場合に Docker 非常に便利ですね。
exit
Mavenライブラリ配布の自動化をやめた話
この記事は モバイル 自動化/自動テスト Advent Calendar 2017 の19日目です。
皆さんは、JavaやKotlinで作成したライブラリ、加えてGradleプラグインの配布について悩んだことはないでしょうか。
クロスプラットフォームな開発環境も増えましたが、Android開発といえば Java や Kotlin といった JVM言語が主流です。
もちろんライブラリもこれらの言語で作成されます。
一般的に、JavaやKotlinで作成されたライブラリの配布はMavenリポジトリを介して行われます。
Maven公式のリポジトリは Maven Central です。 その他、 Bintray jcenter も有名なリポジトリです。 よってライブラリを作成して公開したい場合は上記サーバーにデプロイすることになります。 しかし、Maven Central にライブラリを登録するまでにはアカウント作成など面倒な手順を踏むことになります。
今は21世紀なのでサクッとライブラリを作成して公開したいですね。
Mavenリポジトリを立てて公開する
Mavenリポジトリは、誰でも立てることができます。 http(s) でアクセスできるサーバーを立てるだけです。
自分はこれまで、GitHubでソースコードを管理し、レンタルサーバーにリポジトリを立てて公開していました。 また、ソースコードの更新からリポジトリへの公開は自動化していました。
自分の場合、MavenリポジトリとJenkinsサーバーを同一にしています。
GitHubで master ブランチが更新された場合、 Jenkinsが mvn deploy
を実行するだけです。
このコマンドではローカルのMavenリポジトリに配置されますが、
HTTPサーバーの静的コンテンツを配置するディレクトリ以下にMavenリポジトリを指定すると、
サーバーを介してライブラリを利用することができます。
<distributionManagement> <repository> <id>local</id> <name>local</name> <url>file://localhost/path/to/DocumentRoot</url> </repository> </distributionManagement>
この方法ではライブラリを作るたびにJenkinsのジョブを追加しなければなりません。 また、公開できるサーバーとドメインを所有している必要があります。
そこで、GitHubのみを利用して公開する方法を探していました。
GitHub Pagesを利用して公開する
GitHubの ユーザー名.github.io リポジトリあるいは特定のブランチを maven リポジトリとして公開しちゃう方法です。 「GitHub Maven リポジトリ」で検索とこの方法がヒットします。
今回は ユーザー名.github.io リポジトリを利用して公開する方法をご紹介します。
public_repo と user:email の権限を付与した Personal Access Token を作成する
ローカルマシンの
settings.xml
でサーバーを設定する
通常は$HOME/.m2/settings.xml
にあります。
<settings ...> <servers> <server> <id>github.com</id> <password>取得した Personal Access Token</password> </server> </servers> </settings>
- プロジェクトの
pom.xml
を設定する
今回利用するsite-maven-plugin
は Maven Plugin として提供されているので、pom.xml
で設定しています。
<profiles> ... <profile> <id>github</id> <properties> <!-- settings.xml で記述したサーバーの id --> <github.global.server>github.com</github.global.server> </properties> <distributionManagement> <repository> <id>internal.repos</id> <name>Temporary Repository</name> <!-- mvn deploy コマンドで ビルドディレクトリ/mvn 以下にデプロイするようにする --> <url>file://${project.build.directory}/mvn</url> </repository> </distributionManagement> <build> <plugins> <plugin> <groupId>com.github.github</groupId> <artifactId>site-maven-plugin</artifactId> <version>0.12</version> <configuration> <message>Maven artifacts for ${project.version}</message> <!-- GitHubにプッシュするディレクトリを ビルドディレクトリ に指定する --> <outputDirectory>${project.build.directory></outputDirectory> <!-- ビルドディレクトリには classファイル なども作成されるのでディレクトリを指定する --> <includes> <!-- mvn deploy コマンドで作成されるローカルリポジトリ --> <include>mvn/**/*</include> </includes> <repositoryOwner>GitHubのユーザー名</repositoryOwner> <repositoryName>GitHubのユーザー名.github.io</repositoryName> <branch>refs/heads/master</branch> <!-- デフォルトだと最新版の artifact で上書きしてしまうので、マージする --> <merge>true</merge> </configuration> <executions> <execution> <goals> <goal>site</goal> </goals> <!-- maven deploy 後に実行されるようにする --> <phase>deploy</phase> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>
- 実行する
実行時は上述のpom.xml
で設定したプロファイルを指定します。
mvn deploy -P github
- 自動的に実行されるようにする
あとはお好みの CI/CD で上述のコマンドが実行されるようにするだけです。
これによりライブラリの配布もGitHub上でできるようになりました。
ライブラリを利用する場合はリポジトリのURLとして https://ユーザー名.github.io/mvn/
を指定します。
maven-site-plugin
を利用しているため、Gradleの場合は pom.xml
の生成など手間が増えます。
JitPackを利用する
JitPack は少し変わったMavenリポジトリです。 Spockなどがこのリポジトリを介して配布されています。
JitPack を利用する場合、配布側でビルドする必要がありません。 JitPack上のライブラリをインポートしたタイミングで JitPack上でビルドされるのです。
GitHub上のライブラリを利用する
ライブラリの指定
- groupId を
com.github.リポジトリオーナー名
にする - artifactId を
リポジトリ名
にする - バージョンに
リリースタグ
またはコミットハッシュ
を指定する
- groupId を
この方法では特別ビルドを行う必要がありません。
しかし、JitPack が groupId
や artifactId
を書き換えてしまうので、混乱するかもしれません。
ライブラリの groupId
と artifactId
を それぞれ com.github.リポジトリオーナー名
と リポジトリ名
にしてしまうのが最も簡単でしょう。
しかし、groupId
は独自のドメインを指定したい場合もあります。
JitPackでは DNS TXTレコード を利用してドメイン名を指定する方法を提供しています。 https://jitpack.io/docs/#custom-domain-name
まとめ
最近までレンタルサーバーに Maven リポジトリを立てていたのですが、 できる限り管理するサーバーは減らしたいですよね。
Spockを利用する際に指定されていた Mavenリポジトリ が今まで利用したことがなかったものなので調べてみると、 とても便利だったので久しぶりにテンションがあがりました。
これまでGolangやJavaScript、Rubyなど比較して Javaのライブラリ配布は面倒な印象がありました。 しかし、JitPack を利用すれば配布するためのビルドする必要すらなくなりました。 また、GitHubにソースが公開されているけど配布されていないライブラリについても利用できる可能性があります。
Publicなライブラリの場合はこういったサービスを無料で利用することができて非常に便利ですね。
iOSDCで当日スタッフ & LTトークしてきました
i will blog.
全写真です。ご査収ください! #iosdc
— iOSDC (@iosdcjp) 2017年9月21日
前夜祭https://t.co/bDZi3cbgQM
1日目https://t.co/DXQSr3xyx4
2日目https://t.co/25tEGJRrZA
みんなのアルバムhttps://t.co/nEuFBpBZaD
こちらのiOSDCの写真をみてたんです。
…ぼくめっちゃデブやん…
鏡って2割ほど痩せて見えるんですね。気づきがありました。
さて iOSDC 2017 も終わり、日々の業務を粛々と進めております。
僕は 当日スタッフ と、 LTトーク枠で参加してきました。
LTトーク内容は 所属グループのブログ で少し紹介しているのでそちらをご覧ください。
発表前日に資料について気になって、調査したり資料を直したりしていたら朝になっていました。
発表内容に興味を持っていただいて、懇親会時に話かけていただいたりもして、やはり発表するのはいいなと思いました。
…笑いはとれなかったけど。
当日スタッフとしては、トラックDの担当でした。
トラックDはあまりセッションもなかったので、受けつけのヘルプをしていた時間の方が長かったかもしれないです。
あとは仕事ありそうなところ手伝ったり、LT前は緊張しすぎてウロウロしていました。
スタッフのみなさん本当に出来る方々ばかりで、頭があがりませんでした。 何よりみなさんが本当に楽しんでいて、それがよかった。
是非来年もスタッフとして参加させていただきたいです。
トークも応募したいと思います。
それまでにダイエットします。
痩せてイケメン枠で登壇&スタッフしたいです。
普段は iOS Test Night、 Android Test Night などで運営のお手伝いをしています。こちらもどうぞ参加ください。
俺コンでも発表します。
GitHubと各種CIサービスを連携してみる
普段GitHubを使っていて、Travis CIと連携してバッヂをつけたりしています。 Pull Requestが来たときなんかも自動でビルド・テストをしてくれるので便利ですよね。
今回は、自分でサーバーを用意せず利用できるCIとGitHubを連携してみました。 今回ご紹介するのは以下のCIサービスです。
- Travis CI
- Circle CI
- Wercker
Travis CI
GitHubとの連携
トップページ右上の Sign in with GitHub からログインすることができます。
ログイン後、 https://travis-ci.org/profile/GitHubのアカウント名/ にアクセスすると、Publicなリポジトリ一覧が表示されます。
連携したいリポジトリを に設定すると連携できます。
リポジトリの設定
リポジトリの設定は、リポジトリ名横の歯車マークをクリックします。
以下のような設定項目が表示されます。
.travis.yml の記述
詳しくは https://docs.travis-ci.com/user/customizing-the-build/ を見ながら設定しましょう。
以下は ruby プロジェクト(https://github.com/duck8823/danger-slack)の例
language: ruby cache: directories: - bundle rvm: - 2.3.1 before_script: - bundle exec danger script: - bundle exec rake spec
Travis CIはOS X のイメージも無料で利用することができます。
設定項目も必要最低限で1画面でまとまっていて、
スケジュールも設定できる。
個人のOSSなんかは Travis CI を使うと便利そうですね。
Circle CI
GitHubとの連携
Circle CI のサインアップページから Start with GitHub をクリックし、ログインします。
ログイン後に Settings > Projects に進むとリポジトリ一覧が表示されます。
連携したいリポジトリの歯車マークを押し、 表示されたページで Follow Project をクリックしましょう。
リポジトリの設定
follow すると、様々な設定が可能になります。 Settings > Projects > 設定したいプロジェクトの歯車マーク
環境変数は BUILD SETTINGS の Environment Variables で設定できます。
circle.yml の設定
以下は ruby プロジェクト(https://github.com/duck8823/danger-slack)の例
machine: ruby: version: 2.3.1 test: pre: - bundle exec danger override: - bundle exec rake spec
circle ci では osx を利用するには有料プランを選択する必要があります。
Wercker
GitHub との連携
https://app.wercker.com にアクセスするとログインページに遷移します。
LOG IN WITH GITHUB をクリックしてログインしましょう。
ログイン後、ヘッダーに表示されている Create をクリックし、 Application を選択します。
リポジトリ一覧が表示されるので、連携したいプロジェクトを選択肢し、 Use selected repo をクリックします。
続いてアクセス方法を選択して Next step をクリックします。
リポジトリの設定
ヘッダーメニューの Applications をクリックし、一覧から設定したいリポジトリを選択します。 Environment を選択すると環境変数を設定することができます。 TokenなどはProtectedにチェックをつけるといいでしょう。
werker.yml
box: ruby build: steps: - bundle-install - script: name: test code: bundle exec rake spec
Werkerは、パイプラインを作成することも可能です。
プライベートリポジトリも無料で利用できます。
残念ながら今のところ Danger は利用できません。
Dangerプラグインを作ろう
Danger
最近流行りつつある? Danger です。 Pull Request に対して色々チェックできるようになります。
先月末にポツポツと紹介記事が出ました。
- cookpadさんの記事
- Recruit Jobsさんの記事
- Node版のDangerJSは こちらの記事 が詳しいです。
Dangerとても便利です。 他のプロジェクトでも使えそうなルールなどはプラグインにして使い回ししたいですね。 なのでプラグインを作ってみます。
プラグイン作成も公式ページで詳しく乗ってます。 http://danger.systems/guides/creating_your_first_plugin.html
Dangerのインストール
$ gem install danger
プラグインの初期化
プラグイン名にハイフン(-)は推奨されていません。 単語はアンダースコア(_)で区切りましょう。
$ danger plugins create <plugin_name>
上記コマンドを実行すると、 git config からユーザ名とメールアドレスを取得してよしなに初期化してくれます。
danger-plugin_name/ ├── Gemfile ├── Guardfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── danger-plugin_name.gemspec ├── lib │ ├── danger_plugin.rb │ ├── danger_plugin_name.rb │ └── plugin_name │ ├── gem_version.rb │ └── plugin.rb └── spec ├── plugin_name_spec.rb └── spec_helper.rb 3 directories, 12 files
作成されたディレクトリへ移動します。
danger-<plugin_name>
というディレクトリが作成されています。
$ cd danger-plugin_name
テストなどに必要なGemをインストールしておきます。
$ bundle install --path vendor/bundle
また、テストを実行する際にリポジトリの upstream の情報が必要になります。リポジトリを作成して upstream を登録しておきます。
$ git remote add origin <上流のリポジトリURL> $ git push -u origin master
メソッドを作る
簡単なプラグインを作る場合は lib/<plugin_name>/plugin.rb
を変更するだけでできます。
say
というメソッドを追加してみます。
lib/<plugin_name>/plugin.rb
diff --git a/lib/plugin_name/plugin.rb b/lib/plugin_name/plugin.rb index eeda801..cea9600 100644 --- a/lib/plugin_name/plugin.rb +++ b/lib/plugin_name/plugin.rb @@ -29,5 +29,12 @@ module Danger def warn_on_mondays warn 'Trying to merge code on a Monday' if Date.today.wday == 1 end + + # A method that messages 'Hello Danger.' + # @return [Array<String>] + # + def say + message 'Hello Danger.' + end end end
テストを書く
プラグインを作ったらテストをかきましょう。
spec/<plugin_name>_spec.rb
diff --git a/spec/plugin_name_spec.rb b/spec/plugin_name_spec.rb index 484958f..a3ec8ad 100644 --- a/spec/plugin_name_spec.rb +++ b/spec/plugin_name_spec.rb @@ -36,6 +36,11 @@ module Danger expect(@dangerfile.status_report[:warnings]).to eq([]) end + it "Messages" do + @my_plugin.say + + expect(@dangerfile.status_report[:messages]).to eq(["Hello Danger."]) + end end end end
テストを書いたら実行します。 以下のコマンドで rspec と RuboCop が実行されます。 RuboCopでは色々指摘されると思うので必要あれば修正してください。
$ bundle exec rake spec
.... Finished in 0.06292 seconds (files took 0.4549 seconds to load) 4 examples, 0 failures Running RuboCop... Inspecting 6 files ...CCC Offenses: lib/plugin_name/plugin.rb:20:1: C: Extra empty line detected at class body beginning. lib/plugin_name/plugin.rb:30:12: C: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. warn 'Trying to merge code on a Monday' if Date.today.wday == 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lib/plugin_name/plugin.rb:37:15: C: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. message 'Hello Danger.' ^^^^^^^^^^^^^^^ spec/plugin_name_spec.rb:42:1: C: Tab detected. expect(@dangerfile.status_report[:messages]).to eq(["Hello Danger."]) ^^ spec/plugin_name_spec.rb:42:3: C: Inconsistent indentation detected. expect(@dangerfile.status_report[:messages]).to eq(["Hello Danger."]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ spec/spec_helper.rb:12:23: C: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping. if `git remote -v` == '' ^^ 6 files inspected, 6 offenses detected RuboCop failed!
動作確認したい
これがとてもめんどくさいです。 Pull Requestを用意する必要があります。 確認の場合、既にCloseされている Pull Request でも問題ありません。 個人で開発しているライブラリのリポジトリで確認してみました。
$ git clone https://github.com/duck8823/Slack-RTM-Bot.git $ cd Slack-RTM-Bot
Dangerとプラグインを使えるようにGemfileを用意してやります。
プラグインは :path
を指定することで作成途中のもので試すことができます。
Gemfile
source "https://rubygems.org" gem 'danger' gem 'danger-plugin_name', :path => 'path/to/danger-plugin_name'
bundleインストール
$ bundle install --path vendor/bundle
これで準備ができました。
続いて Dangerfile
を用意しましょう。
プロジェクト直下に置く必要があります。
Dangerfile
plugin_name.say
Dangerfile
ではプラグインのインスタンスが利用できます。
インスタンス名は以下の命名規則に従います。
http://danger.systems/guides/creating_your_first_plugin.html#tech-specs
確認は、
$ bundle exec danger local
で可能です。
また、
$ bundle exec danger pr https://github.com/duck8823/Slack-RTM-Bot/pull/20
のようにすることで特定の Pull Request に対して確認することも可能です。
local
または pr
で実行した場合、以下のような内容が表示されます。
Info: +------------------+----------------------------------------------------------------------------------------------+ | Danger v5.3.3 | | DSL Attributes | +------------------+----------------------------------------------------------------------------------------------+ | status_report | | | violation_report | | | --- | --- | | scm_provider | github | | diff | diff --git a/lib/Slack/RTM/Bot/Client.pm b/lib/Slack/RTM/Bot/Client.pm | | | index 9b86bc6..4c8ff0d 100644 | | | --- a/lib/Slack/RTM/Bot/Client.pm | | | +++ b/lib/Slack/RTM/Bot/Client.pm | | | @@ -248,7 +248,7 @@ sub _listen { | | | $channel = $self->find_channel_or_group_name($buffer_obj->{channel}); | $channel ||= $self->_refetch_channel_name($buffer_obj->{channel}); | $channel ||= $self->_refetch_group_name($buffer_obj->{channel}); | | - die "There are no channels or groups of such id: $buffer_obj->{user}" unless $user; | | + die "There are no channels or groups of such id: $buffer_obj->{channel}" unless $channel; | |RTM::Bot::Response->new( | | | @@ -273,4 +273,4 @@ ACTION: for my $action(@{$self->{actions}}){ | | | | | | -1; | | | \ No newline at end of file | | | +1; | | added_files | #<Danger::FileList:0x007fe123a9d678> | | deleted_files | #<Danger::FileList:0x007fe123a9cea8> | | modified_files | lib/Slack/RTM/Bot/Client.pm | | renamed_files | [] | | lines_of_code | 4 | | deletions | 2 | | insertions | 2 | | commits | b4e3b9fd228752e3c7fffd7c9cb5258959f281a2 | | api | Octokit::Client | | pr_json | [Skipped JSON] | | mr_json | [Skipped JSON] | | pr_diff | [Skipped Diff] | | review | #<Danger::RequestSources::GitHubSource::Review:0x007fe12398a498> | | pr_title | bugfix channel or group not found (was checking for user instead) | | pr_body | | | pr_author | dada | | pr_labels | [] | | branch_for_base | master | | branch_for_head | master | | base_commit | 947aeeaf5443494d3e7895292662b617b369bf05 | | head_commit | b4e3b9fd228752e3c7fffd7c9cb5258959f281a2 | | mr_title | bugfix channel or group not found (was checking for user instead) | | mr_body | | | mr_author | dada | | mr_labels | [] | | say | Violation Hello Danger. { file: , line: } | | my_attribute | | | warn_on_mondays | | | --- | --- | | SCM | Danger::GitRepo | | Source | Danger::LocalGitRepo | | Requests | Danger::RequestSources::GitHub | | Base Commit | commit 947aeeaf5443494d3e7895292662b617b369bf05 | | | Author: shunsuke maeda <duck8823@gmail.com> | | | Date: Sat Apr 8 12:30:31 2017 +0900 | | | | | | Checking in changes prior to tagging of version 1.04. | | | | | | Changelog diff is: | | | | | | diff --git a/Changes b/Changes | | | index 311b411..e8e2578 100644 | | | --- a/Changes | | | +++ b/Changes | | | @@ -2,6 +2,10 @@ Revision history for Perl extension Slack-RTM-Bot | | | | | | {{$NEXT}} | | | | | | +1.04 2017-04-08T03:30:26Z | | | + | | | + - Fix dying when response to new channel/group | | | + | | | 1.03 2017-04-05T23:11:07Z | | | | | | - Fix a bug that zombies spawn when stop_RTM | | Head Commit | commit b4e3b9fd228752e3c7fffd7c9cb5258959f281a2 | | | Author: dada <dada@perl.it> | | | Date: Fri May 19 18:07:20 2017 +0200 | | | | | | bugfix channel or group not found (was checking for user instead) | +------------------+----------------------------------------------------------------------------------------------+ Results: Messages: - [ ] Hello Danger. - [ ] Hello Danger.
Info:
ではDangerが取得した Git や GitHub などの情報を閲覧することができます。また、プラグイン内の 引数がないメソッドを自動的に実行し 、結果を表示してくれます。
Results:
では message
や fail
などの DSL を実行した結果を表示してくれます。
上記の例で Hello Danger.
が重複して表示されているのは、
- Dangerfileでの呼び出し
- Info: で表示するための呼び出し
で二回実行されたからです。
引数なしのメソッドでPull Requestをクローズするなどの処理を実装した場合、local または pr モードで意図しないメソッド呼び出しが起こる場合があるので気をつけましょう。
(記事を書いた時点でDangerのバージョンは 5.3.3
)
また、実行時に
Octokit::TooManyRequests: GET https://api.github.com/repos/duck8823/Slack-RTM-Bot/issues/20: 403 - API rate limit exceeded for
というようなエラーが出た場合は、
環境変数に DANGER_GITHUB_API_TOKEN
を設定してやることで回避できる場合があります。
利用するトークンは https://github.com/settings/tokens で作成することができます。
READMEの自動生成
Dangerは README を自動的に生成するコマンドも用意してくれています。
$ bundle exec danger plugins readme
### plugin_name This is your plugin class. Any attributes or methods you expose here will be available from within your Dangerfile. To be published on the Danger plugins site, you will need to have the public interface documented. Danger uses [YARD](http://yardoc.org/) for generating documentation from your plugin source, and you can verify by running `danger plugins lint` or `bundle exec rake spec`. You should replace these comments with a public description of your library. <blockquote>Ensure people are well warned about merging on Mondays <pre> my_plugin.warn_on_mondays</pre> </blockquote> #### Attributes `my_attribute` - An attribute that you can read/write from your Dangerfile #### Methods `warn_on_mondays` - A method that you can call from your Dangerfile `say` - A method that messages 'Hello Danger.'
plugins readme
コマンドは lib/<plugin_name>/plugin.rb
のドキュメント(YARD形式)を元にREADMEを作成します。
正しくドキュメントが記述されているかどうかは、
$ bundle exec danger plugins lint
で調べることができます。 例えば、追加したメソッドにドキュメントが存在しない場合には以下のようなエラーが出ます。
[!] Failed Errors - Description - say (method): - You should include a description for your method. - @see - https://github.com/dbgrandi/danger-prose/blob/v2.0.0/lib/danger_plugin.rb#L40#-L41 - /private/tmp/danger-plugin_name/lib/plugin_name/plugin.rb:33 Warnings - Return Type - say (method): - If the function has no useful return value, use ` @return [void]` - this will be ignored by documentation generators. - @see - https://github.com/dbgrandi/danger-prose/blob/v2.0.0/lib/danger_plugin.rb#L46 - /private/tmp/danger-plugin_name/lib/plugin_name/plugin.rb:33 Failing due to errors
記述に従ってドキュメントを整備しましょう。
公開しましょう
良いプラグインができたら公開しましょう。
公開前に、 danger-<plugin_name>.gemspec
を確認しましょう。
danger-<plugin_name>.gemspec
# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'plugin_name/gem_version.rb' Gem::Specification.new do |spec| spec.name = 'danger-plugin_name' spec.version = PluginName::VERSION spec.authors = ['shunsuke maeda'] spec.email = ['duck8823@gmail.com'] spec.description = %q{A short description of danger-plugin_name.} spec.summary = %q{A longer description of danger-plugin_name.} spec.homepage = 'https://github.com/duck8823/danger-plugin_name' spec.license = 'MIT' . . .
githubアカウント名と git config の user.name が異なる場合などは適宜変更してください。 spec.homepage
のアカウント名部分に user.name が使われるのでスペースがある場合などは gem に登録できません。
修正が完了したら
$ rake release
で RubyGems に登録することができます。
さらに Danger本家サイト にプラグインとして紹介してもらいましょう。 以下にプラグインを追加して Merge Request を出せば、光速でマージしてくれます。
https://gitlab.com/danger-systems/danger.systems/blob/master/plugins.json
その後、サイトはそのうち更新されます。
plugins
コマンドでも確認できます。
$ danger plugins Downloading Plugins list... Available Danger Plugins: -> danger-prose A danger plugin for working with bodies of markdown prose. - Gem: danger-prose - URL: https://github.com/dbgrandi/danger-prose -> danger-android_lint Lint files of a gradle based Android project. This is done using the Android's Lint tool. Results are passed out as tables in markdown. - Gem: danger-android_lint - URL: https://github.com/loadsmart/danger-android_lint ・ ・ ・
公開したプラグイン
僕が作ったプラグインも掲載されています。 http://danger.systems/plugins/slack.html
message や fail などの内容をSlackに通知するプラグインです。 DangerはGitHub上に HTML 形式でコメントしてくれるので、 GitHub の Slack 連携では HTML は表現されません。 対策としてHTMLコメントでそれぞれの数を表示してくれているのですが微妙な感じ。
プラグインでは内容も表示し、色によって error などわかるようにしました。
地味にチャンネルやメンバー一覧を取得するメソッドも用意しています。 サクッと指摘内容をSlackに通知したい場合は使ってみてください。 https://github.com/duck8823/danger-slack