ログ日記

作業ログと日記とメモ

現在見ているページに関連するRedmineのチケット一覧を表示するChrome拡張機能「Related Redmine」

Chrome拡張のページ:
https://chrome.google.com/webstore/detail/related-redmine/kmgkdpnmpjmncggngjcinmkfacbgaecj



画像は、バグったよーっていうGmailのURLに反応してチケット一覧を出す例。


設定例
https://github.com/nishimura/related-redmine
設定画面が正規表現や変数設定で初心者お断りな感じだけれど、Redmineを拡張で更にカスタマイズしようと思うような人なら問題ないよね。



過去のRedmineの記事
https://qiita.com/GEROMAX/items/85ee816f9fe6c5eb331f#subtask-list-columns-plugin
この辺とか
http://forza.cocolog-nifty.com/blog/2018/06/redmine-fe93.html
この辺の関連記事とか、結構読んでたんだけど、どうも自分の欲しいものが無いし自分の使い方はちょっと違うっぽい。
元々少人数で使っていたけど、もう今は環境が変わって一人用Redmineでやってる。


数人で使っていた頃も、具体的なやり取りは口頭やメールなどを使っていてチケット上でコミュニケーションはしていなかったし、メモ書きやまとめた文章もMediawikiGoogle Driveを使っていた。
あと何か綺麗なグラフが欲しいときは画像かPDFにして渡していて、偉い人にログインしてもらうというのはやってなかった。


そんな感じで完全なタスク管理ツールとして使っていたわけだけれども、一人になってからはオーバースペックなので利用をやめていた。
そしてしばらく経ってみて、自作ツールを作ったりしつつ、平行して進む課題がいくつもあると、やっぱり一人でもRedmineを使った方が良いと思い始める。


今は時々メール、あと基本はBacklogを使っている。
Backlogはプログラマー以外でも使いやすい便利なツールなんだけど、Gitを連携して細かく課題を分割して登録してってやると見づらくなってしまった。
コミュニケーションツールとしてBacklogを使うなら、Git連携やタスク整理は他のツールにした方が主要な会話のログが流れず使いやすいと感じた。


そんなわけで、Backlogの課題を親チケットとみなして、プログラマー以外は見ないような細かいチケット、やり取りログではなく作業ログとしてのチケットはRedmineに隔離することにした。
それで、カスタムフィールドを使ってIDやURLにリンクを付ければRedmine側からBacklogへの連携はすぐ出来る。不満ならカスタマイズもできるし。
逆の連携は、Backlog側にリンクを手動で書いたり別途連携ページを作ったり、のようなちょっと面倒な方法しか思い付かなかった。
もっと1クリックでサクッと連携したい。


という背景があって、Backlogの課題を表示中に拡張アイコンをポチッとすれば関連するRedmineのチケット一覧が出るようにした。
あとたまにメールでも別の仕事が来るので最初の画像のようにGmailにも対応できるようにした。
他にもWikiとかGithubとか決まったURLがあれば何でもいけるはず。一つのURLで複数の話題が流れるチャット系は無理かも。





Chrome拡張を初めて作ったけれど、今のJavaScriptってもう別言語になってるんだね。普段はjQueryなのでね…。
async/awaitの便利さにびっくりしたりアロー関数でthisを気にせず書いたり…。ブラウザ対応をChromeだけ考えればいいのがとてもやりやすかった。

extension の Event Page を手動で無効にする

Event Page が無効になった時のテストをしたい。

chrome.webNavigation.onReferenceFragmentUpdated.addListener

で登録した関数は、無効のときはどのように動くのか?など。


https://stackoverflow.com/questions/17808135/chrome-extension-onsuspend-is-never-called
ここに書いてあった。バックグラウンドページで

window.close();

なるほど。


ちなみにグローバル空間トップで 上記 addListener を使った場合は大抵マニュアル通りなんだけど、addListenerをsetTimeoutで挟むと登録した関数は呼び出されない。

chrome.storage.sync.get({
    options: ''
}, function(val) {
    chrome.webNavigation.onHistoryStateUpdated.addListener(callback, {url: [{urlMatches: val}]});
});

とかやると、イベントページが起動した瞬間にはcallbackは呼び出されない。

function f(){
    chrome.webNavigation.onHistoryStateUpdated.addListener(callback, {url: [{urlMatches: val}]});
};
f();

のように同期実行なら関数の中でも問題ない。


おそらく本体側で

// background pageを毎回生成
if (!this.hasFilteredListeners(patternData))
  return;

var bg = newBg();
// この時点で同期実行されたaddListenerのイベントは登録されている

