An easy to use burndown chart generator for GitHub Project Boards.

Overview

Burndown Chart for GitHub Projects

An easy to use burndown chart generator for GitHub Project Boards.

Table of Contents

Features

  • Create a burndown chart for a GitHub Project Board.
  • Works for private repositories.
  • Includes a trend line for the current sprint.
  • Supports custom labels for tracking points for issues

Assumptions

This tool, while flexible, makes the following assumptions about your project management workflow:

  • You use one and only one GitHub Project Board for each of your Sprints
  • You use one and only one GitHub Milestone for each of your User Stories
  • You use one and only one GitHub Issue for each of your Sprint Backlog Items/Tasks
  • Each of your GitHub Issues has a label indicating how many points its corresponding task is worth.
    • Furthermore, all labels that indicate point values have the format <prefix><int>.
    • However, multiple labels indicating points on the same Issue are supported.
  • A Sprint Backlog Task is considered Done if its corresponding GitHub Issue is Closed.

Installation

0. Clone this repository

git clone https://github.com/jhale1805/github-projects-burndown-chart.git
cd github-projects-burndown-chart

1. Create a virtual environment

python -m venv ./venv

2. Activate the virtual environment

Linux/Mac OS

source venv/bin/activate

Windows (Powershell)

.\venv\Scripts\activate

Windows (Command Prompt)

.\venv\Scripts\activate.bat

3. Install the dependencies

pip install -r requirements.txt

Usage

  1. Create a Personal Access Token with the repo scope.
    • Do not share this token with anyone! It gives the bearer full control over all private repositories you have access to!
    • This is required to pull the Project Board data from GitHub's GraphQL API.
  2. Make a copy of src/config/secrets.json.dist without the .dist ending.
    • This allows the .gitignore to exclude your secrets.json from being accidentally committed.
  3. Fill out the github_token with your newly created Personal Access Token.
  4. Make a copy of src/config/config.json.dist without the .dist ending.
    • This allows the .gitignore to exclude your config.json from being accidentally committed.
  5. Fill out all the configuration settings
    • repo_owner: The username of the owner of the repo.
      • For example, jhale1805
    • repo_name: The name of the repo.
      • For example, github-projects-burndown-chart
    • project_number: The id of the project for which you want to generate a burndown chart. This is found in the URL when looking at the project board on GitHub.
    • sprint_start_date: The first day of the sprint. Formatted as YYYY-MM-DD.
      • Must be entered here since GitHub Project Boards don't have an assigned start/end date.
      • For example, 2021-10-08
    • sprint_end_date: The last day of the sprint. Formatted as YYYY-MM-DD.
      • Must be entered here since GitHub Project Boards don't have an assigned start/end date.
      • For example, 2021-10-22
    • points_label: The prefix for issue labels containing the point value of the issue. Removing this prefix must leave just an integer.
      • For example: Points: (with the space)
  6. Run python src/main.py to generate the burndown chart.
    • This will pop up an interactive window containing the burndown chart, including a button for saving it as a picture.

Contributing

Contributions are welcome via a Pull Request.

The Legal Part

By submitting a contribution, you are agreeing that the full contents of your contribution will be subject to the license terms governing this repository, and you are affirming that you have the legal right to subject your contribution to these terms.

About

This project was first created by Joseph Hale (@jhale1805) and Jacob Janes (@jgjanes) to facilitate their coursework in the BS Software Engineering degree program at Arizona State University.

We hope it will be especially useful to other students in computing-related fields.

