Redmine テーマのつくりかた

2018年12月17日 0 イベント ,

本記事は Redmine Advent Calendar 2018 の 17 日目です。Redmine テーマ開発について書きます。

Redmine テーマとは?

Redmine を機能拡張する方法としてプラグインとテーマが提供されている。

プラグインは Redmine の API や DB を直に参照・操作可能なので高度な用途に向く。テーマは CSS と画像、JavaScript など Web フロントエンド技術のみで開発され、外観の変更や Web ブラウザーで可能な範囲の簡単なカスタマイズを担当する。

プラグインは高度な機能拡張を可能とする反面、開発の難易度も高い。バグや Redmine 本体との互換問題が起きるとシステムそのものが動作しなくなる危険性もある。そのため上級者向きといえよう。エンド ユーザーとして利用するにしても慎重な管理を要求される。

テーマの機能は Web ブラウザーの範疇に限定されるものの、プラグインに比べて開発の難易度は低い。バグや互換性の問題が起きたとしても Redmine の外観が崩れるぐらいで済む。プラグインほど気負わず開発・利用可能なため、カジュアルに Redmine 拡張を試したい向きにもオススメ。

かくいう私も以下のテーマを開発している。

本記事では私の経験や知見を踏まえた Redmine テーマ開発手法をとりあげる。

Starter Kit

テーマ開発の説明にあたり Starter Kit を用意した。README に従ってセットアップすればテーマ開発環境を構築できる。

以降の内容は Starter Kit プロジェクトを AtomVisual Studio Code に開いた状態でお読みいただくと理解しやすいはず。

Redmine テーマ構成ファイル

Redmine テーマを構成するファイルについて。

特別なフォルダーはルート直下の stylesheets/ が CSS 用、javascripts/ は JavaScript 用。それぞれ以下の固定ファイルを配置する。テーマとしては最低限 application.css があればよい。その他は必要なら定義。

ファイル 役割
application.css Redmine の外観を定義する CSS。
responsive.css Redmine の表示された Web ブラウザー表示幅が一定量を下回った際の外観を定義する CSS。
theme.js Web ブラウザー機能の範疇で動的な処理を実行するための JavaScript。

画像などがあれば適宜、追加してゆく。その際の構成はテーマのフォルダー内で完結すること。Redmine 標準テーマだと画像は images/ に配置して CSS からは ../images/add.png という感じの相対パスで参照している。

CSS

CSS を開発する方法は主に

  1. 標準テーマ CSS を自作テーマ CSS の先頭に @import して必要なスタイルを上書き
  2. 標準テーマ CSS を自作テーマにコピーして編集

となるだろう。方法 1 は可動している Redmine の標準テーマ CSS を

@import url(../../../stylesheets/application.css);

/* 以下に必要なスタイルを上書き */

のように取り込むため、上書き部分の量や構成にもよるが壊れにくい。問題が起きたら上書き部分を削除すれば標準へ戻せる。標準テーマとの差分が少なくて @import のパフォーマンス問題を許容できるならオススメ。

方法 2 は 1 の @import なし版。パフォーマンスが気になるとか、標準に対して大胆に改造する場合によい。

Sass (SCSS)

CSS 開発において直に編集してもよいが AltCSS を利用すると便利だ。AltCSS は CSS を拡張したメタ言語。CSS 標準にない機能や記法を利用しながら編集して CSS に変換する。今回は最も普及しているであろう Sass の SCSS 記法を採用。ファイルの拡張子は *.scss としておく。

Sass は様々なプログラミング言語用のパッケージを提供しているが、今回は Web フロントエンド開発でよく使われる Node.js 版を選択。Node.js で利用するライブラリーやツールは npm 形式で配布されており Sass は node-sass – npm になる。

Starter Kit の CSS/SCSS ファイル関連は以下のように構成。

.
└── src/
    ├── assets/
    │   ├── images/
    │   └── stylesheets/
    │        ├── application.css
    │        └── responsive.css
    └── scss/
        ├── App.scss
        ├── Responsive.scss
        └── default/
            ├── application.css
            └── responsive.css

それぞれのフォルダーについて解説する。

フォルダー 役割
src/ 開発者が編集する CSS やソース コードなどを格納。
src/assets/ 開発時にテーマとして解釈されるフォルダー。後述するローカル HTML を配置したり Docker コンテナ上の Redmine からテーマ フォルダーとして参照される場所。
src/assets/images/ テーマの画像ファイル置き場。
src/assets/stylesheets/ テーマの CSS ファイル置き場。SCSS から変換されたものの出力先。
scss/ SCSS ファイル置き場。App.scssapplication.cssResponsive.scssresponsive.css に変換される。
scss/default/ Redmine 標準 CSS 置き場。これらは SCSS ファイルから参照される。

Sass の提供する便利機能のうち、特に便利なのが @import によるファイル参照と結合。前述のように CSS 標準の @import は対象を動的に参照するため、CSS ファイルとして別れていてもダウンロードを並列化できずパフォーマンスを損なう可能性がある。

Sass の @import はコンパイル時に参照を解決するため、出力された CSS ではファイル間が @import した順番で結合された状態となる。これを前提として Redmine 標準 CSS を取り込むとか、SCSS ファイルが肥大化してきたら別ファイルに分割して後から結合といった運用を実現。

theme.js

CSS ではカスタマイズしきれない部分、例えばページの要素を増減するなどの処理は theme.js に実装する。Starter Kit では以下に配置されているものを編集。

.
└── src/
    └── assets/
         └── javascripts/
              └── theme.js

最近の代表的な Web ブラウザーにおける JavaScript は非常に機能が充実している。そのため外部ライブラリーやツールを使用せずとも実用十分だが、要素の操作などを簡単に処理したければ Redmine 付属の jQuery も利用可能。

Starter Kit の theme.js では以下のようにしている。

