GitBucket 4.26.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.26.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.26.0

セントラルレジストリからのプラグインインストール

先日運用を開始したプラグインレジストリからインターネット経由でプラグインをインストールできるようになりました。

f:id:takezoe:20180627120403p:plain

プラグインレジストリについては以下のエントリを参照していただければと思います。

takezoe.hatenablog.com

ダッシュボードにRepositoriesタブを追加

ダッシュボードにログイン中のユーザが参照可能なリポジトリの一覧を表示するRepositoriesを追加しました。

f:id:takezoe:20180627120534p:plain

これに伴い、ダッシュボードのサイドバーは非ログイン時もログイン時も最近更新されたリポジトリの一覧に固定されました(これまではログイン時は参照可能なリポジトリの一覧が表示されていました)。

Forkダイアログの改善

"Fork"ボタンがサイドバーから画面の右上のボタンに移動しました。このボタンをクリックすることでフォークするアカウントを選択するダイアログが表示されます。

f:id:takezoe:20180627120801p:plain

ダイアログはカードスタイルからリストスタイルに変更されています。長いアカウント名でも省略されなくなったため、目的のアカウントを見つけるのが容易になっています。また、"Show forks"ボタンをクリックするとフォークの一覧を表示することができます。

f:id:takezoe:20180627120933p:plain

クイックプルリクエストのサジェストを抑制

リポジトリビューアにはブランチからワンクリックでプルリクエスト作成画面に遷移できるサジェストが表示されますが、この表示条件を以下のように修正することにより、不要なサジェストの表示を抑制しました。

  • A last committer of the branch is the logged-in user
  • A last commit of the branch is within one hour
  • The branch isn't behind of the default branch

f:id:takezoe:20180627121139p:plain

未完了のタスクリストの表示

プルリクエストでは古いコミットに対するコメントはデフォルトでは折りたたまれて表示されますが、未完了のタスクリストを含むコメントについては折りたたまずに表示するようになりました。

f:id:takezoe:20180627121326p:plain

プラグイン向けに新しい通知フックを追加

通知に関して、以下のフックを追加しました。

  • assigned
  • closedByCommitComment

実際に通知を有効にするにはGitBucketのバージョンアップ後にgitbucket-notification-pluginを最新版に更新する必要があります。

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

GitBucketのプラグインレジストリの運用を始めました

f:id:takezoe:20180618024108p:plain

GitBucketはプラグイン機構を持っているのですが、Jenkinsのようにインターネット経由でインストールできるようにしたいという考えはGitBucketを作り始めた頃からありました。また、実際にプラグイン機構を導入してみると、本体の修正にあわせてプラグインの修正が必要な場合の検出が難しかったり、ソースコードの修正は不要でもバイナリ互換性の問題で再コンパイルが必要な場合があり、プラグインのメンテナンスコストの点で問題を感じていました。

そこで、インターネット経由でプラグインをインストールするためのセントラルレジストリ兼ビルドファームをここ1ヶ月ほどコツコツ作っていたのですが、ようやく形になってきたので以下で運用を初めてみました。

https://plugins.gitbucket-community.org/

このサイトは以下の機能を持っています。

  • プラグインの開発中バージョン(master)がGitBucket本体のmasterでビルドが通るかチェックする
  • プラグインの最新のリリース版(最新のタグ)がGitBucket本体のmasterでビルドが通るかチェックする
  • プラグインまたはGitBucketに新しいタグが打たれるとビルドしてプラグインのjarファイルをダウンロード可能にする

プラグインは最新のタグのバージョンがGitBucketのリリース毎に自動的にビルドされるという形になります(jarファイル名にGitBucketのバージョンが含まれるようになります)。インストール時はお使いのGitBucketのバージョン用にビルドされたjarファイルを使用することでこれまでのようにプラグインが動作するGitBucketのバージョンを気にする必要はなくなります。

現在はGitBucketのorganizationで開発されているプラグインしか登録されていませんが、将来的にはサードパーティ製のプラグインも登録できるようにする予定です。プラグイン作者の方のメンテナンスコストの低減、ユーザの利便性の向上の両方に繋がるのではないかと思っています。

GitBucket側でこのレジストリからプラグインをインストールできるようにする機能もすでに実装してあるのですが、次のリリースに含めるかどうかはまだ検討しているところです。

github.com

ASUSのリアル店舗にスマートフォンを修理に出してみた