for(var listener in this.getFilteredListeners(patternData)){
  listener.fire(bg, data);
  // 非同期のイベントはまだ登録されていないので実行されない
}

のようなことになっているのではないかと。
これは困った…。

Debian9にRedmineを入れるメモ

Redmineインストール

Wikiに書いてある通りにやるだけで、特に問題なくいける。バージョンは最新のものにする。
https://www.redmine.org/projects/redmine/wiki/HowTo_Install_Redmine_on_Debian_9
以前は専用ユーザー作ったりホームディレクトリのpublicに入れたりしてたけど、まぁ別に /opt でいいかなって。


ApachePHPPostgreSQLが元々入っていたサーバー
PostgreSQLは10が入っていた。本家のやつ。

apt install gcc build-essential zlib1g zlib1g-dev zlibc ruby-zip libssl-dev libyaml-dev libcurl4-openssl-dev ruby gem libapache2-mod-passenger apache2 apache2-dev libapr1-dev libxslt1-dev checkinstall libxml2-dev ruby-dev vim libmagickwand-dev imagemagick sudo rails


...

以下のパッケージが新たにインストールされます:
  apache2-dev bzip2-doc checkinstall fonts-lato gem gem-doc gem-extra
  gem-plugin-gmerlin gem-plugin-lqt gem-plugin-magick gem-plugin-v4l2
  gir1.2-freedesktop gir1.2-gdkpixbuf-2.0 gir1.2-glib-2.0 gir1.2-rsvg-2.0
  i965-va-driver imagemagick imagemagick-6.q16 liba52-0.7.4 libaacs0
  libapache2-mod-passenger libapr1-dev libaprutil1-dev libavcodec57
  libavformat57 libavutil55 libbdplus0 libbluray1 libbz2-dev
  libcairo-script-interpreter2 libcairo2-dev libcdio13 libcdt5 libcgraph6
  libchromaprint1 libcrystalhd3 libdca0 libdjvulibre-dev libdjvulibre-text
  libdjvulibre21 libdv4 libdvdnav4 libdvdread4 libexif-dev libfaad2 libflac8
  libfontconfig1-dev libfontenc1 libfreetype6-dev libftgl2 libgavl1
  libgdk-pixbuf2.0-dev libgirepository-1.0-1 libglib2.0-bin libglib2.0-dev
  libgme0 libgmerlin-avdec1 libgmp-dev libgmpxx4ldbl libgraphviz-dev libgsm1
  libgts-0.7-5 libgts-bin libgvc6 libgvc6-plugins-gtk libgvpr2 libice-dev
  libilmbase-dev libilmbase12 libjack-jackd2-0 libjbig-dev libjpeg-dev
  libjpeg62-turbo-dev libjs-coffeescript libjs-source-map libjs-uglify
  libjxr-tools libjxr0 liblcms2-dev libldap2-dev liblqr-1-0-dev liblzma-dev
  libmad0 libmagick++-6.q16-7 libmagickcore-6-arch-config
  libmagickcore-6-headers libmagickcore-6.q16-3-extra libmagickcore-6.q16-dev
  libmagickwand-6-headers libmagickwand-6.q16-dev libmagickwand-dev
  libmjpegutils-2.1-0 libmp3lame0 libmpeg2-4 libmpg123-0 libnetpbm10 libogg0
  libopenexr-dev libopenexr22 libopenjp2-7-dev libopenmpt0 libopus0
  libpathplan4 libpixman-1-dev libpng-dev libpng-tools libportaudio2
  libpostproc54 libpthread-stubs0-dev libquicktime2 librsvg2-dev libruby2.3
  libsamplerate0 libsctp-dev libshine3 libsm-dev libsnappy1v5 libsoxr0
  libspeex1 libssh-gcrypt-4 libssl-dev libssl-doc libswresample2 libswscale4
  libtheora0 libtiff5-dev libtiffxx5 libtwolame0 libutempter0 libuv1 libv4l-0
  libv4lconvert0 libva-drm1 libva-x11-1 libva1 libvdpau-va-gl1 libvdpau1
  libvorbis0a libvorbisenc2 libvorbisfile3 libvpx4 libwmf-dev libwmf0.2-7
  libx11-dev libx11-doc libx264-148 libx265-95 libxau-dev libxaw7
  libxcb-render0-dev libxcb-shm0-dev libxcb1-dev libxdmcp-dev libxdot4
  libxext-dev libxml2-dev libxmu6 libxrender-dev libxslt1-dev libxt-dev libxv1
  libxvidcore4 libxxf86dga1 libyaml-0-2 libyaml-dev libzvbi-common libzvbi0
  mesa-va-drivers mesa-vdpau-drivers netpbm nodejs passenger pkg-config
  puredata puredata-core puredata-dev puredata-doc puredata-extra puredata-gui
  puredata-utils rails rake ruby ruby-actionmailer ruby-actionpack
  ruby-actionview ruby-activejob ruby-activemodel ruby-activerecord
  ruby-activesupport ruby-arel ruby-atomic ruby-binding-of-caller
  ruby-blankslate ruby-builder ruby-bundler ruby-byebug ruby-coffee-rails
  ruby-coffee-script ruby-coffee-script-source ruby-columnize ruby-concurrent
  ruby-debug-inspector ruby-dev ruby-did-you-mean ruby-erubis ruby-execjs
  ruby-ffi ruby-globalid ruby-hike ruby-i18n ruby-jbuilder ruby-jquery-rails
  ruby-json ruby-listen ruby-loofah ruby-mail ruby-mime-types ruby-minitest
  ruby-molinillo ruby-multi-json ruby-net-http-persistent ruby-net-telnet
  ruby-nokogiri ruby-oj ruby-pkg-config ruby-polyglot ruby-power-assert
  ruby-rack ruby-rack-test ruby-rails ruby-rails-deprecated-sanitizer
  ruby-rails-dom-testing ruby-rails-html-sanitizer ruby-railties
  ruby-rb-inotify ruby-sass ruby-sass-rails ruby-sdoc ruby-spring
  ruby-sprockets ruby-sprockets-rails ruby-sqlite3 ruby-test-unit ruby-thor
  ruby-thread-safe ruby-tilt ruby-treetop ruby-turbolinks ruby-tzinfo
  ruby-uglifier ruby-web-console ruby-zip ruby2.3 ruby2.3-dev
  rubygems-integration sudo tcl tcl8.6 tk tk8.6 unzip uuid-dev va-driver-all
  vdpau-driver-all x11-utils x11proto-core-dev x11proto-input-dev
  x11proto-kb-dev x11proto-render-dev x11proto-xext-dev xbitmaps
  xorg-sgml-doctools xterm xtrans-dev zip zlibc