(function ($) {
  if (!($)) {
    return
  }

  // Cutomize

})(window.jQuery)

// Cutomize というコメント以降に $ で jQuery の機能を呼び出しながらカスタマイズしてゆく。この処理では jQuery がグローバル定義されていることを判定。Redmine に付属しなくなったらカスタマイズはキャンセルされるようにしてある。

開発スタイル

Starter Kit の提供する機能を利用したテーマ開発スタイルについて。

セットアップ

Starter Kit のセットアップ手順。Windows のコマンド プロンプトや PowerShell、macOS であれば Terminal を使用する。以降、これらをまとめて CLI と呼ぶ。

  1. Node.js 最新版をインストールまたは更新
  2. Starter Kit を入手、Git がなくても GitHub から ZIP 形式で取得可能
  3. CLI 上で cd コマンドにより Starter Kit フォルダーへ移動
  4. CLI 上で npm i コマンドを実行

これで Starter Kit に必要な環境が揃ったはず。

タスク実行

Starter Kit は package.json というファイルに開発で必要とされる機能をタスクとして定義。これらは CLI から npm run タスク という形式で呼び出す。以下にタスクをまとめる。

タスク 機能
start SCSS ファイルの変更監視と自動 CSS コンパイル、プレビューを起動。キーボードから Ctrl + C を押すことで終了する。
release テーマのリリース用イメージを出力。

他にも細かなタスクはあるが、基本的にこれらだけで実用十分なはず。開発中は npm run start で SCSS 編集しながらプレビューで確認。十分な品質となったら npm run release でリリース用イメージを生成 (テーマを ZIP に固めたもの)、それを Web に公開する。

なお start は特殊なタスクで run を省略して npm start でも実行可能。

自動 CSS コンパイルとプレビュー

start タスクで実行される処理について。

SCSS ファイルの変更を監視しており、編集して保存すると自動的に CSS コンパイルされる。プレビューは Redmine の代表的なページを対象に HTML 化したものを Web ブラウザーに表示。CSS がコンパイルされると Web ブラウザー上のプレビューも自動更新される。

そのため SCSS ファイルを編集するエディターと Web ブラウザーのウィンドウを横へ並べると開発しやすい。エディターはお好みで。私の推奨は以下。

これらに Sass (SCSS) 関連プラグインを入れることで構文強調や CSS プロパティーの入力補完などが効くようになる。こうした機能は開発を快適にしてくれるので、ぜひ。

注意点。プレビュー用 HTML は私が Redmine から取得した時点のもの。つまり厳密には Redmine 本体のものと異なるし本体の更新に追従できていない可能性がある。大まかな外観をプレビューするにはよいが、最終的には Redmine 本体で確認したほうがよい。

Redmine 上の動作確認

テーマが Redmine 上で実際に動作することを確認したい。しかし開発中のものを本番環境で試すのはリスクが高く、検証用にサーバーを用意するのも面倒だ。

という開発者のために Starter Kit では DockerDocker Compose により手元で気軽に Redmine 動作環境を構築できるようにしてある。手順は以下。

  1. DockerDocker Compose をインストール
  2. CLI 上で cd コマンドにより Starter Kit フォルダーへ移動
  3. CLI 上で docker-compose up -d コマンドで Redmine 起動、停止は docker-compose stop

この状態で Web ブラウザーから http://localhost:8080/ にアクセスすると Redmine が表示されるはず。ちなみに初期状態の Redmine における user/pass は admin/admin のみとなっている。admin で Sign In したら管理画面からテーマを変更してみよう。mytheme という候補があるので選択すると開発中しているテーマが Redmine へ適用される。

Docker 上の Redmine テーマ フォルダーは Starter Kit の src/assets と連携するように設定済み。そのため SCSS を CSS にコンパイルしたり src/assets 内の構造を変更すれば、そのまま反映される。なにかテーマを変更したら Web ブラウザーから Redmine ページを表示更新することで最新の状態を確認可能。

Docker 関連の設定は以下を参考にした。これまで Redmine 用 Docker イメージは sameersbn/redmine を使用していたのだが、本家となる redmine のほうがバージョン追従や継続性の面でよかろうと判断して移行。

もし Redmine が表示されないようなら Docker コンテナが落ちているかもしれない。コンテナの起動状況は docker ps コマンドで確認。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
d56a255d3cb3        redmine:passenger   "/docker-entrypoint.…"   11 minutes ago      Up 2 seconds        0.0.0.0:8080->3000/tcp   redmine
c299c663ee67        mysql:5.7           "docker-entrypoint.s…"   14 minutes ago      Up 3 seconds        3306/tcp, 33060/tcp      mysql

こんな感じで redminemysql が両方とも存在すれば成功。ないものがあれば docker logs redmine のようにすると対象コンテナのログが表示される。そのメッセージを参考に環境や設定を見直したり、Docker イメージのバグと予想されるなら作者に修正要望を出すなどすること。

リリース用イメージ生成

CLI 上で npm run release を実行することでテーマのリリース用イメージが生成される。その詳細について。

  1. テーマ名でリリース用フォルダーを作成
  2. src/assets に置かれた静的な画像と theme.js をリリース用フォルダーにコピー
  3. プロジェクト直下の CHANGELOG.mdLICENSE ファイルをリリース用フォルダーにコピー
  4. SCSS をリリース用フォルダーに CSS コンパイル出力
  5. リリース用フォルダーを ZIP 圧縮

これらの処理により Web ページなどで配布するためのイメージができあがる。テーマの名前とバージョンはプロジェクトのルートにある package.json の当該設定を編集することで更新可能。

{
  "name": "mytheme",
  "version": "1.0.0"
}

上記ならテーマは mytheme フォルダー、それを圧縮した ZIP ファイルは mytheme-1.0.0.zip というファイル名。私はこのように生成した ZIP を GitHub の Releases ページへアップロードすることでテーマ配信している。