f:id:takezoe:20180617020005j:plain

ASUSのZenfone2というSIMフリー端末を3年ほど使っていたのですが、うっかり落としてディスプレイをバキバキに割ってしまい、バッテリーがだいぶヘタってきていたこともあり新しい端末に変えようと思い、価格重視で同じくASUSのZenfone4 Maxという端末を購入しました。

ローエンドの機種ですが、まあ自分の場合そんなに大した使い方をするわけではないので性能的には特に不満はないです。Zenfone2と比べるとディスプレイが小さく解像度も低いのでPCサイトを見ると字が潰れて読みにくくなったかなというくらいでしょうか。あとはZenfone2とSIMのサイズが違ったので(Zenfone2はMicroSIMだったのですがZenfone4 MaxはNanoSIM)SIM交換の手間がかかりました。BIC SIM(IIJ Mio)なので即時発行の手数料はかかりますがビックカメラの店頭で再発行してもらえるのは便利です。

ところが、使い始めて二週間ほどでいつの間にかメインカメラが動作しなくなってしまいました。購入直後に二段階認証の移行などでQRコードを撮影した記憶はあるので初期不良ではないと思われ、仕方なく修理に出すことにしました。海外メーカーの端末ですし、電話したり郵送したりするのは面倒だなーと思っていたのですが、調べたところどうやら赤坂にリアル店舗があり、修理も受け付けてくれているようです。職場からも近いのでWebサイトから予約して修理に出しに行ってみました。

k-tai.watch.impress.co.jp

店舗はアップルストアのような感じでだいぶお洒落な感じでした。様々なASUS製品やアクセサリの販売もしているのですが、やはりサポート・修理拠点としての意味合いが強いのでしょうか。自分以外にも数名のお客さんがいましたが、さほど待たされることもなく端末をチェックしてもらい、カメラの作動音からおそらくオートフォーカスの故障と思われるのでメインカメラの交換が必要、保証期間内なので無料で修理可能ですが2日かかるとのことでそのまま修理をお願いし、2日後無事受け取ることができました。

いままでPCなどではリアル店舗でのサポートの必要性を感じたことはなかったのですが(PCは修理に出しても職場には作業環境があるし、最悪数週間手元になくてもなんとかなる)、スマートフォン、特に非キャリア端末の場合代替機の貸し出しなどもないので国内で短期間で修理・受取が可能なのは便利だなと感じました。

今回のように安価な端末の場合は諦めて買い直すというのも選択肢の1つですが、ハイエンドの端末だとなかなかそうもいきません。電話サポートだと面倒なことになるケースも多いですが、ASUS Storeの店員さんは対応も丁寧でしたし、スキルもだいぶ高そうな感じでまったくストレスはありませんでした。特に直接店舗を訪問できる環境の方にとってはASUS製品を安心して購入できる材料になるのではないかと思います。

MacでThinkPad Bluetoothキーボードを使う場合のKarabiner Elementsの設定

職場で使っているMacBook Proの外付けキーボードをThinkPad Bluetoothキーボードにしてみました。

モノ自体はUSB接続の有線版と同じですが、Macで使う場合、ファンクションキーの入力にFnキーとのコンビネーションが必要なのを変更できなかったり、トラックポイントのスクロールボタンの挙動がちょっと違う感じがします。US配列ですが、Karabiner Elementsは以下のような設定にしてみました。

f:id:takezoe:20181103122212p:plain

f:id:takezoe:20180604113417p:plain

マウスのbutton3を適当なキーに変更することでChromeなどでトラックポイントスクロールしようとしたときに新しいウィンドウが開いてしまう問題を回避できます(USB版ではセンターボタンを単独でクリックした場合は新しいウィンドウが開いてしまうのですが、スクロールするときは開かなかったのであまり気になりませんでした)。ファンクションキーはどうしようもないみたいなので今のところ諦めています。

それとトラックポイントでのマウスカーソルの移動の感度がやや悪い気がするのですが、Mac側の設定でマウスカーソルの速度を最大にした上でトラックポイントのキャップをロープロファイル(昔のものと比べると少し背が低い)のものから通常の高さのキャップに交換することでいい感じになります。操作性がだいぶよくなるのでおすすめのカスタマイズです。

takezoe.hatenablog.com