本当はこんな大量にパッケージを入れたくないけど…新しい版の公式debが無いので仕方あるまい。

apt install postgresql-server-dev-10

使っているのは10なので。

cd /opt
mkdir redmine
cd redmine

sudo -u postgres psql postgres
CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'your_password' NOINHERIT VALID UNTIL 'infinity';
CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;

sudo chown -R www-data:www-data /opt/redmine
sudo -u www-data bash -l
alias ls='ls --color'

wget http://www.redmine.org/releases/redmine-3.4.6.tar.gz
tar xzf redmine-3.4.6.tar.gz 

なるべく早めにrootから離脱。
"local all postgres trust" これは書かない。

cd /opt/redmine/redmine-3.4.6/config
cat > database.yml
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: your_password
^D
bundle install

rootで?
うーんやっぱり /opt じゃなくて redmine専用機じゃないなら /home の方が無難だったのかも。


www-data で。

bundle exec rake generate_secret_token
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake redmine:load_default_data


rootで

ln -s /opt/redmine/redmine-3.4.6/public/ /var/www/html/redmine

vi /etc/apache2/sites-available/redmine.example.com.conf

この辺はだいたいそのまま

<VirtualHost *:80>

ServerAdmin admin@example.com
Servername hostname
DocumentRoot /opt/redmine/redmine-3.4.6/public

ErrorLog ${APACHE_LOG_DIR}/redmine_error.log
CustomLog ${APACHE_LOG_DIR}/redmine_access.log combined


PassengerHighPerformance on
<Directory /opt/redmine/redmine-3.4.6/public>
RailsEnv production
Options -MultiViews
Require all granted
</Directory>

</VirtualHost>

ルートに配置するのでちょっと変えた。

vi /etc/apache2/mods-available/passenger.conf
<IfModule mod_passenger.c>
  PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
  PassengerDefaultRuby /usr/bin/ruby
  PassengerUser www-data
</IfModule>
a2ensite redmine.example.com
service apache2 graceful

DNSを設定して、admin:admin でログイン。

Redmineの初期設定

