Redmine issue assign notice plugin の v1.1.2 をリリースしました

チケットの担当者が変わったときに、SlackやRocket.Chat、Teamsなどに通知するプラグイン、Redmine issue assign notice pluginのv1.1.2をリリースしました。

担当者にグループをアサインするとエラーとなるという致命的な問題でした。

私の関わるプロジェクトでも、先日やっと導入しました。とっても便利ですね!

2020年音楽振り返り

2020年はコロナもあって、数年ぶりにまったくライブに行かない年になりました。
逆に家での時間が増えたので、その分家で音楽を聴く時間も増えたと思います。

Spotifyの2020まとめでみた12月3日時点でのトータル視聴時間は 74,646時間でした。
夜中はYouTubeでPV流しながら作業するし、SoundCloudでも音楽聴くので、それを考慮すると、1日平均で4時間以上は音楽聴いていたようです。

f:id:onozaty:20210101171121p:plain

  • トップアーティスト
    1. eill
    2. ずっと真夜中でいいのに。
    3. Rin音
    4. YOASOBI
    5. ジャスティン・ビーバー
  • トップソング
    1. SPOTLIGHT (eill)
    2. tell me tell me (m-flo laves Sik-K & eill & 向井太一)
    3. 運動 (abelest, 諭吉佳作/men)
    4. MILABO (ずっと真夜中でいいのに。)
    5. snow jam (Rin音)

2019年のSpotifyまとめの画像がもう見れないので比較画像は貼れないのですが、、2019年は洋楽ばっかり(1位のアーティストはEd Sheeran、上位5位も全部洋楽)だったので、それとはうってかわって2020年は邦楽を多く聴く年になりました。

eill

2020年に一番聴いた&ハマったアーティストはeillでした。 tell me tell me で、この良い声のアーティストは誰だろう、、ってところから始まり、SPOTLIGHTを聴いてすぐに大好きになりました。曲が良いのはもちろん、声がとーーっても良いです。


eill | SPOTLIGHT (Official Music Video)

SPOTLIGHT以外でも、この夜が明けるまで、20、MAKUAKE、最近だとFAKE LOVE/ や 片っぽ とか、たくさん良い曲があります。
もっといろんな人に聴いて欲しいアーティストです。ちょっとしたきっかけがあれば、すぐに有名になるんじゃないかなーって思っています。

ずとまよ、Rin音、YOASOBI、ヨルシカ

Spotifyのプレイリストで良く聴くのはグローバルTop50や日本Top50、Top Hits Japan、Tokyo Super Hits!、Teen Cultureといったところですが、そこからYOASOBI、ずとまよ、Rin音やヨルシカを知って、どんどん聴くようになりました。
どのアーティストも特徴があって、好きな曲がたくさんあります。家族も好きで、小学2年生の娘も良く歌ってます。

Spotifyのおかげでいろいろ新しい音楽を見つけることができているので、ほんとSpotifyすばらしいです。家族みんな音楽が好きなので、Premium Familyに入っています。5人家族で1480円って価格も安すぎるな、、って感じです。

諭吉佳作/men

もっと聞きたかったアーティストです。Spotify上だと楽曲が少ないのですが、、YouTubeやSoundCloudでも聴いています。一番好きな曲は「洋装の語る今日は」で、リズミカルに流れる曲の上でさらに流れるような声という、声も楽器のようなすばらしい曲です。

曲と声のどちらもすばらしいアーティストなので、2021年はもっと楽曲出してくれることをすごーーく期待しています。

2021年に向けて

ストリーミングでのライブはいくつか視聴しましたが、やはり周りのみんなで歌ってアーティストと一緒に盛り上がるライブが最高なので、コロナが収束して、そういったライブにまた参戦できればな、、って思っています。

Flywayでマイグレーション完了時に決められたSQLを実行する

JavaのDBマイグレーションライブラリとしてFlywayを愛用していますが、マイグレーションが全て完了した後に、特定のSQLを流せないかなと調べてみたところ、Callbackという仕組みがあることがわかりました。

マイグレーションが全て成功した後だったり、1マイグレーション毎だったりと、いろいろなコールバックというかフック的なものが用意されています。

マイグレーションが全て完了した後だと、afterMigrateが使えるようです。afterMigrate.sqlを配置し、そこにマイグレーションが全て完了した後に流したいSQLを書けばOKです。

今回これを使いたいと思ったのは、PostgreSQLで参照しかできないユーザを用意したいと思ったところからでした。
PostgreSQLだと、下記のようなSQLでスキーマ内の全部のテーブルに対して権限を与えられます。(以下はpublicスキーマの全てのテーブルに対して、user2にSELECT権限を与えています)

GRANT SELECT ON ALL TABLES IN SCHEMA public To user2;

このSQLは、SQLを実行した時点で存在するテーブルに対してのみしか権限が付与されません。その後に追加されたテーブルがあった場合には、そのテーブルに対しても適宜権限を付与する必要がでてきます。

テーブル追加されるごとに行うのはかなり煩雑なので、afterMigrate.sqlにこのSQLを書いておけば、毎回全てのテーブルに対して権限を与えることができてとても便利そうです。

試したプロジェクトのリンクも張っておきます。