やはりケーブルがないのはいいですね。特にキー入力の遅延も感じられませんし、有線版と同じ感覚で使用できています。ファンクションキーを多用する人だと厳しいかもしれませんが、自分はそんなでもないので今のところさほど不便はなさそうです。

GitBucket 4.25.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.25.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.25.0

セキュリティの改善

以前のバージョンのGitBucketにはKacper SzurekさんによるGitBucket 4.23.1 Unauthenticated Remote Code Executionという記事で解説されているようにいくつかのセキュリティ上の問題がありました。

リモートコードが実行可能な脆弱性はすでにGitBucket 4.24.0で修正済みでしたが今回のバージョンではセキュリティトークンの強度についても改善されています。Kacperさんの事前の連絡によって素早く修正を行うことができました。ありがとうございました。

また、この他にもパスワードのハッシュ強度などいくつかのセキュリティ上の改善が行われていますので、既存のバージョンをお使いの方はバージョンアップを強くお奨めします。

プロフィールページにメールアドレスを表示可能に

システム設定により、ユーザのプロフィールページにメールアドレスを表示できるようになりました。

f:id:takezoe:20180529111625p:plain

コミットコメントでもタスクリストが有効に

コミットコメントでもタスクリストが利用可能になりました。

f:id:takezoe:20180529111656p:plain

イシューやプルリクエストの変更履歴の強化

イシュー、プルリクエストのタイトルの変更が変更履歴として記録されるようになりました。

f:id:takezoe:20180529111640p:plain

公開キーを参照可能なエンドポイントを追加

/{user}.keys というエンドポイントでユーザの公開キーを参照できるようになりました。

リポジトリのダウンロード機能の改善

リポジトリのダウンロード機能に以下のような改善が加えられました。

  • LFS管理のファイルも含まれるように
  • リポジトリ全体だけでなく、特定のディレクトリをダウンロード可能に
  • ダウンロードファイル名改善(これまでは{branch}.zipでしたが{repository}-{branch}-{directory}.zipのようになりました。リポジトリのルートディレクトリの場合は{repository}-{branch}.zipのようになります)

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

Software Design総集編【2013~2017】に関数型プログラミングについて書かせていただきました

Software Designさんは大昔にWikiの記事などを書かせていただいた記憶があるのですが、昨年久しぶりにGitHub、BitBucket等の比較記事を書かせていただいたので総集編をお送りいただきました。そうえいば弊社の同僚も文字コードの記事やtmuxの記事を書かせていただいていましたね。

また、今回の総集編では関数型プログラミングについて書き下ろしで少しだけ書かせていただいています。仕事でScalaを8年近くやってきていろいろ思うところもあったりするわけですが、プログラマとして関数型プログラミングとどう接するべきかということについて自分なりに考えていることをまとめてみました。

書き下ろしの記事ではこの他にもクラウド、コンテナ、サーバーレス、機械学習、IoTとここ数年の技術変化のおさらいと今後についてそれぞれの分野で一線で活躍されている皆さんが寄稿されています。DVD-ROMに収録されている総集編のPDFファイルはWebからもダウンロード可能となっているあたりもさすが技評さんわかってますねという感じです。

普段Software Deisgnさんを読んでいらっしゃる方も本棚の圧縮に如何でしょうか。

Software Design総集編【2013~2017】

Software Design総集編【2013~2017】

GraphQLスキーマからCRUDを自動生成できるPrismaについて

Prismaは、様々なデータベースをバックエンドにGraphQLのスキーマからCRUDを行うためのエンドポイントを提供するプロキシとして動作するミドルウェアです。最近$4.5Mの資金調達をしてちょっとだけ話題になりました。

www.prisma.io

Prismaが提供するソフトウェアは現在オープンソースソフトウェアとしてGitHub上で公開されています。本体はScalaで書かれていますが、CLIはTypeScript(Node.js)で書かれているようです。Scalaのコードは関数型プログラミングを駆使したものではなく、比較的読みやすい部類だと思います。

github.com

触ってみる

GraphQLのエンドポイントを簡単に用意することができそうということで少し調べてみました。Webサイトにチュートリアルがあり、dockerを使って簡単に試すことができるようになっています。事前にnpmとdockerが利用できるようになっている必要があります。

まずはnpmでPrismaCLIをインストールします。

$ npm install -g prisma