機能を減らす方向なのは前と同じ。
http://d.hatena.ne.jp/n314/20150626/1435298335
それに加えて、Backlog(backlog.com のこと)との手動連携を考慮する。

  • 設定
    • 全般
      • 環境に合わせる
    • 認証
    • プロジェクト
      • 「デフォルトで新しいプロジェクトは公開にする」オフ
    • チケットトラッキング
      • 進捗率の算出方法 ステータスに連動
  • ロールと権限
    • 開発者に「プロジェクトの編集」「メンバーの管理」を追加
  • カスタムフィールド
    • チケット
      • リンク「参照先」
  • トラッカー
    • 「提案場所」
      • 「進捗率」「参照先」
    • 「課題」
      • 「担当者」「対象バージョン」「親チケット」「進捗率」「説明」
  • ワークフロー
    • ステータスの遷移「開発者」「提案場所」
      • 「進行中」「解決」は使わない
    • フィールドに対する権限「開発者」「提案場所」
      • 「進捗率」読み取り専用
      • 「参照先」必須
    • フィールドに対する権限「開発者」「課題」
      • 「担当者」進行中から必須
      • 「対象バージョン」必須
      • 「親チケット」必須
      • 「進捗率」読み取り専用
  • チケットのステータス
    • 進捗率
      • 新規:空欄、進行中:10、解決:90、フィードバック:50、終了:100、却下:100


基本的に文章でのやり取りはBacklogを使い、Redmineは連携に注力する。
Backlogでやり取りをしていると、そこにGitのコミットが紛れ込んだら見づらいし、かと言ってコミットと課題の関連がなくなるのもつらい。
そういうわけで今回は、GitとBacklogの連携の間に挟むように使う。
Redmineに一本化することは機能的には可能なんだろうけども、一旦様子見。前もRedmine上ではあまりやり取りはしておらず、後から参照するための記録になっていた。仕様が不安定の状態でRedmine上でやり取りするのは向いてない気がしている。


「提案場所」はBacklogのURLを書く。今はBacklogを使っているけれども、別にChatWorkでもWikiでもGoogle Documentでも課題管理Excelの番号でもML番号でも何でも良いと思う。
ソースコードとやり取りの場所を結びつけるためのチケット。説明欄や担当者は無し。
電話とかLINEとかで来られると説明欄が無いのはつらいのかもしれない。どうしようもなさそうなのでその場合は時刻等を書く(?)

/opt/redmine/redmine-3.4.6/plugins/redmine_dmsf/extra/xapian_indexer.rb
「トラッカー」は、ワークフローとフィールドに基づいて作る。
「バグ修正」「機能追加」「設計」「実装」のようなものはワークフローとフィールドが同じなら作らない。全て「課題」で良い。


「提案場所」は新規または終了のみのステータスのみ。
「新規」の進捗率連動を空欄にすることによって、親チケットの進捗率を子チケットの集計に対応させる。


プラグインは「View Customize plugin」「Redmine Default Custom Query」「DMSF(タグ v1.6.0)」を入れた。
DMSFは権限を追加、cronなど色々必要な設定がある。


DMSFの紹介を見ていると便利そうに見えたんだけど、使ってみるとちょっと微妙かもしれない。
WebDavでファイラーで見たりdavfs2でマウントするのは微妙で、「アップロード=コミット」として履歴が更新されることを頭の隅で意識しながらじゃないとまずいかもしれない。そしてどうせ意識するならコミットコメントを入れたい、とか。
バイナリファイルを自動で詳細に管理すること自体に無理があるのかも。
ファイルをフォルダにドラッグして上書きコピーしたり、echo foo >> foo.txt とやるとファイルのバージョンが更新されるのが新鮮ではあるんだけれども、もっさりして今ネットワークアクセス中だなということを意識せざるを得ない。なのでWebDavはオフでブラウザアップロードで使うことにして、従来のファイル・文書の強化版として以外は使わない方がいいのかも。





ここまで書いて何か良い方法がないか考えつつ数日放置してたんだけど一旦終了で。

git-flowって結構使われてるんだなとブコメ見て思った

GitFlowをやめて本番リリースが楽になった話
ここ。


なんか全然想像できないんだけど、最終確認者がお客さんとか技術に詳しくない社長とか偉い人だとすると
「feature/1 作ったので http://feature1.example.com/ 見てくださいー」
「feature/2 作ったので http://feature2.example.com/ 見てくださいー。あ、ここには feature/1 は反映してないので feature/2 のことだけ考えて下さいね」
「feature/3 は http://feature3.example.com/ ですよー。あ、こっちは feature/1 マージ後の developから派生してるので feature/1 も反映済みです」
とか言って上手く行く気がしないんだが…。
「あれ?feature2は?」とか「feature1入っちゃってるよ?」とか容易に想像できるんだが…。


まず「検証」の定義が違うんだろうけど、技術者が検証しても、最終リリースに何の機能を入れるかの責任者が営業とかマーケティング寄りならやっぱり無理だよね。
マーケティング的に featrue1 は後で」とか「経理の都合でfeature2 は来月にして」とか普通にあるよね。例外的な扱いにならない頻度で。