Comments
  • Support for projects in organizations

    Support for projects in organizations

    I renamed repo_owner to username, so the terminology would fit these changes. This is a breaking change!

    Also, I made it so that the tool looks for an organization if repo_name is left empty. Unfortunately, users may have to read the docs to understand this. Feel free to make suggestions or contributions for this.

    I have updated the docs to reflect these changes.

    Closes #14

    opened by Seldom-SE 2
  • [enhancement] Allow partial point awards when cards are moved to

    [enhancement] Allow partial point awards when cards are moved to "In Progress" and "In Review"

    It would be nice if there were an option for part of the points to be awarded as the card starts moving through the project board.

    Some sensible defaults would be to award 50% of the points when a task moves to "In Progress" and 75% of the points when the task is "In Review", however this should be customizable in the per-project settings. There will also need to be a way for users to specify which columns are "In Progress" or "In Review", again per project.

    Other considerations:

    • If a task goes back to "In Progress" after a review requested changes, then the point award for "In Review" should still stay as long as the task was in that column, but as soon as the task goes back to "In Progress" the point award will drop until the task is again "In Review"
      • This could be implemented within the card using a points_completed_as_of(date) function.
    opened by thehale 0
  • Improve date handling

    Improve date handling

    This project was processing dates without proper consideration of their timezones. As such, several bizarre errors errors were happening, especially around the start and end of a sprint.

    For example, issues closed at 6pm Arizona time on the last day of the sprint were not having their points credited to that day on the burndown chart because GitHub returned that closed date as 1am UTC the following day.

    This project now processes all dates internally using UTC. The sprint_start_date and sprint_end_date are assumed to be at 00:00:00 local time, and the final burndown chart is rendered in local time.

    These changes fix #17 and fix #21

    opened by thehale 0
  • [bug] Issues closed at the end of a sprint don't get marked as completed

    [bug] Issues closed at the end of a sprint don't get marked as completed

    GitHub stores issue create/close dates in UTC, but this project often uses the local time of the user running it. Ignoring timezone info, this often means that the GitHub create/close dates appear in the future, which can cause problems like the one reported in #17 or this one where closed issues weren't getting counted in point totals because their UTC time make it look like they closed the day after.

    Handling of time needs to work better to cover these edge cases.

    opened by thehale 0
  • Add the ability to save multiple project configs in the config.json

    Add the ability to save multiple project configs in the config.json

    I am often working on tasks for or overseeing multiple different projects. I'd like to have a way to save all of the configurations for each project and easily switch between them without having to change out the config.json file each time I want to look at a different project's burndown chart.

    opened by thehale 0
  • [bug] `KeyError: 'DATE'` when DATE is outside of the sprint start/end date

    [bug] `KeyError: 'DATE'` when DATE is outside of the sprint start/end date

    The program simply crashes when the closedDate of an issue card falls before the sprint_start_date or after the sprint_end_date from the config.

    There needs to be a guard to make sure the closedDate is within the bounds of the sprint before attempting to mark its points for a specific day.

    opened by thehale 0
  • [enhancement] Support for issues without points

    [enhancement] Support for issues without points

    The repo that I'm using this for does not have point values assigned to its issues, which renders the tool unusable. I would like to add support for this. I propose one of the following solutions:

    1. Issues without point labels have a default point value of 1
    2. If points_label in the config is blank, points are not parsed, and the chart is updated to use the term, "issues" instead of "points"
    3. Add some other value to the config that determines whether issues or points are measured

    Any feedback would be appreciated.

    opened by Seldom-SE 0
  • Example task #5

    Example task #5

    A task created to make the demo burndown chart look more realistic.

    This particular task illustrates the ability to sum up points from multiple points labels.

    Points: 1 Points: 3 
    opened by thehale 0
  • Error when generating a burndown chart for the new GitHub Projects in an Organization

    Error when generating a burndown chart for the new GitHub Projects in an Organization

    I am having the following exception when using this application with a private organization:

    Traceback (most recent call last):
      File "main.py", line 58, in <module>
        project = download_project_data(args)
      File "main.py", line 29, in download_project_data
        project: Project = get_organization_project()
      File "/Code/github-projects-burndown-chart/src/github_projects_burndown_chart/gh/api_wrapper.py", line 32, in get_organization_project
        return Project(project_data)
      File "/Code/github-projects-burndown-chart/src/github_projects_burndown_chart/gh/project.py", line 9, in __init__
        self.name = project_data['name']
    TypeError: 'NoneType' object is not subscriptable
    

    Any idea on what might be going wrong?

    Upon some investigation I discovered that the culprit seems to be this request to the GitHub GraphQL API (organization name redacted):

    {
       "query":"query OrganizationProject($organization_name: String!, $project_number: Int!, $column_count: Int!, $max_cards_per_column_count: Int!, $labels_per_issue_count: Int!) {\n  organization(login: $organization_name) {\n    project(number: $project_number) {\n      name\n      columns(first: $column_count) {\n        nodes {\n          name\n          cards(first: $max_cards_per_column_count) {\n            nodes {\n              id\n              note\n              state\n              content {\n                ... on Issue {\n                  title\n                  timelineItems(first: 20, itemTypes: [ASSIGNED_EVENT]) {\n                    nodes {\n                      __typename\n                      ... on AssignedEvent {\n                        createdAt\n                      }\n                    }\n                  }\n                  createdAt\n                  closedAt\n                  labels(first: $labels_per_issue_count) {\n                    nodes {\n                      name\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}",
       "variables":{
          "organization_name":"<my org name>",
          "project_number":1,
          "column_count":5,
          "max_cards_per_column_count":50,
          "labels_per_issue_count":5
       }
    }
    

    Which is returning the following (request-id redacted):

    Headers:

    {
       "Server":"GitHub.com",
       "Date":"Fri, 11 Nov 2022 10:54:30 GMT",
       "Content-Type":"application/json; charset=utf-8",
       "Transfer-Encoding":"chunked",
       "X-OAuth-Scopes":"admin:org, project, repo",
       "X-Accepted-OAuth-Scopes":"repo",
       "github-authentication-token-expiration":"2023-02-05 10:43:50 UTC",
       "X-GitHub-Media-Type":"github.v4; format=json",
       "X-RateLimit-Limit":"5000",
       "X-RateLimit-Remaining":"4994",
       "X-RateLimit-Reset":"1668167670",
       "X-RateLimit-Used":"6",
       "X-RateLimit-Resource":"graphql",
       "Access-Control-Expose-Headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset",
       "Access-Control-Allow-Origin":"*",
       "Strict-Transport-Security":"max-age=31536000; includeSubdomains; preload",
       "X-Frame-Options":"deny",
       "X-Content-Type-Options":"nosniff",
       "X-XSS-Protection":"0",
       "Referrer-Policy":"origin-when-cross-origin, strict-origin-when-cross-origin",
       "Content-Security-Policy":"default-src 'none'",
       "Vary":"Accept-Encoding, Accept, X-Requested-With",
       "Content-Encoding":"gzip",
       "X-GitHub-Request-Id":"<some id>"
    }
    

    Content:

    b'{"data":{"organization":{"project":null}}}'
    
    bug 
    opened by filipefigcorreia 4
  • Add a chart showing per-contributor points breakdowns

    Add a chart showing per-contributor points breakdowns

    It would be really nice to have a chart that showed the relative amount of work put in by each contributor over the course of a sprint. This feature can start with a simple chart showing total points completed per contributor (the blue line), and future versions can support showing additional bars (stacked even?) for different types of tasks.

    It would also be great to support splitting points between multiple people who contributed to a single task, but that doesn't have to come immediately. unknown

    enhancement 
    opened by thehale 0
  • Provide warning if `points_label` is specified, but doesn't match any labels on an issue

    Provide warning if `points_label` is specified, but doesn't match any labels on an issue

    I just tried to pull a burndown chart for one of my active projects and got a flat line at 0, but no errors. By debugging the code I realized that my points_label setting was wrong (case sensitive issue - potentially another issue) so none of the point values were getting read.

    Better checks here would make for a better user experience.

    enhancement 
    opened by thehale 0