まとめ

この記事により一人でもテーマ開発者が増えることを願っている。質問などがあれば Twitter で声をかけてください。

redmine.tokyo 15 所感

2018年11月14日 0 イベント

2018/11/10 (土) に参加した redmine.tokyo 15 のレポート。前回は登壇したが今回は聴講のみ。

開場前

  • 前回の参加で会場までの交通と時間を把握したつもりだったが、到着はギリギリになった
  • そのため田町駅でそばを食べるのを諦めてコンビニのサンドイッチに
  • 前回登壇していたのと Twitter でキャラ作りの一貫として前回と同じ格好でゆく、と書いたためか受け付けで私だと個体識別された
  • 時間ギリギリのため最後方端に座る、そのためスライドの下 1/3 ぐらいが見えない…

Redmine 4.0 新機能ピックアップ

Redmine 4.0 アウトライン

  • 機能追加とバグ修正は約 200 件、2018/11/9 時点の進捗率は 98%
  • Ruby on Rails 5.2 移行により多くのプラグインが要修正となるだろう
  • MySQL 5.1、PostgreSQL 9.1 以前がサポート外
    • RHEL/CentOS 6 系の yum 標準リポジトリーで入らないバージョン
    • 私が職場で運用している Redmine 環境が CentOS 6 系なので移行しなければならない
    • CentOS 7 へ移行するとして、ついでに Redmine と MySQL を Docker コンポーネント化することも検討したい
  • バージョン番号による変化の話
    • セマンティック バージョニング的な運用
    • Major = フレームワーク更新など大きな影響のあるもの、数年に一度
    • Minor = 多数の機能追加、年に数回
    • Patch = バグ修正や軽微な改善、発表にはなかったが過去の運用を見るに随時

新機能ピックアップ

  • Textile/Markdown プレビューのタブ化
    • GitHub のような感じになる
    • タブ切り替えでページ全体ロードにならなければ便利そう
    • 従来の下側表示は見辛かった
    • うちの Redmine は Markdown にしてあるので、チケットや Wiki に書くときはリアルタイム プレビュー付きエディター (Atom や vscode など) で編集してから貼り付けてた
    • 小〜中規模の文ならこの新プレビューでまかなえそう
  • コンテキストメニュー表示用アイコン
    • チケット一覧がコンテキストメニュー対応しているのに気づきにくい
    • そのため、メニュー表示アイコンを追加した
    • 確かにこの機能、教えるとビックリされる
    • メニューはチケット一覧から一気に担当やステータスを変えられるなど便利なので、この改善により周知されてほしい
  • チケットのウォッチャーで自分以外も選択可能に
    • この機能を前提とした新しい管理手法ができるかも?
    • 少し興味がある程度でウォッチャーに追加するような運用をしていると、フィルターとして有効に機能させるのは難しいそう
  • ユーザーのフィルターにロック中ユーザーを表示
    • 例えば退職したユーザーが担当になっているチケットを探せる
    • 昨年、ちょうどこの用途でこの機能を求めていた時期があった…
  • 親プロジェクトから子プロジェクトのチケットを作成
    • プロジェクト子へ切り替えずに済む
    • プロジェクトを細かく階層化しているなら便利そう
    • うちは極力、浅い階層に収める運用なので使い機会はなさそう
  • コメントの表示順が新しい順なら編集フォームを上に表示
    • 私はこの表示順で使用しているため、待望の機能だ
    • これまでフォームが最下段になるのは地味にストレスだった
    • 前述のプレビュー タブ化と並んで嬉しい
  • チケットリンクの新書式
    • ##123 と書くとトラッカーと題名も表示される
    • 議事録や Release Notes ページにチケット一覧を作成するなどで役立ちそう
    • いままでは普通のリンクでこれをおこなっていた
    • 普通のリンクだと題名変更などで手動追従が面倒だった、自動になるのはありがたい
  • 添付ファイルを連続プレビュー
    • プレビューに前へ次へボタンが追加
    • これらのボタンで前後移動できる
    • 画像はサムネイル表示して興味あるものだけクリックする感じだったから、プレビュー モードがあることを初めて知った
  • 添付された動画・音声ファイルの再生
    • プレビュー画面で再生可能になった
    • この流れで YouTube や Twitter 埋め込みにも対応してほしい
  • CSV エクスポート時にエンコード選択
    • CP932 以外も選択可能に
    • Excel 以外で読むため UTF-8 にできたりする
  • ユーザー一覧の CSV エクスポート
    • チーム単位をまとめてユーザー追加する際に便利そう
    • 受託などで取り引き先の関係者をまとめて追加する、という用途も考えられる
  • ガントチャート右クリックでコンテキスト メニューを表示
    • メニューからステータスや担当者の変更がおこなえる
    • ガントチャートを利用する動機づけの一助になるだろう
  • ガントチャートの表示幅リサイズ
    • ドラッグ & ドロップで変更可能になった
    • コンテキスト メニュー編集とこの機能の流れで、将来はグラフも標準でドラッグ & ドロップによる伸縮編集されることを期待する
  • マイページに活動ブロックを追加
    • マイページ、うちでは意外に使っている人がいるので喜ばれそう
  • リポジトリ画面のファイルと差分表示をタブで切り替え可能に
    • レビュー時に便利そう
    • 編集フォームやこれなど、画面遷移する箇所はタブ化を推進するのかな?
    • SPA 対応は難しくても静的に読み込んでおいたものをタブ切り替えするようにしておけば、画面遷移のストレスをなくせる
    • SPA 化の布石にもなるだろう、タブ切り替えを React や Vue のコンポーネント描画に移行すればよいので
  • シンタックス ハイライト対応言語が大幅に増えた
    • 約 20 から約 130 に
    • ライブラリーを CodeRay から Rogue へ移行した
    • Apache や nginx 設定ファイルなども対象に
    • これまで対応言語が少なすぎて指定なしにせざるを得ない場面が多々あったから非常に嬉しい
  • 動作環境の変更
    • 冒頭で触れていた環境面の話の詳細
    • MySQL 5.1 以前がサポート外に
    • PostgreSQL 9.1 以前がサポート外に
    • RHEL/CentOS 6 系は要注意
    • Ruby 2.5 対応、2.2.1 以前はサポート外
  • Redmine 4.0 は…
    • もうすぐリリース予定
    • 地味だが品質向上と小改善を重ねたバージョン

