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
🧇 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
LabGraph is a a Python-first framework used to build sophisticated research systems with real-time streaming, graph API, and parallelism.

LabGraph is a a Python-first framework used to build sophisticated research systems with real-time streaming, graph API, and parallelism.

MLH Fellowship 7 Oct 05, 2022
Generate visualizations of GitHub user and repository statistics using GitHub Actions.

GitHub Stats Visualization Generate visualizations of GitHub user and repository statistics using GitHub Actions. This project is currently a work-in-

JoelImgu 3 Dec 14, 2022
Fractals plotted on MatPlotLib in Python.

About The Project Learning more about fractals through the process of visualization. Built With Matplotlib Numpy License This project is licensed unde

Akeel Ather Medina 2 Aug 30, 2022
Visualization Data Drug in thailand during 2014 to 2020

Visualization Data Drug in thailand during 2014 to 2020 Data sorce from ข้อมูลเปิดภาครัฐ สำนักงาน ป.ป.ส Inttroducing program Using tkinter module for

Narongkorn 1 Jan 05, 2022
eoplatform is a Python package that aims to simplify Remote Sensing Earth Observation by providing actionable information on a wide swath of RS platforms and provide a simple API for downloading and visualizing RS imagery

An Earth Observation Platform Earth Observation made easy. Report Bug | Request Feature About eoplatform is a Python package that aims to simplify Rem

Matthew Tralka 4 Aug 11, 2022
An open-source plotting library for statistical data.

Lets-Plot Lets-Plot is an open-source plotting library for statistical data. It is implemented using the Kotlin programming language. The design of Le

JetBrains 820 Jan 06, 2023
Open-questions - Open questions for Bellingcat technical contributors

Open questions for Bellingcat technical contributors These are difficult, long-term projects that would contribute to open source investigations at Be

Bellingcat 234 Dec 31, 2022
Data-FX is an addon for Blender (2.9) that allows for the visualization of data with different charts

Data-FX Data-FX is an addon for Blender (2.9) that allows for the visualization of data with different charts Currently, there are only 2 chart option

Landon Ferguson 20 Nov 21, 2022
Simple spectra visualization tool for astronomers

SpecViewer A simple visualization tool for astronomers. Dependencies Python = 3.7.4 PyQt5 = 5.15.4 pyqtgraph == 0.10.0 numpy = 1.19.4 How to use py

5 Oct 07, 2021
Python wrapper for Synoptic Data API. Retrieve data from thousands of mesonet stations and networks. Returns JSON from Synoptic as Pandas DataFrame

☁ Synoptic API for Python (unofficial) The Synoptic Mesonet API (formerly MesoWest) gives you access to real-time and historical surface-based weather

Brian Blaylock 23 Jan 06, 2023
Massively parallel self-organizing maps: accelerate training on multicore CPUs, GPUs, and clusters

Somoclu Somoclu is a massively parallel implementation of self-organizing maps. It exploits multicore CPUs, it is able to rely on MPI for distributing

Peter Wittek 239 Nov 10, 2022
A site that displays up to date COVID-19 stats, powered by fastpages.

https://covid19dashboards.com This project was built with fastpages Background This project showcases how you can use fastpages to create a static das

GitHub 1.6k Jan 07, 2023
A tool for creating Toontown-style nametags in Panda3D

Toontown-Nametag Toontown-Nametag is a tool for creating Toontown Online/Toontown Rewritten-style nametags in Panda3D. It contains a function, createN

BoggoTV 2 Dec 23, 2021
Sci palettes for matplotlib/seaborn

sci palettes for matplotlib/seaborn Installation python3 -m pip install sci-palettes Usage import seaborn as sns import matplotlib.pyplot as plt impor

Qingdong Su 2 Jun 07, 2022
Make sankey, alluvial and sankey bump plots in ggplot

The goal of ggsankey is to make beautiful sankey, alluvial and sankey bump plots in ggplot2

David Sjoberg 156 Jan 03, 2023
Matplotlib JOTA style for making figures

Matplotlib JOTA style for making figures This repo has Matplotlib JOTA style to format plots and figures for publications and presentation.

JOTA JORNALISMO 2 May 05, 2022
Customizing Visual Styles in Plotly

Customizing Visual Styles in Plotly Code for a workshop originally developed for an Unconference session during the Outlier Conference hosted by Data

Data Design Dimension 9 Aug 03, 2022
Time series visualizer is a flexible extension that provides filling world map by country from real data.

Time-series-visualizer Time series visualizer is a flexible extension that provides filling world map by country from csv or json file. You can know d

Long Ng 3 Jul 09, 2021
Main repository for Vispy

VisPy: interactive scientific visualization in Python Main website: http://vispy.org VisPy is a high-performance interactive 2D/3D data visualization

vispy 3k Jan 03, 2023