で、そんなのにgit-flowを適用することがそもそも間違っていると言えば、それはそうなんだけど、それはつまりタイトル通りで良かったねということでは…。


ちなみに

この運用してるプロジェクトや会社は他にもあるんじゃないかと思ったけど軽く検索しただけでは見つからなかったのでまとめた。

これ同じようなフロー昔書いたんだけど http://d.hatena.ne.jp/n314/20150704/1435997678 特に名前がないので検索ではヒットしないよね。厳密にやらずゆるくやってる自覚があるので、これが最適なワークフローだ!と言うほどでもないと思ったり。featureブランチとか言わずにただのブランチって言ってるし。
masterとdevelopでできるだけシンプルにしましょうってなるとここに行き着く気がするので、結構やってる人居るんじゃないだろうか。


そもそも git-flow って小規模webに向かなくない?アプリなら分かる。あとJavaとか大規模で厳密にきっちりかっちりやるという体制なら分かる。

MacBook Pro 2017 15inch の Touch Bar が壊れた

Touch Bar の表示が三原色の横線の表示になって、ちょっと乱れたとかじゃなくて完全に表示不能になった。
VMware Fusion を使っていたときに急になって、何かバグ的なものかと思って再起動したけど直らなかった。


USBや電源を抜いて電源オフしてしばらく待ったりとかしてみたけどダメ。セーフモードもダメ。
表示は見えないけどタッチは反応するからしばらくこれで乗り切るか…と思って使っていたら、急に回復した。
3時間ぐらい諦めて使っていた。というかMacの修理とかiCloudのバックアップとか調べていたら直った。


どうせ壊れるなら一年経つ前にしてほしいところだが…。
後で写真撮っておこうと思ってたけど急に直ったから撮れず。


追記:また起きたので写真撮った。数分で元に戻ってまたバグったり…一部だけチカチカしたりもして何となくやばそう。


4/9 追記:Touch Bar の表示が完全に停止した…。

毎日差分バックアップ Mac編

http://d.hatena.ne.jp/n314/20061113/1163427268
http://d.hatena.ne.jp/n314/20061115/1163593260
http://d.hatena.ne.jp/n314/20061116/1163677384
この辺の続き。


今見て気付いたけど、Windowsのときの--link-destにネットワーク込みのパスを書いてた。そりゃダメだ。10年越しの解決(?)

Mac:~ root# cat backuptool/backup.sh 
#!/bin/bash

LANG=C

REMOTE=root@sakura:
BASEDIR=/var/local/BACKUPS/Mac
NEWDIR=`date "+%a"`
TARGET=$REMOTE$BASEDIR/$NEWDIR/
OLD=`date -v -1d "+%a"`
OPTS="-avz --delete --stats --exclude-from=/var/root/backuptool/exclude --link-dest=$BASEDIR/$OLD/"

FROM="/Users/foo /var/root"

rsync $OPTS $FROM $TARGET
# rsync -n $OPTS $FROM $TARGET

最初にバックアップ先で

mkdir Sun Mon Tue Wed Thu Fri Sat

しておく。

# cat cron.conf 
0 12 * * * /var/root/backuptool/backup.sh >> /var/root/backuptool/logs/`date "+\%Y\%m\%d\%H\%M\%S"`.log 2>&1

cronは%がコマンドの区切りのようで動かなくて少しハマった。


excludeはduで巨大なファイルを調べて書く。

:~ root# cat backuptool/exclude 
Bitcoin/
Virtual?Machines.localized/
.Trash/
Downloads/

今はこんな感じ。

MacBook Pro の初期設定のメモ その2

http://d.hatena.ne.jp/n314/20170715/1500099904 これの続き。


結局メインの作業はVMwareDebianになりそう。
そしてRealforceとKensingtonのExpert Mouseを使う。










MacBook Proは完全にディスプレイ要員になった。
ちょっとネット見る程度とかトラックパッドの操作性は断然Macが便利なんだけどね…。
フリーズの罠があるのでタブを大量に開くのはちょっと躊躇する。
https://beadored.com/chrome-mac-freeze/


かなキーをF13にしている箇所は現状諦め。
あとShift+バックスラッシュ(アンダーバー)のキーが効かないことがある。MacBook Proのハード的な問題と思ったけど、Realforceでも効かないときがあるのでmacOS的な問題っぽい。


VMwareの設定


xmodmapでEisu_toggleのcaps lockを外したり、mod1を右Altにしたり。
Macのキーのキャプチャはアプリでやるとして、Linuxはxevを使う。