おまけ

  • Redmine に新機能が追加されるまで
    1. 誰かが redmine.org にチケットを作る
    2. 何かのきっかけ、ここで Redmine への疑問ツイートに前田氏がリプライしているスクリーンショット
    3. 誰かがパッチを書く
    4. 誰かがコミット
    5. 次期バージョンに入る
  • redmine.org のチケットは日本語 OK
    • 日本語で書いても Google 翻訳などを利用した英訳を併記してくれればよい
    • チケットを書くのが楽 (心理面でも) だし、日本人の開発者に意図が伝わりやすい
    • 私も GitHub issues で Google 翻訳に頼ることがある
    • 最近は精度もよくなってるので機械翻訳してから露骨な誤訳を手直し、というのは負担が少なくてよい

View customize 1.2.0 の紹介

View customize plugin について

  • Redmine の画面をカスタマイズ可能
  • 特定の画面に対して JavaScript や CSS を埋め込む
  • これを利用してプロジェクトのヘッダーを変更したり画面の動作を変えられる
  • Web フロントエンド部分を操作するだけ、というのがポイントで Redmine を再起動せずにカスタマイズできる
  • 参考 View customize pluginを使いこなす

v1.2.0

  • リリース内容
    • コード挿入一を選択可能に
    • ユーザーやプロジェクト情報へ JavaScript からアクセス可能に
    • ローカライズ対応、日本語リソースを追加した
    • コメント欄を追加、一覧表示でコメントがあればそちらを表示
    • 一覧をソート可能に
    • …etc
  • コード挿入位置の選択 (Insertion position)
    • Insertion position という項目を追加、コードをヘッダー以外の場所へ埋め込める
    • 挿入位置を利用した制御について紹介
    • Redmine の操作で DOM 構造が変化した際、挿入位置によっては一緒に再構築されるためデータ変更に自動で追従できる
    • 埋め込み位置が存在しないページではコード埋め込み処理がスキップされる
    • スキップを応用して Path pattern (埋め込み対象ページ) を .* で全対象にしておき、Insertion position で制御するテクニックもあり
  • ユーザーやプロジェクト情報へ JavaScript からアクセス可能に
    • Twitter でこの情報は動的 or 静的取得のどちらだろう?と書いたら静的だと教えていただいた
    • 静的ゆえリアルタイムな変更追従は無理だが実運用で困ることは滅多にないだろう
    • ViewCustomize.context から参照可能
    • 情報が増えたことにとり View customize 側を変更しなくてもユーザーの JavaScript で処理できる範囲が広がる
    • 例えばグループ情報を利用してスクリプトの適用を特定ユーザーに限定する、など
  • カスタムフィールドを使った制御
  • ユーザーのカスタムフィールド
    • ユーザー自身が情報を追加できるのは大きい
    • 他システムやサービスの token を入力して、それと連携するとか
  • ローカライズ対応
    • 日本人にとって UI などが母国語でないだけで利用時のハードルが上がる、これを解消
    • 他の言語もがんばりたい
  • 一覧をソート可能に、コメント欄を追加
    • View customize 一覧の項目にコメントがあればそれを、なければ従来どおりコードを表示するようになった
    • 説明を書く際、従来はコード冒頭にコード ドキュメントとして記述するしかなかったが、これからはコードと切り離されたコメントを管理できようになったためコードを汚さずに済む

redmine導入における効果的なヒント

導入ヒントの概要

  • マズローの欲求 5 段階説などをベースに図示
    • チームのふるまい、利用したい業務、定着までの難敵を整理
    • 難敵の解決や利用業務の定着に必要な「さくせん」を考案、ここで「とくぎ」の概要をまとめる
    • 「さくせん」に基づき「とくぎ」を詳細化
  • 前回の LT に続き、国産 RPG などでよく用いられる「さくせん」や「とくぎ」などの語を採用
  • 目的を達成する動機づけとして近年ゲーミフィケーションの引用される機会が増えた
  • ゲームに親しむものとしては、楽しみながら自然とゲーム攻略のために分析や対策を練っているもので Redmine のようなタスク管理システムも似た存在だと感じている
  • よってゲーム、特に RPG やストラテジー系シミュレーションの世界観は Redmine の理解に有効ではなかろうか?

効果的な導入に向けての研究方針

  • チームのふるまいと対象業務 = マズローの欲求 5 段階説
  • 難敵 = TOC の抵抗の 6 階層
  • さくせん = 難敵の克服、対象業務の精度・成熟度の向上と維持
  • とくぎ = 武器と防具、仲間、魔法

