···11+# Local config files
12secrets.json
23config.json
3444-**/venv**
55-55+# VS Code Project Files
66.vscode
7788-__pycache__
981010-.coverage99+############################################################################
1010+# From https://github.com/github/gitignore/blob/master/Python.gitignore
1111+############################################################################
1212+# Byte-compiled / optimized / DLL files
1313+__pycache__/
1414+*.py[cod]
1515+*$py.class
1616+1717+# C extensions
1818+*.so
1919+2020+# Distribution / packaging
2121+.Python
2222+build/
2323+develop-eggs/
2424+dist/
2525+downloads/
2626+eggs/
2727+.eggs/
2828+lib/
2929+lib64/
3030+parts/
3131+sdist/
3232+var/
3333+wheels/
3434+share/python-wheels/
3535+*.egg-info/
3636+.installed.cfg
3737+*.egg
3838+MANIFEST
3939+4040+# PyInstaller
4141+# Usually these files are written by a python script from a template
4242+# before PyInstaller builds the exe, so as to inject date/other infos into it.
4343+*.manifest
4444+*.spec
4545+4646+# Installer logs
4747+pip-log.txt
4848+pip-delete-this-directory.txt
4949+5050+# Unit test / coverage reports
5151+htmlcov/
5252+.tox/
5353+.nox/
5454+.coverage
5555+.coverage.*
5656+.cache
5757+nosetests.xml
5858+coverage.xml
5959+*.cover
6060+*.py,cover
6161+.hypothesis/
6262+.pytest_cache/
6363+cover/
6464+6565+# Translations
6666+*.mo
6767+*.pot
6868+6969+# Django stuff:
7070+*.log
7171+local_settings.py
7272+db.sqlite3
7373+db.sqlite3-journal
7474+7575+# Flask stuff:
7676+instance/
7777+.webassets-cache
7878+7979+# Scrapy stuff:
8080+.scrapy
8181+8282+# Sphinx documentation
8383+docs/_build/
8484+8585+# PyBuilder
8686+.pybuilder/
8787+target/
8888+8989+# Jupyter Notebook
9090+.ipynb_checkpoints
9191+9292+# IPython
9393+profile_default/
9494+ipython_config.py
9595+9696+# pyenv
9797+# For a library or package, you might want to ignore these files since the code is
9898+# intended to run in multiple environments; otherwise, check them in:
9999+# .python-version
100100+101101+# pipenv
102102+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
103103+# However, in case of collaboration, if having platform-specific dependencies or dependencies
104104+# having no cross-platform support, pipenv may install dependencies that don't work, or not
105105+# install all needed dependencies.
106106+#Pipfile.lock
107107+108108+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
109109+__pypackages__/
110110+111111+# Celery stuff
112112+celerybeat-schedule
113113+celerybeat.pid
114114+115115+# SageMath parsed files
116116+*.sage.py
117117+118118+# Environments
119119+.env
120120+.venv
121121+env/
122122+venv/
123123+ENV/
124124+env.bak/
125125+venv.bak/
126126+127127+# Spyder project settings
128128+.spyderproject
129129+.spyproject
130130+131131+# Rope project settings
132132+.ropeproject
133133+134134+# mkdocs documentation
135135+/site
136136+137137+# mypy
138138+.mypy_cache/
139139+.dmypy.json
140140+dmypy.json
141141+142142+# Pyre type checker
143143+.pyre/
144144+145145+# pytype static type analyzer
146146+.pytype/
147147+148148+# Cython debug symbols
149149+cython_debug/
···11# Burndown Chart for GitHub Projects
22An easy to use [burndown chart](https://www.scrum.org/resources/scrum-glossary#:~:text=B-,burn-down%20chart,-%3A%C2%A0a%20chart%20which) generator for [GitHub Project Boards](https://docs.github.com/en/issues/organizing-your-work-with-project-boards/managing-project-boards/about-project-boards).
3344+
55+46## Table of Contents
57* [Features](#features)
68* [Installation](#installation)
79* [Assumptions](#assumptions)
1010+* [Configuration](#configuration)
811* [Usage](#usage)
912* [Contributing](#contributing)
1013* [About](#about)
11141215## Features
1316* Create a **burndown chart for a GitHub Project Board**.
1414-* Works for **private repositories**.
1717+* Works for projects in **public/private repositories** and **organizations**.
1518* Includes a **trend line** for the current sprint.
1619* Supports custom labels for **tracking points for issues**
1720···2023* You use one and only one [GitHub Project Board](https://docs.github.com/en/issues/organizing-your-work-with-project-boards/managing-project-boards/about-project-boards) for each of your [Sprints](https://scrumguides.org/scrum-guide.html#the-sprint)
2124* You use one and only one [GitHub Milestone](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/about-milestones) for each of your [User Stories](https://www.scrum.org/resources/blog/user-story-or-stakeholder-story)
2225* You use one and only one [GitHub Issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) for each of your [Sprint Backlog Items/Tasks](https://scrumguides.org/scrum-guide.html#sprint-backlog)
2323-* Each of your GitHub Issues has a [label](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) indicating how many [points](https://www.scrum.org/resources/scrum-glossary#:~:text=several%20ways%20such%20as-,user%20story%20points,-or%20task%20hours.%20Work) its corresponding task is worth.
2626+* If you want to track points, each of your GitHub Issues has a [label](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) indicating how many [points](https://www.scrum.org/resources/scrum-glossary#:~:text=several%20ways%20such%20as-,user%20story%20points,-or%20task%20hours.%20Work) its corresponding task is worth.
2427 - Furthermore, all labels that indicate point values have the format `<prefix><int>`.
2525- - However, multiple labels indicating points on the same Issue are supported.
2828+ - Multiple labels indicating points on the same Issue are supported.
2629* A Sprint Backlog Task is considered [Done](https://www.scrum.org/resources/professional-scrum-developer-glossary#:~:text=D-,definition%20of%20done%3A,-a%20shared%20understanding) if its corresponding GitHub Issue is Closed.
27302831## Installation
···38413942### 2. Activate the virtual environment
40434141-*Linux/Mac OS*
4444+*Linux/macOS*
4245```
4346source venv/bin/activate
4447```
···5659pip install -r requirements.txt
5760```
58616262+## Configuration
6363+### 1. Create a [Personal Access Token](https://github.com/settings/tokens) with the `repo` scope.
6464+Do not share this token with anyone! It gives the bearer full control over all private repositories you have access to!
6565+6666+This is required to pull the Project Board data from GitHub's GraphQL API.
6767+### 2. Make a copy of `src/github_projects_burndown_chart/config/secrets.json.dist` without the `.dist` ending.
6868+This allows the `.gitignore` to exclude your `secrets.json` from being accidentally committed.
6969+### 3. Fill out the `github_token` with your newly created Personal Access Token.
7070+### 4. Make a copy of `src/github_projects_burndown_chart/config/config.json.dist` without the `.dist` ending.
7171+This allows the `.gitignore` to exclude your `config.json` from being accidentally committed.
7272+### 5. Fill out all the configuration settings
7373+#### Repository Projects
7474+`project_name`: A memorable name for your project for use with this tool.
7575+7676+`project_name.query_variables`
7777+| Variable | Meaning |
7878+|----------|---------|
7979+| `repo_owner` | The username of the owner of the repo. <br/><br/> Example: `jhale1805` |
8080+| `repo_name` | The name of the repo. <br/><br/> Example: `github-projects-burndown-chart`|
8181+| `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. <br/><br/> Example: `1` (from [`https://github.com/jhale1805/github-projects-burndown-chart/projects/1`](https://github.com/jhale1805/github-projects-burndown-chart/projects/1)) |
8282+| `column_count` | A number >= the number of columns on the project board. (DEFAULT: 5)<br/><br/> A closer fit improves performance and reduces the chance of rate limiting from GitHub's GraphQL API. |
8383+| `max_cards_per_column_count` | A number >= the maximum number of cards in any column on the project board. (DEFAULT: 50)<br/><br/> A closer fit improves performance and reduces the chance of rate limiting from GitHub's GraphQL API. |
8484+| `labels_per_issue_count` | A number >= the number of labels on any issue on project board. (DEFAULT: 5)<br/><br/> A closer fit improves performance and reduces the chance of rate limiting from GitHub's GraphQL API. |
8585+8686+`project_name.settings`
8787+| Variable | Meaning |
8888+|----------|---------|
8989+| `sprint_start_date` | The first day of the sprint formatted as `YYYY-MM-DD`. <br/><br/> Must be entered here since GitHub Project Boards don't have an assigned start/end date. <br/><br/> Example: `2021-10-08` |
9090+| `sprint_end_date` | The last day of the sprint formatted as `YYYY-MM-DD`. <br/><br/> Must be entered here since GitHub Project Boards don't have an assigned start/end date. <br/><br/> Example: `2021-10-21` |
9191+| `points_label` | (OPTIONAL) The prefix for issue labels containing the point value of the issue. Removing this prefix must leave just an integer. If set to `null`, the burndown chart will count open issues instead of points.<br/><br/> Example: `Points: ` (with the space) |
9292+9393+#### Organization Projects
9494+All settings are the same as for the [Repository Projects](#repository-projects), except `repo_owner` and `repo_name` are replaced with `organization_name` as shown below.
9595+9696+`project_name.query_variables`
9797+| Variable | Meaning |
9898+|----------|---------|
9999+| `organization_name` | The name of the organization on GitHub as it appears in the URL of their organization page. <br/><br/> Example: `golang` (from https://github.com/golang) |
59100## Usage
6060-### Configuration
6161-1. Create a [Personal Access Token](https://github.com/settings/tokens) with the `repo` scope.
6262- - Do not share this token with anyone! It gives the bearer full control over all private repositories you have access to!
6363- - This is required to pull the Project Board data from GitHub's GraphQL API.
6464-2. Make a copy of `src/github_projects_burndown_chart/config/secrets.json.dist` without the `.dist` ending.
6565- - This allows the `.gitignore` to exclude your `secrets.json` from being accidentally committed.
6666-3. Fill out the `github_token` with your newly created Personal Access Token.
6767-4. Make a copy of `src/github_projects_burndown_chart/config/config.json.dist` without the `.dist` ending.
6868- - This allows the `.gitignore` to exclude your `config.json` from being accidentally committed.
6969-5. Fill out all the configuration settings
7070- - `repository_project_query.repo_owner`: The username of the owner of the repo.
7171- - For example, `jhale1805`
7272- - `repository_project_query.repo_name`: The name of the repo.
7373- - For example, `github-projects-burndown-chart`
7474- - `repository_project_query.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.
7575- - For example, `1` from [`https://github.com/jhale1805/github-projects-burndown-chart/projects/1`](https://github.com/jhale1805/github-projects-burndown-chart/projects/1)
7676- - `settings.sprint_start_date`: The first day of the sprint. Formatted as `YYYY-MM-DD`.
7777- - Must be entered here since GitHub Project Boards don't have an assigned start/end date.
7878- - For example, `2021-10-08`
7979- - `settings.sprint_end_date`: The last day of the sprint. Formatted as `YYYY-MM-DD`.
8080- - Must be entered here since GitHub Project Boards don't have an assigned start/end date.
8181- - For example, `2021-10-22`
8282- - `settings.points_label`: The prefix for issue labels containing the point value of the issue. Removing this prefix must leave just an integer.
8383- - For example: `Points: ` (with the space)
8484-### Generating the Chart
8585-1. Run `make run` to generate the burndown chart.
8686- - This will pop up an interactive window containing the burndown chart, including a button for saving it as a picture.
101101+Given that `PROJECT_TYPE` is one of `[repository, organization]` and `PROJECT_NAME` matches a key in the `config.json` under the chosen `PROJECT_TYPE`, run the following command:
102102+```
103103+make run project_type=PROJECT_TYPE project_name=PROJECT_NAME
104104+```
105105+106106+This will pop up an interactive window containing the burndown chart, including a button for saving it as a picture.
107107+108108+### Example
109109+Make a copy of `example.config.json` without the leading `example.`
110110+111111+To see this repository's example project board:
112112+```
113113+make run project_type=repository project_name=burndown_chart_kickoff
114114+```
115115+116116+To see Golang's progress on their current roadmap:
117117+```
118118+make run project_type=organization project_name=golang_on_deck
119119+```
8712088121## Contributing
89122Contributions are welcome via a [Pull Request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
docs/images/example_burndown_chart.png
This is a binary file and will not be displayed.
+24-3
src/github_projects_burndown_chart/main.py
···11+import argparse
22+13from chart.burndown import BurndownChart
22-from gh.api_wrapper import get_repository_project
44+from config import config
55+from gh.api_wrapper import get_organization_project, get_repository_project
36from gh.project import Project
4758if __name__ == '__main__':
66- project: Project = get_repository_project()
99+ # Parse the command line arguments
1010+ parser = argparse.ArgumentParser(
1111+ description='Generate a burndown chart for a GitHub project.')
1212+ parser.add_argument("project_type",
1313+ choices=['repository', 'organization'],
1414+ help="The type of project to generate a burndown chart for. Can be either 'organization' or 'repository'.")
1515+ parser.add_argument("project_name", help="The name of the project as it appears in the config.json")
1616+ args = parser.parse_args()
1717+1818+ # Point the config to the correct project
1919+ config.set_project(args.project_type, args.project_name)
2020+2121+ # Pull the corresponding project from GitHub
2222+ if args.project_type == 'repository':
2323+ project: Project = get_repository_project()
2424+ elif args.project_type == 'organization':
2525+ project: Project = get_organization_project()
2626+2727+ # Generate the burndown chart
728 burndown_chart = BurndownChart(project)
829 burndown_chart.render()
99- print('Done')3030+ print('Done')