Redmine issue assign notice plugin を作りました

この記事はRedmine Advent Calendar 2020 17日目の記事です。

チケットの担当者が変わったときに、SlackやRocket.Chatなどに通知するプラグインを作りました。

チケットの担当者が変わった時に、下記のようなメッセージを投稿してくれるようになります。

  • 1行目: 担当者変更に関する情報
  • 2行目: プロジェクト名、トラッカー、チケット番号、題名、ステータス
  • 3行目: チケット新規作成時は説明、チケット変更時は注記(先頭200文字まで)

https://github.com/onozaty/redmine_issue_assign_notice/raw/main/screenshots/slack_message.png

また、オプションでメンションを送ることもできます。(メンション先のIDは、ユーザのカスタムフィールドを利用します)

https://github.com/onozaty/redmine_issue_assign_notice/raw/main/screenshots/slack_mention.png

詳しい利用方法は、下記をご参照ください!

Redmine3.0.2と、最新の4.1.1で動作することを確認しています。
また、通知先としてSlackとRocket.Chatで確認していますが、Incoming webhookでtextしか使っていないので、Incoming webhookに対応している他のチャットツールでも動くと思います。(メンション周りはツールによって異なるので、動かないところあったら教えてください!)

こんなプロジェクトにおすすめ

  • 担当者を頻繁に切り替えながら進めていくようなプロジェクト
    • View customize使って、ステータス毎に担当者を切り替える仕組みと組み合わせるとさらに捗ります
  • とりあえずRedmineとSlackなどを連携してみたけど、大量に通知が流れるだけで、あまり活用されていないプロジェクト
    • 本当に欲しいのは「自分が担当者になったことにすぐに気づける仕組み」だったりしないでしょうか

Redmine: View customize plugin の v2.8.0 をリリースしました

View customize plugin の v2.8.0 をリリースしました。

Insertion position として Bottom of all pages が選べるようになりました。

f:id:onozaty:20201124224411p:plain

HTML bodyの末尾に埋め込まれるような形になります。これを利用すると、Redmine自体でJavaScriptが埋め込まれているような箇所(例えばガントチャート)で、それより後に実行するといったことが簡単にできます。

iquiw (Iku Iwasa)さんに要望+プルリクエストをいただき実現しました。ありがとうございます。

挿入位置を表す名称を悩んだ(特に日本語)のですが、いったんこの名前にしています。HTML上の要素で表した方が良いのかな、、とも思いましたが、いったんこのままで。

WebDriverManagerを利用してSeleniumでのWebDriverの更新を楽にする

ブラウザでのテストだけではなく、ちょっとしたブラウザ操作の自動化にもSeleniumを利用するのですが、久しぶりに起動すると、各ブラウザのDriverが古くでエラーになる、、みたいなことが多々発生していました。

今更ながら、他の方々はどうやってこの問題を解決しているのだろうと調べてみたら、WebDriverManagerというとても便利なものがあることを知りました。

WebDriverManagerは、下記のようなコードを書くだけで、、

WebDriverManager.chromedriver().setup();
  • PCにインストールされているブラウザのバージョンをチェック。
  • バージョンと一致するDriverをダウンロード。ローカルにキャッシュするので、2回目以降はキャッシュが利用される。
  • そのDriverを実行するのに必要なシステム変数(webdriver.chrome.driverとか)を設定。

といったことをやってくれます。これを使えば、自分でいちいち最新のDriverをダウンロードしてくるといったことをする必要はありません。

個人のプロダクトでSelenium使っているものは、全部WebDriverManagerに置き換えました。

サンプルとしてRedmineに対してのテストをGradleプロジェクトとして書いているので、気になる方はぜひ。

SeleniumでChromeをヘッドレスモードで動作させた場合に org.openqa.selenium.ElementNotInteractableException: element not interactable が発生する

SeleniumでChromeDriverで実行した際に、ヘッドレスモードだとエラー、ヘッドレスモードにしないと成功するといったテストがありました。

エラー内容は下記のような感じで、要素が操作できないといったものでした。

org.openqa.selenium.ElementNotInteractableException: element not interactable
  (Session info: headless chrome=86.0.4240.183)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'DESKTOP-U275NQ4', ip: '192.168.33.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_222'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 86.0.4240.183, chrome: {chromedriverVersion: 86.0.4240.22 (398b0743353ff..., userDataDir: C:\Users\xxxxx\AppData\Lo...}, goog:chromeOptions: {debuggerAddress: localhost:57435}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: 467a08d7a335a893b5ec767a330cc821
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
    at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:84)
    at com.github.onozaty.selenium.RedmineTest.login(RedmineTest.java:114)
    at com.github.onozaty.selenium.RedmineTest.チケット作成(RedmineTest.java:41)

調べたところ、下記のような記事を見つけました。

ヘッドレスモードの場合、ウインドウのデフォルトサイズは 800 × 600 になり、ヘッドレスモードではないときよりサイズが小さくなるため、このような現象になるようです。

下記のような形で、ウインドウサイズを指定してあげることで回避できました。

        ChromeOptions options = new ChromeOptions()
                .setHeadless(true)
                .addArguments("-window-size=1280,1024");
        WebDriver driver = new ChromeDriver(options);