本編

  • マズローの欲求 5 段階説と TOC の抵抗の 6 階層について
  • 難敵を克服して対象業務の制度と熟練度をあげる
  • マズローの話
  • TOC、あとで調べる
  • 自律的ナレッジを目指すために
  • 抵抗の 6 階層について、よくある意見をまとめてみる
  • 「さくせん」と「とくぎ」の内訳
  • 心理的安全性の話
    • 心理的安全性は意図的に作るものではなく後からついてくるもの
    • チケットや Wiki に何かを書いておくと、誰かがそれを見て助けてくれる
    • これは心理的安全性を意図したものではなく、課題や問題を衆目に晒すことにより結果として助けを得られたことになる
    • このような体験が重なることで、課題は問題を自己検閲 (こんなの書いて意味あるのだろうか?的な) するよりもいっそ書き出したほうがよい = 忌憚なく出力する = 心理的安全性が確保された状態になるのではないか
  • 仲間の話
    • どういう人が関わると Redmine をうまく回せるか?
    • 職場ではここに挙げられてるような活動をしている、Redmine 管理者であり、方針の提案やヘルプもおこなう
    • 前回の私の登壇でもこのあたりの話をした
  • 人に聞くなチケットに聞け
    • いま私の職場でも課題になっている問題
    • Redmine 以外にも Slack があるため、そちらで作業依頼と相談がおこなわれる
    • Slack ならテキストな分、まだよくて口頭もかなり多い
    • 部署単位で席が近いゆえ、口頭のほうが早いというのもある
    • テキストで対話することに抵抗を持っている人が多いと感じる
    • テキストはきちんと推敲されたものにしなければ、という雰囲気
    • もっと気軽に、という話を常々しているのだけど長年の文化的なものなのでなかなか理解されない
    • プログラマーであれば BTS としての導入動機があり、チケット蓄積で過去の仕様決定やバグ修正の考察を知れるため「チケットに聞け」の利点をわかりやすく体感できるのだが…
    • これを「説明」するのではなく、なんとか「体験」させたいのがここ数年の私の課題
    • うちの場合、Wiki はよく使われているので「Wiki に聞け」は受け入れられている感じ
    • Wiki は書きっぱなし可能だが、チケットで「対話」するのに抵抗があるのだろう
  • Redmine アップデート センターはよ
    • この意見は様々な人が言及してる
    • インストールと互換検証が自動化されたうえで導入されれば、プラグインやテーマを積極採用できる
    • うちはプラグインによる環境破壊 (実際、Redmime が起動しなくなった経験を何度もしている…) を避けるため排除しているのだが、本当は導入したい
    • アップデート センターやプラグインとテーマの配布システムを構築する気がないのであれば、著名プラグイン (前述の View customize とか) を本体に取り込んでほしいものだ
    • Redine を Docker 運用すれば気軽に環境を捨てたり再構築できるため、本体・本家に頼らずプラグイン運用しやすくなるかもしれない
  • 発表速度
    • 前回のブログで速度について書いたためか、登壇後に今回の速度はどうだった?と氏に尋ねられる
    • 前回を 2 倍速としたら今回は 1.2 倍速と回答

Redmine使いが注目したJIRAの機能

JIRA のイケてる機能

  • カスタムフィルター
    • Redmine でもおなじみ、チケットなどをフィルタリングするための機能
    • ベーシック モードは Form UI を操作する、よくある形式
    • JQL という簡易スクリプトで条件式をかける
    • 複雑な UI を用意するのではなく、いっそスクリプトで対応しようというのが面白い
    • ありがちな AND と OR 以外に WAS というのがある、現在または過去にその値が設定されているか?という機能
    • スクリプトは学習コストこそ嵩むが自由度は高く、テキストなので理解していないユーザーとも共有しやすい (コピペで済む) メリットがある
  • アジャイル機能
    • かんばん
    • バックログとスプリント
    • レポート機能が強力、分析好きにはたまらないだろう、企業や大きなチームを対象としているであろう商用ソフトウェアらしさともいえる
  • イベントと通知
    • イベント = チケットの内部フック
    • イベント単位のメール通知、Redmine に比べてかなり細かく挙動を制御できるようだ
  • チケット ワークフロー
    • ステータス遷移のカスタマイズ
    • ワークフローのダイアグラム表示がよい感じ
    • Redmine のマトリクス形式も「この範疇を超えることはやるべからず」という複雑化を防ぐためのギプスとして好ましいとは思うけど、複雑にならざるを得ないならダイアグラムかスクリプトを必要とするだろう
    • 簡易的な承認フローの実装

Confluence 連携

アップデート機能

  • 標準でアドオンのインストールと更新を自動管理する仕組みが提供されている
    • アドオン登録することでサブスクリプションによる収益を期待できる
    • これはアドオンを継続的にメンテナンスする動機づけになる
    • 結果、アドオンが死ににくい
  • アドオンはマーケットプレイスで提供
  • ビジネスとして回せているらしく、もりのあさ氏の企業で導入しているアドオンは結構な額を支払っているとのこと
  • Redmine にもこうなって欲しくはあるが、大手資本とビジネス専任者がいないと企画倒れになるだろう
  • Redmine が参考にするとしたら WordPress.com あたりか

困ったところ

  • WBS が組みづらい
    • エピック、ストーリー or タスク、サブ タスクの計 3 階層まで
    • Redmine のように階層を細かく深く管理できない
  • 機能が多すぎて稼働させるまで時間がかかる
    • 「とりあえず動かす」には心理的に重い
    • Redmine だとプロジェクトの立ち上げは機能的にも心理的にも軽すぎて縛りを入れないと雑にプロジェクトを量産できる問題がある、うちも社員個人が Wiki を分けるためだけにプロジェクトを量産してて収束させるのに苦労した
    • WBS もそうだけど、ゆるさと厳しさ (縛り) のさじ加減は難しい
  • 大半はシステム管理者しか触れないため負荷が集中する
    • Redmine だとプロジェクト単位の管理者に機能管理の相当部分を委譲できるから分割統治に向く
    • 一方、運用ルールを明確にしないとプロジェクト管理者ごとに全くことなる運営をしてプロジェクト間のやりとりで問題になったりする
    • 完全な専任を立てられれば JIRA の一極集中も悪くはない
    • 私は分割統治の利点のほうが大きいと思うので Redmine 方式でルール縛りするほうが好み

ある工場の Redmine 2018 ー私が愛用しているプラグインー

最近のできごと

  • Redmine 絡みで IoT やってる
  • 前回のデモは面白かった
  • 今回のデモ、スマートフォンのロックを解除してください、ショートしました?、で失敗 (会場笑)

