I love the “Unix way” of work: specified tools that can be used together to build a powerfull environment. I’ve been using this approach to almost everything, including project management on Coderockr. We use some Scrum and Kanban ideas, such as sprints, story points, task boards, burndown chart, daily meetings, and so on. And to manage all this aspects we use different tools:

Trello to manage task boards and sprints. We use a Firefox/Chrome extension called Scrum for Trello :

Github to host code and issues

And we use Google Docs to create burndown charts:

Everything works fine, but i realize that some team members prefer to use Github issues to manage their tasks, not using Trello’s boards. So, we can remove Trello and use Github only to manage the scrum project, using this logic:

every sprint became a milestone on Github;

every task on backlog became an issue on Github;

every story point became a label, that can be attached to an issue;

Creating the labels:

Creating the milestones:

Every milestone can have a due date, the same as a sprint. And we can follow the sprint status using this same view.

Now we can create our issues, choose the labels and allocate them to the milestones.

But removing Trello we missed your coolest feature: the visual task boards. We can solve this including another tool: ZenHub. ZenHub is a Chrome extension that add some new features to Github, including a task board similar to that provided by Trello.

In you first access to your repository, after installing ZenHub, you can choose a task board configuration:

We are using this:

Now we can easily move the issues between the boards.

And we can use Github’s API to build statistics and reports, burndown charts, and so on. I created a small PHP script to test, using php-github-api:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 <? php require_once 'vendor/autoload.php' ; if ( $argc < 2 ) { echo "Usage: php index.php ProjectName

" ; exit ; } $projectName = $argv [ 1 ]; $client = new \Github\Client ( new \Github\HttpClient\CachedHttpClient ( array ( 'cache_dir' => '/tmp/github-api-cache' )) ); $client -> authenticate ( 'username' , 'password' , \Github\Client :: AUTH_HTTP_PASSWORD ); //get sprints $sprints = array (); $milestones = $client -> api ( 'issue' ) -> milestones () -> all ( 'coderockr' , $projectName , array ( 'direction' => 'asc' )); foreach ( $milestones as $m ) { $sprints [ $m [ 'id' ]] = array ( 'name' => $m [ 'title' ], 'open_issues' => $m [ 'open_issues' ], 'closed_issues' => $m [ 'closed_issues' ], 'state' => $m [ 'state' ], 'due_on' => $m [ 'due_on' ], 'open_points' => 0 , 'closed_points' => 0 , ); } //get issues $issues = array_merge ( $client -> api ( 'issue' ) -> all ( 'coderockr' , $projectName , array ( 'state' => 'open' )), $client -> api ( 'issue' ) -> all ( 'coderockr' , $projectName , array ( 'state' => 'closed' )) ); //update sprint points foreach ( $issues as $i ) { $milestone = $i [ 'milestone' ]; switch ( $i [ 'state' ]) { case 'open' : $open_points = $sprints [ $milestone [ 'id' ]][ 'open_points' ]; foreach ( $i [ 'labels' ] as $l ) { $open_points += ( float ) $l [ 'name' ]; } $sprints [ $milestone [ 'id' ]][ 'open_points' ] = $open_points ; break ; case 'closed' : $closed_points = $sprints [ $milestone [ 'id' ]][ 'closed_points' ]; foreach ( $i [ 'labels' ] as $l ) { $closed_points += ( float ) $l [ 'name' ]; } $sprints [ $milestone [ 'id' ]][ 'closed_points' ] = $closed_points ; break ; } } //show sprint's details $total_open_points = 0 ; $total_closed_points = 0 ; foreach ( $sprints as $s ) { $sprint_points = $s [ 'open_points' ] + $s [ 'closed_points' ]; $sprint_issues = $s [ 'open_issues' ] + $s [ 'closed_issues' ]; echo " { $s [ 'name' ] } due on { $s [ 'due_on' ] } has { $s [ 'closed_issues' ] } closed of { $sprint_issues } issues and { $s [ 'closed_points' ] } closed of { $sprint_points } points

" ; $total_open_points += $s [ 'open_points' ]; $total_closed_points += $s [ 'closed_points' ]; } //show project's details $project_points = $total_open_points + $total_closed_points ; echo "Project have { $total_closed_points } closed of { $project_points } points

" ;

Executing the script:

eminetto@MacBook-Pro-de-Elton ~/Documents/Projects/GitHubPM: php index.php ProjectTemplate Sprint 1 due on 2014-01-09T08:00:00Z has 1 closed of 3 issues and 2 closed of 28 points Sprint 2 due on 2014-01-16T08:00:00Z has 1 closed of 2 issues and 3 closed of 11 points Sprint 3 due on 2014-01-23T08:00:00Z has 0 closed of 2 issues and 0 closed of 3.5 points Sprint 4 due on 2014-01-30T08:00:00Z has 0 closed of 1 issues and 0 closed of 3 points Project have 5 closed of 45.5 points eminetto@MacBook-Pro-de-Elton ~/Documents/Projects/GitHubPM:

We just started using this approach and a lot of changes can happen on next projects, but i believe this can save some project management headaches.