Releases(v1.4.0)
  • v1.4.0(Jan 23, 2022)

    What's Changed

    • Add support for custom point calculators by @jhale1805 in https://github.com/jhale1805/github-projects-burndown-chart/pull/23

    Full Changelog: https://github.com/jhale1805/github-projects-burndown-chart/compare/v1.3.0...v1.4.0

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Nov 6, 2021)

    What's Changed

    • Add support for Discord Webhooks by @jhale1805 in https://github.com/jhale1805/github-projects-burndown-chart/pull/25

    Full Changelog: https://github.com/jhale1805/github-projects-burndown-chart/compare/v1.2.0...v1.3.0

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Nov 2, 2021)

    What's Changed

    • Simplify Makefile commands + add optional chart_end_date setting by @jhale1805 in https://github.com/jhale1805/github-projects-burndown-chart/pull/24

    Full Changelog: https://github.com/jhale1805/github-projects-burndown-chart/compare/v1.1.1...v1.2.0

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Oct 22, 2021)

    What's Changed

    • Improve date handling by @jhale1805 in https://github.com/jhale1805/github-projects-burndown-chart/pull/22

    Full Changelog: https://github.com/jhale1805/github-projects-burndown-chart/compare/v1.1.0...v1.1.1

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Oct 17, 2021)

    New Features:

    • Burndown charts can now be generated for Organization Projects.
    • Multiple Project configurations can now be saved simultaneously to make it faster to generate burndown charts for multiple frequently visited projects.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Oct 8, 2021)

    This is the first release of the GitHub Projects Burndown Chart!

    Within a few minutes you can have the entire projected installed and setup, ready for you to start generating Burndown Charts for all your GitHub Project Boards!

    See the project README.md for instructions.

    Source code(tar.gz)
    Source code(zip)
Owner
Joseph Hale
Software Engineering major at Barrett, the Honors College, Arizona State University. Graduating in May 2022. ¡Hablo español!
Joseph Hale
A TileDB backend for xarray.

TileDB-xarray This library provides a backend engine to xarray using the TileDB Storage Engine. Example usage: import xarray as xr dataset = xr.open_d