いいプラグインを使おう

  • プラグインを使うと魅力的な機能が入る
    • しかしバージョンアップ検証が大変
    • でもプラグインを使いたい
    • いいプラグインを使えばいい
    • プラグインの信用度をもって「いい」としている
    • 評価が高かったりちゃんとメンテされていたり
  • 使用しているプラグインの紹介
    • 今回登壇で紹介された View customize や Issue Template など
  • プラグイン使わない派の私としては色々と考えさせられた登壇
    • 私がプラグインを使わない理由は互換性と環境破壊
    • 本登壇で「いいプラグイン」とされているものなら「現在は」問題はないだろう
    • しかし「これからは」については作者に委ねられている
    • Redmine のシステムとして互換性を自動検証する仕組みがないと「作者の努力」に依存することとなり、ここが不安
    • これさえ解決すれば入れたいプラグインはいくつもある
    • WordPress プラグインの場合、自動更新、互換性の自動検証、ユーザー レビューがあるため安心して利用できる
    • Redmine として導入しやすいのは互換性の自動検証だろう、Manifest 的な設定を用意して対応バージョン範囲を明記し、それが本体と一致しないなら無効化すればよい
    • 環境破壊の問題はグループ ディスカッションでも議論した

LT

プロジェクト管理ソフトの群雄割拠をどうやって勝ち抜くか?②

  • 岩崎成記氏
  • 資料
  • リソース予約プラグイン
  • JavaScript の fullcalendar を使用
  • プラグイン開発メモ
  • Ruby on Rails 学習 400、開発 300 時間を費やす
  • Ruby on Rails 以外にも DB など広範な知識が必要
  • よい IDE 見つからず、エディタによる開発、毎回 Redmine リロード
  • テスト環境を用意するもの大変
  • プラグインではなくテーマだが動作確認は Docker がオススメ
    • Redmine コンテナを sameersbn/redmine にすれば複数バージョンも同時に試せる
    • 私は Docker Compose で sameersbn/redmine と mysql を連携して動かしてる
    • ファイル システムのマウント方法による違いのためか、Vagrant だと CSS/JS が更新されても Redmine 本体をリロードするまで反映されないが Docker は Web ブラウザーのリロードで即時反映される
    • Docker は起動と終了も高速なので気軽に動作テストできて嬉しい
  • Vagrant なら onozaty 氏の Redmine Vagrant Box シリーズがよい
    • Redmine のバージョン追従も迅速
    • Docker 移行前はこれを利用していた

あなたは、ねぎ派?ぶどう派?『JavaScriptで選択を便利に』

  • yamasaki24
  • 資料
  • Redmine の画面カスタマイズは JavaScript でおこなえる
  • 実例として複数 select box の連携をとりあげる
  • 大項目、中項目の select box がある
  • 大項目でアイテムを選ぶと中項目がそれにあわせて絞り込まれる
  • 実装の解説
  • ガントチャートのバーを動かす話、これは本体側に取り入れてほしい

Redmine本家コピー+投票サイト作成 (Python-Redmine 利用事例)

  • y503Unavailable
  • Redmine本家コピー+投票サイト作成(Python-Redmine利用事例)
  • Redmine への要求レベルは高度化する
  • Redmine 自体に手を入れず汎用言語によりユーザー自身が手を入れられるようにする
  • Python-Redmine を利用して複数 Redmine からデータをコピー
  • チケット画面に投票とタグ機能を追加
  • 作成手順と環境について
  • Redmine は VPS に Ansible で入れている
  • Python-Redmine で外部から Redmine を操作可能

基本手順の順守

  • 齋藤
  • 基本手順の順守と redmine
  • マネージメントの話
  • 議事メモ
    • 私が会議のオーナーでは似たような感じで運用している
    • いわゆる議事録ドリブン
    • 事前に課題 (あれば補足も) を箇条書きした Redmine Wiki を作成、これを議事録の候補とする
    • 事前に議事録の候補を読んでもらってから会議を実行
    • 開始は議事録の候補をプロジェクターなどで投影、課題に発言や決定事項をリアルタイムに書きながら進行
    • 司会 (オーナー) は書紀を兼ねる、エディターのスクロールがそのまま会議の進行になる
    • 司会能力とタイピング速度の両方を要求されるので難しそうだが、実際は議題を読んで各人の意見をタイピングするだけでも場が持つので司会能力はそれほど必要ない
    • 議事録の候補段階で、この登壇で示された要素を書けていれば更に楽だろう
    • 逆にこの程度は用意して事前に読んでもらう (共有してもらう) ぐらいでないと、人を集めて話しても無駄な雑談や脱線が増えるだけだとも思う
  • 課題管理
    • チケット発行基準で「発生翌日までに自分で対応可能なものは除き」というのは面白い
    • 既にチケット運用できているならよいが、これからチケット管理を取り入れるチームは工数よりも手を動かしたいだろうから心理手面で導入によいルールである
    • 私は些細なメモや考えごともチケットで、というようにチケット作成の雑さを許容して「チケット運用経験」を先に積んでもらう方法を採っている
    • チケット運用 = 起票して終了する、という経験を積んでもらってからの方がタスク管理について説明しやすいと考えている
    • なにかを学習する入門方法として経験と理論のどちらを優先するか?という話
  • 計画管理
    • トップ ダウン、ボトム アップどちらを採るか?で変わる話
    • メンテナンスの負担を考慮する、というのはよい視点