インストールしたCLIを使ってサンプルを生成します。既存のデータベースを使うか、dockerで新たなデータベースを作成するかを聞かれます。いずれにしろPrisma自体はdockerで起動するので既存のデータベースを使用する場合はdockerコンテナからアクセスできるようになっている必要があります。

$ prisma init hello-world

Webサイトには様々なデータストアを利用できるようになると書かれていますが、今のところ対応しているのはMySQLPostgreSQLのみのようで、スケールさせる場合はデータベース側で頑張る(Prisma自体は横に並べればOK)ということのようです。現在はまだベータのようですが、既存のテーブルからGraphQLスキーマを生成するという機能も実装されているようです。

生成されたサンプルを見てみましょう。

$ cd hello-world
$ cat datamodel.graphql
type User {
  id: ID! @unique
  name: String!
}

ディレクトリ内にはこの他にもPrismaやデータベースをdockerで起動するためのdocker-compose.ymlや、Prismaの設定ファイルであるprisma.ymlが生成されています。

Prismaにデプロイして動作確認してみます。まずはdockerコンテナを起動します。

$ docker-compose up -d 

スキーマをデプロイします。するとデータベースに自動的に対応するテーブルが作成され、エンドポイントが利用可能になります。

$ prisma deploy

以下のコマンドでGraphQL PlaygroundというWebブラウザでスキーマを確認したりクエリを投げるためのコンソールを表示することができますので、ここで色々試してみるとよいと思います。クエリが間違ってると赤線が表示されたり、スキーマを確認できたりするのでなかなか便利です。

$ prisma playgroud 

f:id:takezoe:20180523121831p:plain

Prismaスキーマのオートマイグレーションもサポートしています。先ほどのスキーマに以下のようにemailプロパティを追加してみます。

type User {
  id: ID! @unique
  name: String!
  email: String
}

これをprisma deployでデプロイすると以下のようにemailプロパティが追加されていることがわかります。プロパティの削除も可能ですが、すでにデータが入っている場合は警告が表示され、--forceオプションをつけてデプロイを実行する必要がありました.

f:id:takezoe:20180523122625p:plain

Prismaにはサーバーサイドサブスクリプションという機能があり、条件を指定してWebフックを登録しておくことができます。たとえば以下のような設定をprisma.ymlに入れておきます(host.docker.internalというのはdockerコンテナ内からホストにアクセスするためのホスト名ですので実際は呼び出したいホストに置き換えてください)。

subscriptions:
  userChangedName:
    webhook:
      url: http://host.docker.internal:8080/test
    query: |
      subscription {
        user(where: {
          mutation_in: [UPDATED]
        }) {
          node {
            id
            name
          }
        }
      }

Userが変更されると指定したURLに以下のような内容のPOSTリクエストが送信されます。

{"data":{"user":{"node":{"id":"cjhij3xjs000h09748tmsaku4","name":"Alice"}}}}

設定ファイルに1つずつ記述しないといけないので数が増えるとちょっと大変そうですが、この機能を使えば簡単な外部連携などはサーバサイドで完結させることができそうです。

感想的なもの

Prismaを使うとシンプルなCRUD用のGraphQL APIを簡単に作成することができるのですが、実際のシステムではそれだけでは済まないケースがほとんどなのではないかと思います。このような場合、Prismaとクライアントの間にもう1層BFF的なGraphQLサーバを作成することが推奨されているようです。ただ、PrismaをラップするGraphQLサーバを自前で作るのであればバックエンドをPrismaでGraphQL化する意味があまりないような気がするんですよね…。SQLを直接書くよりBFFを書きやすいというのはあるのかもしれませんが…。

また、Prismaクラウドサービスとして利用可能なPrisma Cloudというサービスも提供しています。が、こちらはデータベースは自前で用意する必要があり、Prisma Cloudからインターネット経由でデータベースに接続することが想定されているようです。前述のようにPrismaの手前に別途GraphQLサーバを立てるとすると、手元にあるデータベースにアクセスするためにインターネット経由で一往復しないといけないという状況が発生します。さすがにこれはちょっと厳しいのではという気がします。

機能面にしろ運用面にしろ面倒な部分を外部に丸投げしてる感があり、個人的にはクライアントアプリケーション向けのGraphQL API開発に使ってもあまり楽にならなそうな印象を受けました。いまのところPrismaはGraphQL DB的なものを志向しているように見えるので、そういうものだと割り切って使う必要がありそうです。