TileDB, Inc. 14 Jun 02, 2021
Pglive - Pglive package adds support for thread-safe live plotting to pyqtgraph

Live pyqtgraph plot Pglive package adds support for thread-safe live plotting to

Martin Domaracký 15 Dec 10, 2022
Create Badges with stats of Scratch User, Project and Studio. Use those badges in Github readmes, etc.

Scratch-Stats-Badge Create customized Badges with stats of Scratch User, Studio or Project. Use those badges in Github readmes, etc. Examples Document

Siddhesh Chavan 5 Aug 28, 2022
Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js

pivottablejs: the Python module Drag’n’drop Pivot Tables and Charts for Jupyter/IPython Notebook, care of PivotTable.js Installation pip install pivot

Nicolas Kruchten 512 Dec 26, 2022
Script to create an animated data visualisation for categorical timeseries data - GIF choropleth map with annotations.

choropleth_ldn Simple script to create a chloropleth map of London with categorical timeseries data. The script in main.py creates a gif of the most f

1 Oct 07, 2021
paintable GitHub contribute table

githeart paintable github contribute table how to use: Functions key color select 1,2,3,4,5 clear c drawing mode mode on turn off e print paint matrix

Bahadır Araz 27 Nov 24, 2022
AB-test-analyzer - Python class to perform AB test analysis

AB-test-analyzer Python class to perform AB test analysis Overview This repo con

13 Jul 16, 2022
🧇 Make Waffle Charts in Python.

PyWaffle PyWaffle is an open source, MIT-licensed Python package for plotting waffle charts. It provides a Figure constructor class Waffle, which coul

Guangyang Li 528 Jan 02, 2023
A Python-based non-fungible token (NFT) generator built using Samilla and Matplotlib

PyNFT A Pythonic NF (non-fungible token) generator built using Samilla and Matplotlib Use python pynft.py [amount] The intention behind this generato

Ayush Gundawar 6 Feb 07, 2022
Chem: collection of mostly python code for molecular visualization, QM/MM, FEP, etc

chem: collection of mostly python code for molecular visualization, QM/MM, FEP,

5 Sep 02, 2022
Python module for drawing and rendering beautiful atoms and molecules using Blender.

Batoms is a Python package for editing and rendering atoms and molecules objects using blender. A Python interface that allows for automating workflows.

Xing Wang 1 Jul 06, 2022
A Bokeh project developed for learning and teaching Bokeh interactive plotting!

Bokeh-Python-Visualization A Bokeh project developed for learning and teaching Bokeh interactive plotting! See my medium blog posts about making bokeh

Will Koehrsen 350 Dec 05, 2022
A tool to plot and execute Rossmos's Formula, that helps to catch serial criminals using mathematics

Rossmo Plotter A tool to plot and execute Rossmos's Formula using python, that helps to catch serial criminals using mathematics Author: Amlan Saha Ku

Amlan Saha Kundu 3 Aug 29, 2022
A Jupyter - Three.js bridge

pythreejs A Python / ThreeJS bridge utilizing the Jupyter widget infrastructure. Getting Started Installation Using pip: pip install pythreejs And the

Jupyter Widgets 844 Dec 27, 2022
A dashboard built using Plotly-Dash for interactive visualization of Dex-connected individuals across the country.

Dashboard For The DexConnect Platform of Dexterity Global Working prototype submission for internship at Dexterity Global Group. Dashboard for real ti

Yashasvi Misra 2 Jun 15, 2021
Sky attention heatmap of submissions to astrometry.net

astroheat Installation Requires Python 3.6+, Tested with Python 3.9.5 Install library dependencies pip install -r requirements.txt The program require

4 Jun 20, 2022
Matplotlib colormaps from the yt project !

cmyt Matplotlib colormaps from the yt project ! Colormaps overview The following colormaps, as well as their respective reversed (*_r) versions are av

The yt project 5 Sep 16, 2022
ecoglib: visualization and statistics for high density microecog signals

ecoglib: visualization and statistics for high density microecog signals This library contains high-level analysis tools for "topos" and "chronos" asp

1 Nov 17, 2021
3D Vision functions with end-to-end support for deep learning developers, written in Ivy.

Ivy vision focuses predominantly on 3D vision, with functions for camera geometry, image projections, co-ordinate frame transformations, forward warping, inverse warping, optical flow, depth triangul

Ivy 61 Dec 29, 2022
Manim is an animation engine for explanatory math videos.

A community-maintained Python framework for creating mathematical animations.

12.4k Dec 30, 2022