小さく始めるRedmine

  • びくんびくん氏、読み上げるだけで笑みのこぼれる命名を見習いたい
  • 小さく始めるRedmine 第15回redmine.tokyo勉強会LT資料 – Speaker Deck
  • Redmine 導入にかつて失敗している
  • 再導入にあたり気をつけたこと
  • いろいろ制限する
  • プラグインも View customize ぐらい
  • 禁止事項をひたすら列挙
  • Redmine アンチパターン、よくわかる
    • リテラシーの話をすると知識を持つ側が教条主義に陥りがちで、私もそうなることがある
    • 味方を増やすのが最優先、そのためにはリテラシーよりも具体的な方法を
    • 「具体的な方法」としてルールや入力項目が多すぎるとビビらせてしまうので、本登壇のように積極的に縛って見えるもの触れるものを減らすのは有効
    • うちはトラッカーを減らした、標準で有効になってる開始日や工数、進捗率も削除したいぐらい
    • GitHub issues + 担当者、ぐらいだと受け入れてもらいやすそう

Redmine Rest API の現在の困りごと

Redmine Community on Discord (Video Message)

  • Max Johansson 氏
  • Redmine on Discord: Intro – YouTube
  • Discord の動画メッセージ
  • 設備や通信のトラブルか、Max 氏とのオンライン対話がなかなかうまくゆかず
  • 会場から Max 氏への質問、そちらでの Redmine を取り巻く状況はどのような感じか?
    • Redmine を使っている人はあまりいない、Gitlab とか使っている
    • コミュニティを立ち上げたことで状況がかわるかもしれない
    • ボランティアでやってる、今後に期待している

今後のRedmineコミュニティの方向性について

  • akipii
  • 今後のRedmineコミュニティの方向性について #redmineT
  • コミュニティをどのように発展させるべきか?
  • 1 スタッフとしての意見
  • Redmine は日本人に向いているのでは?
  • 大阪と東京、ふたつのコミュニティが 2011 年からゆるく長く続いている
  • コミッターが JPL 氏を含めて 3 名というのは知らなかった
    • コミュニティーを拡大しても要望反映のリソース不足が問題になりそう
    • 3 名にしては非常によくやっているとは思うけど、心配

Redmine本、売ってみた。

  • たかのあきこ
  • 今回は欠席?時間がかなり押しているので登壇はスキップしてひとまずグループ ディスカッションに移行
  • 17:40 に合流、開始
  • どうやら保護者会があったそうで、そのため遅れたとのこと
  • スライドが手書きイラストになっててよい、絵が描けるのは強み
  • 本書、技術書典 5 でブースを訪れた時は売り切れていた
    • なので挨拶だけでも、と話しかけたらご厚意によりコピー本をいただいた
    • 感想は後ほど技術書典 5 感想の頒布物編としてブログに書く予定
    • 本書の感想は既に書いたのだが、他に大ボリューム本がいくつかあってなかなか記事がまとまらない…

グループ ディスカッション

Redmine テーマ開発

  • 私のほうから Redmine テーマについて議題をだす
  • redmine.tokyo 14、15 と参加したが Redmine テーマに関する話はほとんどないため
  • 今回だと Max 氏のコミュニティー話で Redmine 標準テーマのモダーン化が検討されている、というものぐらい
  • Redmine 標準テーマ以外を使っていますか?→GitHub 風テーマ (多分 makotokw/redmine-theme-gitmike) が 1 名、あと確か A1 がいて、他の人は標準テーマだった気がする
  • プラグインだと具体的な機能拡張が動機になる
  • テーマは外観が変わるだけなのと、外観の変化による違和感への抵抗により避けられているのでは?
  • 標準テーマでもそれなりな見た目なのもあるだろう
  • プラグインにも言えることだが、Redmine バージョン更新に追従できてないテーマを経験するとプラグインほどには導入動機が高くないので使用を断念するというのもありそう
  • テーマ開発の話
    • 実際に私が minimalflat2 の開発をどのようにおこなっているかデモ
    • SCSS を編集するとリアルタイムで CSS に Transpile され、Web ブラウザー表示が更新される話
    • Docker を使うと Redmine を実際に動かしながらテーマ開発できる話、こちらは Web ブラウザー自動更新できない (フック方法を検討中) ので手動更新としている

プラグインの課題

  • Redmine プラグインは専用の API を用意しておらず、直に DB や UI を操作する
  • そのため Redmine バージョン互換を意識しないと容易に環境が壊れる
  • かといって今から API を整備するか?というと難しそう
  • せめてバージョンの自動検証は実装したほうがよいのでは?
  • 既存チケットになければ私がこの案を登録するかも

anyenv + ndenv を試す

2018年11月9日 0 開発 , ,

Node 11 へ更新したら mapbox/node-sqlite3 が動作しなくなった。#1063 によれば既に修正の準備はできているものの CI サービス AppVeyor が Node 11 対応していないので待ちとなっているらしい。

これまでも node-sqlite3 のように node-gyp を利用した npm で Node バージョン更新による問題に遭遇してきたが、概ね短期間で対応された。そのため Homebrew で Node を最新バージョンにしていたのだけど、今回は 2 週間を経ても未解決である。ちょうど直近で node-sqlite3 を業務利用する機会があるため、これは困る。

また自身も npm 開発することもあって、いつかは *env 系ツールで複数 Node バージョンを検証できなくてはなぁと思っていた。Current 以外の動作テストは Travis CI に丸投げしていたが、特定 Node バージョンで問題が起きた時は環境を切り替えて検証しなければならない。というわけで今回の問題を契機に anyenv + ndenv を試すことにした。

anyenv をインストールする

riywo/anyenv の手順に従い anyenv をインストール。まずは git clone。HOME 直下に .anyenv という名前で git clone する。

$ git clone https://github.com/riywo/anyenv ~/.anyenv

次に anyenv へパスを通す。手順だと echo でプロファイル末尾に出力しているが、既存の設定を確認してからにしたいので .bash_profile を vi で開く。

$ cd
$ vi .bash_profile

内容を確認して問題なければ好みの位置 (export をまとめている箇所など) や末尾に以下を追記して保存する。

export PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"

その後、有効化。手順では exec $SHELL -l になっている。今回は .bash_profile を自身で編集したから source コマンドで読み直した。これは単に手癖の話。

