Technical Memo - nomlab/octaccord GitHub Wiki
#+TITLE: Octaccord Technical Memo
#+AUTHOR:
#+EMAIL:
#+DATE:
#+OPTIONS: H:3 num:2 toc:nil
#+OPTIONS: ^:nil @:t \n:nil ::t |:t f:t TeX:t
#+OPTIONS: skip:nil
#+OPTIONS: author:t
#+OPTIONS: email:nil
#+OPTIONS: creator:nil
#+OPTIONS: timestamp:nil
#+OPTIONS: timestamps:nil
#+OPTIONS: d:nil
#+OPTIONS: tags:t
#+TEXT:
#+DESCRIPTION:
#+KEYWORDS:
#+LANGUAGE: ja
#+LATEX_CLASS: jsarticle
#+LATEX_CLASS_OPTIONS: [a4j]
# #+LATEX_HEADER: \usepackage{plain-article}
# #+LATEX_HEADER: \renewcommand\maketitle{}
# #+LATEX_HEADER: \pagestyle{empty}
# #+LaTeX: \thispagestyle{empty}
* Introduction
これまで GitHub + Redmine でプロジェクト管理をしていた.
Redmine のチケット管理は強力だが,GitHub に置いたコードとの連携が弱い.
GitHub issue でコードに関する議論やレビューをしたいので,
Redmine との行ったり来たりが面倒になる.
加えて Redmine のサーバを自前でサーバを持つのが重荷.
このさい,GitHub だけで管理できないのか.
そこで,GitHub + GitHub Wiki でプロジェクト管理を試みてみた.
足りない部分を支援する簡単な CLI ツールを作成した.
* Related Works
GitHub によるプロジェクト管理についての既存の試み.
+ [[https://guides.github.com/introduction/desktop/][Getting your project on GitHub (Github Official Guide)]]
+ [[https://huboard.com/][Huboard - GitHub issues made awesome]]
+ https://github.com/rauhryan/huboard
+ [[http://www.lullabot.com/blog/article/managing-projects-github][Managing Projects with GitHub | Lullabot]]
+ [[http://awebfactory.com/node/474][Github itself for Agile Project Management madness!]]
+ [[https://github.com/yuroyoro/git-issue][Github: yuroyoro/git-issue]]
共通としているところは,
+ Milestone を Scrum の Sprint として活用
+ Product Backlog (PBL) をどう管理するのかは曖昧.別途ツールを用意している? (Excel や Google Docs)
GitHub + Wiki だけで困りそうな事は,
+ PBL の (優先順位) の管理
+ Github Wik の貧弱さ
* GitHub の問題点
** Task (issue) の状態管理
+ Todo, Doing, Done
+ 締切,進捗(パーセント),コスト(負荷)
** 統計情報の提示
+ 各人の抱えている issue 数(負荷)
+ 各人のこなした issue 数
+ 現状のグラフは,モチベーション向上につながっていないのではないか
** Issue の自動分類
スマートフォルダのようなイメージ.
以下のような issue を瞬時にリストアップできるようにラベルを自動で貼る.
+ 最近更新がない
+ 重要 (基準は,まだ曖昧 comment の量が多いなど?)
+ プルリクエスト(PR)が付いている
+ 階層の上(下)にある
+ 今イテレーションで解決が必要
+ 締切に遅れている
+ プロダクトバックログに入るべき
** Issue の並べ変え(優先順位付け)
現状存在するのは,
+ newest, oldest, recently updated, least recently updated, most commented, least commented
他にもあると便利そうなのは,
+ 期限が迫っている順
+ プルリクエスト (PR) が付いている順
+ 任意の順番の定義 (Product Backlog を issue で管理するなら必須)
** Issue と PR の関係を提示
+ 現状のインタフェースでは,話の流れを追いかけ辛い
+ PR が付いている元 issue の一覧
+ rails/rails の attached PR というラベルが,それを指向していたように見えるが,管理されていない
+ Issue 間のグラフを見る → 檀上のテーマの一部
** 議事録作成支援
+ 会議中に issue について付いたコメントの一覧を
イテレーション記録として wiki に残したい
** プロダクトバックログ (PBL) の管理
+ 特定のラベルの付いた issue を PBL とみなす?
* 対処
** PBL Issue 一覧を取得して PBL Wiki Page を自動作成する
*** コマンド書式
#+BEGIN_SRC shell-script
octaccord backlog nomlab/LastNote --label=PBL --replace LastNote.wiki/Product-Backlog.md
#+END_SRC
*** 出力結果
Product-Backlog.md 中の
#+BEGIN_EXAMPLE
<!-- octaccord:begin backlog -->
...
<!-- octaccord:end backlog -->
#+END_EXAMPLE
で囲まれた部分に,プロダクトバックログのテーブルを埋める.書式は,以下の通り.
| No. | Title | Story | Demo | Cost |
|------+----------------+-------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------|
| #100 | 招待機能の実装 | メンバとして,ML にメールを投げることでイベントの出欠を簡単に取りたい.それは,イベントの開催を活発にしたいからである. | gn メーリングリストに送信する際にアドレス末尾に「+inv」と追記して送信すると,LastNote 上に対応するイベント参加者一覧のページが作成される.メンバに届いたメール本文には,イベント出欠を返答するリンクが付いている.出席/欠席のどちらかをクリックすると,出欠一覧ページに出欠状況として名前が反映される. | 5 |
+ No :: PBL Issue の番号 =[#100](../issues/100)= のように Issue へのリンクにする.
+ Title :: PBL Issue のタイトル
+ Story :: PBL Issue の記述中の =# Story= 以下の記述を抜き出してきたもの
+ Demo :: PBL Issue の記述中の =# Demo= 以下の記述を抜き出してきたもの
+ Cost :: 実装するのにかかるコストを示す整数(空欄でよい)
ただし,既にテーブルがある場合は,以下の状態を保存する
+ No. と Cost の値
+ ソート順
既存の既にテーブルになかった新規の PBL Issue は,末尾に追記する.
** 指定された PBL Issue の内容から Task Issue を作成する
*** コマンド書式
#+BEGIN_SRC shell-script
octaccord create-task nomlab/LastNote --label=PBL --add-label=Itr0094 100 111 ...
#+END_SRC
1) 各引数の PBL Issue について
2) description か comment から =# Tasks= 以下の項目を抜き出す
(末尾の =# Tasks= を優先する)
3) 子要素である各 =## title...= 項目を Task Issue として新規作成する.
4) Task Issue の本文中に,元となる PBL Issue への参照を入れる.(#100 のように)
5) 元となる Issue の =# Task= 以下の =## title...= 部分を
=## #150 title...= のように置き換えておく.
6) 2度,同じ操作をしても,新規に作成しないように, title 部分が =#番号=
で始まる部分は,無視すること.
7) =-add-label= で指定された label を作成した Task Issue に付けること.
** Floating Issue を発見してラベルを付ける
*** Story
+ マネージャが,重要なラベルの付いていない Task Issue にラベルを付けたい.
それは,棚卸すべき Task Issue が何であるかを素早く確認したいからである.
*** コマンド書式
#+BEGIN_SRC shell-script
octaccord update-label nomlab/LastNote --search='!label:/^[A-Z]/' --label=Floating
# 現状,こう書けば一応できる?↓
octaccord scan nomlab/sandbox --search="no:milestone -label:PBL" --format=number |\
xargs octaccord update_issues nomlab/sandbox --labels=Floating
#+END_SRC
1) 大文字で始まるラベルは,排他的に付けられることが前提
2) 全ての Issue について, =--search= 式にマッチした Issue のみに
=--label= で指定されたラベルを付与する.
3) つまり,マッチしなかった Issue からは,ラベルをはがすことも必要.
** 検索式に一致する Issue を列挙する (未完)
*** コマンド書式
#+BEGIN_SRC shell-script
octaccord issues nomlab/LastNote --search="!label:"
#+END_SRC
+ ある時刻の範囲でアップデートがあった
+ ある時刻の範囲で作成された
+ あるラベルにマッチする/しない
+ オープン/クローズの別
** Wiki Page 中の Issue 番号に反応して最新の情報を付与する
*** コマンド書式
#+BEGIN_SRC shell-script
octaccord embed-issue-info nomlab/LastNote --replace Itr0094.md
#+END_SRC
Wiki のページ中に現れる =#番号= の記述をスキャンして,
リンクやタイトルを付与する.
+ =#番号= の記述にリンクを付与して, =[#番号](../issues/番号)= の記述に置き換える
+ 行頭の =*= や =#= の直後に来る場合は後ろに Issue のタイトルも追加する
この機能によって,Wiki 中に
#+BEGIN_EXAMPLE
,* #150
#+END_EXAMPLE
とだけ書いておけば,リンクとタイトルが付いた記述に置き換えられる.
#+BEGIN_EXAMPLE
,* =[#番号](../issues/番号)= カレンダをまたぐリカーレンスを作成できないようにする
#+END_EXAMPLE
* 付けるべきラベルの一覧
PR には,ラベルを PRは, issue の付属物として見る.
大文字で始まるラベルは排他的にしかつかない.
+ PBL ::
プロダクトバックログ相当の issue に付けるラベル.
各イテレーションの開始時の会議で付けられる.
octaccord は,PBL Wiki に当該 issue を追加する.
+ ItrXXXX ::
イテレーション内で消化すべき issue に付けるラベル.
各イテレーションの開始時の会議で付けられる.
(Scrumでいうスプリントバックログ)
同一の名前でマイルストーンが設定される.
close されたものから,自動的に剥されていく.
マイルストーンの期間が過ぎると label は消滅する.
+ Floating :: PBL でも Itr のどちらも付いていない issue.
+ pullrequest :: レビューが必要な (PRが付いた) issue
+ incomming :: 前イテレーション中に付いた新規の issue
+ updated :: 今Itrで更新されたため,議論が必要なissue
+ unbound PR :: どの issue にも関連しない PR
+ stale :: 一定期間更新のない issue
* ラベル付けの手順
** 状態に関するラベル (PBL, ItrXXXX, Floating)
全ての open issue について
1) pull_request なら,終了
2) label:PBL なら,終了
3) label:Itr???? を全部剥がす
octaccord label --search="type:issue -label:PBL" --remove="^Itr.*" --add="%milestone||Floating"
4) ms:Itr???? なら,同名の label を付け終了
5) label:Floating を付け終了
全ての open issue について
1) created: ItrXXXX の Due Date の後で ItrYYYY の Due Date より前なら,label:incoming を付ける
octaccord label --search="created:<{-7days}" --add="incoming" --exclusive
2) updated: が 1ヶ月前以上なら label:stale
octaccord label --search="updated:<{-30days}" --add="stale" --exclusive
3) 他の pull_request の body 中に自身の issue 番号があるなら, mentioned を付ける
octaccord label --search="mentioned" --add="mentioned" --exclusive
4) pull_request で,どの issue にも言及していないなら,unbound を付ける
octaccord label --search="type:pr is:referred" --add="unbound" --exclusive
* 人間によるラベルの処理
** PBLの処理
+ User Story を最初に述べる
+ Tasks から始まる章は Issue にする
+ Issue を作成したら, Issue 名の後ろに作成した Issue 番号を追記する
+ 作成する Issue から,基となる PBL の Issue を reference する.
** Issue を Review 後の処遇
+ 次のItr番号を付与.
+ プロダクトバックログ化
+ close
+ Itr番号を単に外す.
* 勉強
** GitHub API
*** 参考URL
+ https://developer.github.com/guides/ (まずこれを読む)
+ https://developer.github.com/v3/ (API リファレンス)
+ https://help.github.com/categories/78/articles (search)
+ https://developer.github.com/v3/markdown/ (Markdown レンダラ)
API のクライアント実装
+ https://github.com/octokit/octokit.rb
+ https://github.com/lostisland/sawyer/blob/master/lib/sawyer/resource.rb
+ https://github.com/plataformatec/faraday-http-cache
*** issue と pull の違い
#+BEGIN_SRC shell-script
# issues として取得
curl -s -i -u yoshinari-nomura https://api.github.com/repos/nomlab/LastNote/issues/113 > attic/i113
# PR として取得
curl -s -i -u yoshinari-nomura https://api.github.com/repos/nomlab/LastNote/pulls/113 > attic/p113
#+END_SRC
両者は,同じモノのようだが,返って来る情報が違う
+ ETag は,両者で異なる (これは当然)
+ id が両者で異なる (これは意外)
+ body は,同期している
以下は,issue にしかない
+ labels
+ events
一方,merge や commit 関連の情報は pulls にしかない.
また,HTML URL を開くと,pull にリダイレクトされる.
https://github.com/nomlab/LastNote/issues/113 は
https://github.com/nomlab/LastNote/pull/113 へリダイレクトされる
*** issue の updated_at は,いつ変化するのか
+ label を付けかえるだけで変化する
+ comment の変更でも変化する
+ タイムスタンプを頼りに何かをするのは,難しそうだ
issue に関する議論は,コメントで付けて,会議の議事録に抜き出して Wikiに追記するのは,
抜き出す基準が時刻になるので,難しい.その場でならいいが,後日抜こうとするとダメ
かといって,issue コメントに会議の場で付いたコメントを示すマークを付けるのは,面倒だ.
*** 検索
+ https://help.github.com/articles/search-syntax
+ https://help.github.com/categories/78/articles
+ https://developer.github.com/v3/search/
API では,「PBLラベルを含まない」に対応するのは =-label:PBL= のように =-= を付ける
#+BEGIN_SRC shell-script
curl -s -u yoshinari-nomura 'https://api.github.com/search/issues?q=Tasks+label:PBL+-label:management+repo:nomlab/LastNote'| less
#+END_SRC
なぜか,issue のコメント欄が検索にヒットしない.
https://help.github.com/articles/searching-issues#search-in
の =in:comment= がうまく働かない?
#+BEGIN_SRC shell-script
curl -s -u yoshinari-nomura 'https://api.github.com/search/issues?q=Tasks+label:PBL+repo:nomlab/LastNote+in:comment'| less
#+END_SRC
** Github Wiki (Markdown)
+ https://guides.github.com/features/mastering-markdown/
+ https://help.github.com/articles/github-flavored-markdown
+ https://github.com/gollum/gollum/wiki
+ https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
+ http://www.emoji-cheat-sheet.com/
** Octkit
https://github.com/octokit/octokit.rb
** 用語
**** Elevator Pitch
エレベーター(elevator)に乗っている間に説明(pitch)できるような売り文句.
たとえば,
*このシステムは,[]したい[]向けの[]という名前のシステムは,[]です.これは,[]ができ,[]とは違って,[]が備わっています.*
のような短かい文言.
**** Product Backlog
+ 製品で実現すべき機能の一覧に優先順位を付けたもの
+ 常に更新や追加され,順番の並べ変えが置こる
+ 各項目にコストの項目が付く
+ コストは具体的に作業が想像しやすいものを基準にして相対的に値を付ける
+ フィボナッチ数で相対値を決めることで,微妙な数の違いを付けられなくするとよい
大きな違いを発見することで,分割すべきかどうかの判断の助けとなる.
+ ユーザストーリーの形で書くことが多い
**** スプリント
+ イテレーションとほぼ同義
+ 最長1ヶ月程度の期間
+ 計画,設計,開発,テストのプロダクトのリリース判断に必要な内容を実施する.
+ 期間は,延長しない.タイムボックスを守る(短縮は,可能).