$ source .bash_profile

anyenv のインストール手順は Linux や macOS を想定しているようで Windows はどうするのだろう?と思ったが、現在は WSL があるからそちらでどうぞ、ということなのかもしれない。Windows 版のインストール手順をググって見つけた WSLでWindowsにLinux開発環境を構築する – Qiita では実際そうしている。

インストールに成功したことを確認するため、anyenv の提供する *env を表示。

$ anyenv install -l
Available **envs:
  Renv
  crenv
  denv
  erlenv
  exenv
  goenv
  hsenv
  jenv
  luaenv
  ndenv
  nenv
  nodenv
  phpenv
  plenv
  pyenv
  rbenv
  sbtenv
  scalaenv
  swiftenv

無事、成功したようだ。こうして見ると対応環境が多い。今回の対象となる Node 系だけでも ndenv、nenv、nodenv の 3 種類ある。これらを個別にインストールしたり設定するのは非常に面倒なので実にありがたい。

anyenv-update をインストールする

anyenv 管理下の *env を更新するために便利なプラグイン znz/anyenv-update をインストールする。これは anyenv の README からリンクされているので公認と考えてよいだろう。

まずはインストール先となるディレクトリーを作成。anyenv の手順でパスを通してあるから、その配下に入れる。作成後、実際にディレクトリーが存在することを確認。

$ mkdir -p $(anyenv root)/plugins
$ ls $(anyenv root)
README.md   bin         completions envs        libexec     plugins     share

anyenv-update をインストールして存在を確認。

$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
$ ls $(anyenv root)/plugins
anyenv-update

これを入れると

$ anyenv update

により *env をまとめて更新できる。

Homebrew 管理下 Node を削除する

まずはグローバルな npm を確認。必要なら ndenv に移行した後で入れ直すため、名前を控えておくこと。

$ npm ls -g --depth=0
/usr/local/lib
├── asar@0.14.3
├── eslint@5.3.0
├── eslint-config-standard@11.0.0
├── eslint-config-standard-react@6.0.0
├── eslint-plugin-import@2.13.0
├── eslint-plugin-node@7.0.1
├── eslint-plugin-promise@3.8.0
├── eslint-plugin-react@7.10.0
├── eslint-plugin-standard@3.1.0
├── npm@6.4.1
└── npm-check-updates@2.14.2

次にこれらをまとめてアンインストール。その後に npm が残っていないことを確認。

$ npm uninstall npm -g
removed 387 packages in 6.033s
$ npm ls -g --depth=0
-bash: /usr/local/bin/npm: No such file or directory

Node 本体をアンインストール。その後にバージョン表示コマンドを実行して失敗 = Node 消滅を確認。

$ brew uninstall node
Uninstalling /usr/local/Cellar/node/11.1.0... (3,936 files, 47.0MB)
$ node -v
-bash: node: command not found

Homebrew 環境が壊れていないことを確認。

$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: Broken symlinks were found. Remove them with `brew prune`:
  /usr/local/share/man/man5/package-lock.json.5
  /usr/local/share/man/man7/removing-npm.7
  /usr/local/share/man/man7/semver.7

依存関係の警告が出ているので brew prune を実行、回復したことを確認。

$ brew prune
Pruned 3 symbolic links and 10 directories from /usr/local
$ brew doctor
Your system is ready to brew.

これで Homebrew 管理下 Node を削除できた。もし which node して残骸があるようなら rm コマンドなどを実行して消す。私の環境では検出されなかったから、これで終わり。

ndenv をインストールする

anyenv 経由で ndenv をインストールする。実行してみて気づいたのだが anyenv install XXXX だけでは ndenv がコマンドとして認識されず exec $SHELL -l によるシェル再起動が必要だった。

インストール後、バージョン表示して存在を確認。

$ anyenv install ndenv
$ exec $SHELL -l
$ ndenv -v
ndenv 0.4.0-4-ga339097

ndenv の提供する Node バージョンを確認。Node だけでなく io.js も管理されている。

$ ndenv install -l
Available versions:
...前略
v10.12.0
v10.13.0
v11.0.0
v11.1.0
iojs-v1.0.0
後略...

Node バージョン管理

ndenv を用意したので

  • グローバルを最新となる Node 11
  • node-sqlite3 を必要とするプロジェクトでは Node 10

という環境を構築してみる。まずは各バージョンの最新版を入れる。インストール後には ndenv rehash を実行する必要あり。

$ ndenv install v11.1.0
$ ndenv install v10.13.0
$ ndenv rehash

Node 11 をグローバルに設定してから Node と npm のバージョンを確認。

$ ndenv global v11.1.0
$ node -v
v11.1.0
$ npm -v
6.4.1

成功。ndenv では Node と npm を一緒にインストールしてくれる。

試しに簡単なプログラムを実行したり、既存プロジェクトで npm test を起動するなどしてみたところ正常に動作することを確認できた。

次は特定のプロジェクトだけ Node 10 を有効化してみる。対象となる Node プロジェクトに移動してから以下を実行。その後にバージョン確認してみる。

$ ndenv local v10.13.0
$ node -v
v10.13.0

おお、無事に Node 10 が適用されている。すごい。

ndenv help local の解説を読むと .node-version というファイルを作成して ndenv はそこに記述された Node バージョンへ切り替えているとのことだった。設定がファイルになっているため、これをリポジトリーで共有すれば ndenv を利用するユーザー間で Node バージョンを固定することも可能。よい仕組みだ。

実際、node-sqlite3 を利用している既存プロジェクトを Node 10 に固定し、正常に動作することも確認できた。

まとめ

anyenv + ndenv で自由に Node バージョンを制御できる環境を手に入れた。契機となる node-sqlite3 互換問題も解決したので満足度が高い。今回は ndenv を試したが、他の言語による開発でも役立つだろう。