Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
120ba71
Merge pull request #18 from ntavares/node_shape
pawelrychlik Jan 28, 2018
ed85408
Merge pull request #20 from ntavares/hyper_nodes
pawelrychlik Jan 28, 2018
1f3fc9a
ignore subtasks
Jan 29, 2018
0c24149
prevent traversing projects
Jan 29, 2018
9e27de4
Bugfix - add missing parameter
pawelrychlik Jan 29, 2018
67c187f
Merge branch 'ntavares-traversing'
pawelrychlik Jan 29, 2018
42078a3
Rename variable
pawelrychlik Jan 29, 2018
c3925f9
Simplify create_node_text
pawelrychlik Jan 29, 2018
6e59c33
Comment out debug logs
pawelrychlik Jan 29, 2018
bf14812
Simplify
pawelrychlik Jan 29, 2018
0ec88db
Simplifying further
pawelrychlik Jan 29, 2018
f27c4b6
Refactor and simplify
pawelrychlik Jan 29, 2018
2841d63
Refactor - keyword param
pawelrychlik Jan 29, 2018
a50415b
Update example output
pawelrychlik Jan 29, 2018
ee529f7
Improve readme
pawelrychlik Jan 29, 2018
139c1e7
Default to box node shape
pawelrychlik Jan 29, 2018
ec5c161
Some clean up
pawelrychlik Feb 4, 2018
0655e65
Add png file extension to git ignore list
Feb 14, 2018
4d1e4cd
Add new command line param to allow --word-wrap of summaries
Feb 14, 2018
aac53cf
Add command line flag to skip SSL check for jira requests
Feb 14, 2018
4a60583
Dockerfile and docs
Mar 25, 2018
d1b7ded
minor
Mar 25, 2018
c222911
Merge pull request #25 from dionjwa/dockerize
pawelrychlik Mar 26, 2018
b29448d
Switch to python alpine distro when running with Docker
pawelrychlik Mar 26, 2018
cfd9ae1
Improve readme - Docker command
pawelrychlik Mar 26, 2018
ed4bff2
Merge branch 'add-ssl-verify-flag' of https://github.com/slash-zero/j…
pawelrychlik Mar 26, 2018
6b095d8
Merge branch 'slash-zero-add-ssl-verify-flag'
pawelrychlik Mar 26, 2018
e964014
Use the rankdir setting instead of unflatten
balain Apr 19, 2018
dac35a2
Merge pull request #26 from balain/master
pawelrychlik Apr 19, 2018
4906de6
Add strip in exclude logic
thomas0306 Nov 21, 2018
2aa7250
Add new -xi/--issue-exclude option.
pradzins Oct 25, 2019
0f13024
Merge pull request #31 from pradzins/exclude-tickets
pawelrychlik Oct 27, 2019
5bf97ed
Merge pull request #27 from thomas0306/master
pawelrychlik Oct 27, 2019
202d702
changes to support python3
Dec 19, 2019
8377c19
Write image file in binary mode
kingchad1989 Feb 1, 2020
d4e2a56
Port to Python 3
fuzzyhandle Feb 5, 2020
df5c0b3
Merge pull request #36 from pkware/write_file_in_binary_mode
pawelrychlik Feb 5, 2020
038823b
Merge branch 'fuzzyhandle-master'
pawelrychlik Feb 5, 2020
18f3f4e
Keep __future__ import; Drop utf-8 encoding of summary - unnecessary?
pawelrychlik Feb 5, 2020
8909cca
Merge branch 'python3' of https://github.com/rbuckland/jira-dependenc…
pawelrychlik Feb 5, 2020
fc44cf2
Add Atlassian Cloud authentication instructions
mcgwiz Sep 18, 2020
784046d
Merge pull request #42 from mcgwiz/patch-1
pawelrychlik Sep 21, 2020
9d975f7
Add ability to dynamically acquire issue-keys using JQL
LisaHelm Nov 19, 2020
aea22d9
Add option to not use authentication at all
brownterryn Dec 22, 2020
46bb8d4
Merge pull request #44 from tbnorth/feature/no-auth
pawelrychlik Jan 10, 2021
0073048
Merge pull request #43 from LisaHelm/master
pawelrychlik Jan 10, 2021
b765166
big sloppy commit - pls pardon all the dusts
gfaza Nov 5, 2021
44db941
log message cleanup
gfaza Nov 5, 2021
7c5ae10
three more hasty typing sessions
gfaza Dec 17, 2021
d8fe252
increasing maximum nodes
gfaza Mar 12, 2022
1df99b8
fix card depth logic
gfaza Mar 12, 2022
8cdf496
card depth relative rendering
gfaza Mar 12, 2022
c7d897d
orient blockers as dependencies toward the end of graph
gfaza Mar 12, 2022
ad2911e
encapsulate graph string construction
gfaza Mar 12, 2022
283ca80
add switch for graph direction
gfaza Mar 12, 2022
da1801f
orient team labels toward graph root
gfaza Mar 12, 2022
015d327
encapsulate graph string construction
gfaza Mar 12, 2022
c99fdd5
add switch for graph direction
gfaza Mar 12, 2022
ed44d6b
orient blockers as dependencies away from root
gfaza Mar 12, 2022
84097fd
adding html stylized node labels
gfaza Mar 12, 2022
2698865
adding option of issue assignee
gfaza Mar 13, 2022
e94a067
adding html stylized node labels
gfaza Mar 13, 2022
0abbdcc
adding option of issue assignee
gfaza Mar 13, 2022
6f9a905
adding html stylized node labels
gfaza Mar 13, 2022
618529d
adding html stylized node labels
gfaza Mar 13, 2022
d674014
big fat grouped layout changes commit - incomplete checkpoint
gfaza Mar 14, 2022
b3ece1e
messy checkpoint, but nearing end of subgraph option
gfaza Mar 22, 2022
23377d0
saving mess
gfaza Mar 25, 2022
d320740
cleanup
gfaza Apr 6, 2022
1af4e9b
cleanup
gfaza Apr 6, 2022
0bcfd1e
cleanup
gfaza Apr 7, 2022
7df996b
cleanup
gfaza Apr 7, 2022
a85874c
cleanup
gfaza Apr 8, 2022
46126af
bless this mess. a little longer. please.
gfaza Apr 12, 2022
5209eab
the kind of changes i should have started with
gfaza Apr 20, 2022
c0c8619
omitting commented code
gfaza Apr 20, 2022
a794561
send in the objects
gfaza Apr 21, 2022
6a1559d
cleaning up subgraph and label logic
gfaza Apr 22, 2022
0d6c427
primarily the cleaning and fixing of card levels
gfaza Apr 23, 2022
f127faf
primarily the cleaning and fixing of card levels
gfaza Apr 23, 2022
139534e
cleaning up card states
gfaza Apr 23, 2022
af30b01
cleaning up card labels
gfaza Apr 23, 2022
e814687
cleaning up subgraphs
gfaza Apr 26, 2022
40ee4d0
cleaning up subgraphs
gfaza Apr 26, 2022
b2bab8e
cleaning up subgraphs
gfaza Apr 27, 2022
e700281
cleaning up subgraphs
gfaza Apr 27, 2022
636c07a
cleaning up subgraphs
gfaza Apr 27, 2022
bd969f8
cleaning up subgraphs
gfaza Apr 28, 2022
ec06a08
cleanup workflow state yaml
gfaza May 6, 2022
2faf020
providing some comparison data before refactoring graph rendering
gfaza May 6, 2022
e3ec4c0
templating going well
gfaza May 6, 2022
bb6a7ae
templating going well
gfaza May 6, 2022
b5af620
apparently ... fixing docker variation
gfaza May 6, 2022
6b9758c
cleanining up fonts
gfaza May 7, 2022
b318d3f
moving toward renderer injection
gfaza May 7, 2022
368f2b0
moving toward renderer injection
gfaza May 10, 2022
a44588e
cleanup link type handling
gfaza May 26, 2022
4876efa
cleanup unused param and blackening
gfaza May 26, 2022
5352c1d
fixing depth-related exclusions
gfaza Jun 1, 2022
4fef6b0
awkward moment, but worth a checkpoint
gfaza Jul 13, 2022
35f56b2
suppressing a bunch of debug/test output
gfaza Aug 2, 2022
d46d976
add a link to view updated card description in the log
gfaza Aug 4, 2022
eec1084
enable omission of empty epics
gfaza Nov 15, 2022
5634a11
allow singular dependents to layout as parent nodes
gfaza Nov 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ wheels/
# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Credentials and other configurations
config/
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.6

ADD jira-dependency-graph.py /jira/
ADD helper_methods.py /jira/
ADD check-subgraph.py /jira/
ADD requirements.txt /jira/
WORKDIR /jira
RUN apt-get update \
&& apt-get install -y --no-install-recommends graphviz \
&& rm -rf /var/lib/apt/lists/* \
&& pip install -r requirements.txt
196 changes: 174 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ Example output

Requirements:
=============
* Python 2.6+
* Python 2.7+ or Python 3+
* [requests](http://docs.python-requests.org/en/master/)

Or
* [docker](https://docs.docker.com/install/)

Usage:
======
```bash
Expand All @@ -24,7 +27,17 @@ $ virtualenv .virtualenv && source .virtualenv/bin/activate # OPTIONAL
$ cd jira-dependency-graph
$ pip install -r requirements.txt
$ python jira-dependency-graph.py --user=your-jira-username --password=your-jira-password --jira=url-of-your-jira-site issue-key
```

Or if you prefer running in docker:
```bash
$ git clone https://github.com/pawelrychlik/jira-dependency-graph.git
$ cd jira-dependency-graph
$ docker build -t jira .
$ docker run -v $PWD/out:/out jira python jira-dependency-graph.py --user=your-jira-username --password=your-jira-password --jira=url-of-your-jira-site --file=/out/output.png issue-key
```

```
# e.g.:
$ python jira-dependency-graph.py --user=pawelrychlik --password=s3cr3t --jira=https://your-company.jira.com JIRATICKET-718

Expand All @@ -48,36 +61,20 @@ Fetching JIRATICKET-2977
JIRATICKET-2977 => blocks => JIRATICKET-2451

Writing to issue_graph.png

```
Result:
![Example result](examples/issue_graph.png)

Local Usage:
============
If you have issues with the Google Graphviz API limitations you can use your local graphviz installation like this:

```bash
$ git clone https://github.com/pawelrychlik/jira-dependency-graph.git
$ cd jira-dependency-graph
$ python jira-dependency-graph.py --user=your-jira-username --password=your-jira-password --jira=url-of-your-jira-site --local issue-key | dot -Tpng > issue_graph.png
```
Advanced Usage:
===============

*Note*: Its possible that the graph produced is too wide if you have a number of issues. In this case, it is better to firstly pipe the graph to a 'dot' text file e.g.
List of all configuration options with descriptions:

```bash
$ python jira-dependency-graph.py --jira=url-of-your-jira-site --local issue-key > graph.dot
```

and then process it using `unflatten`:

```bash
unflatten -f -l 4 -c 16 graph.dot | dot | gvpack -array_t6 | neato -s -n2 -Tpng -o graph.png
python jira-dependency-graph.py --help
```

Advanced Usage:
===============

### Excluding Links

In case you have specific issue links you don't want to see in your graph, you can exclude them:
Expand All @@ -101,10 +98,23 @@ $ python jira-dependency-graph.py --user=your-jira-username --password=your-jira

In order to only specify issues with a certain prefix pass in `--issue-include <XXX>` and all tickets will be checked that they match the prefix `XXX`.

### Excluding Issues

By passing in `--issue-exclude`, or `-xi` the system will explicitly ignore the ticket. It can be repeated multiple times, e.g. `-xi MYPR-456 -x MYPR-999` to ignore both issues.
Use it as a last-resort only, when other means of exclusion do not suit your case, e.g. to omit a part of the graph for better readability.

### Authentication

It is possible to either use the username/password combination or to login via the browser passing in `--cookie <JSESSIONID>`. This logins via the browser and is useful in scenarios where Kerberos authentication is required.

If you are using Atlassian Cloud, use your API token instead of your account password. You can generate one with the following steps:

1. Access https://id.atlassian.com/manage-profile/security/api-tokens.
2. Click "Create API token".
3. Copy the token and store it in a safe place.

More details about API authentication is available in the [official documentation](https://developer.atlassian.com/cloud/jira/platform/basic-auth-for-rest-apis/).

### Closed Issues

By passing in `--ignore-closed` the system will ignore any ticket that is closed.
Expand All @@ -116,8 +126,150 @@ Multiple issue-keys can be passed in via space separated format e.g.
$ python jira-dependency-graph.py --cookie <JSESSIONID> issue-key1 issue-key2
```

### JQL Query

Instead of passing issue-keys, a Jira Query Language command can be passed with `--jql` e.g.
```bash
$ python jira-dependency-graph.py --cookie <JSESSIONID> --jql 'project = JRADEV'
```


Usage without Google Graphviz API:
============
If you have issues with the Google Graphviz API limitations you can use your local graphviz installation like this:

```bash
$ git clone https://github.com/pawelrychlik/jira-dependency-graph.git
$ cd jira-dependency-graph
$ python jira-dependency-graph.py --user=your-jira-username --password=your-jira-password --jira=url-of-your-jira-site --local issue-key | dot -Tpng > issue_graph.png
```

*Note*: Its possible that the graph produced is too wide if you have a number of issues. In this case, it is better to firstly pipe the graph to a 'dot' text file e.g.

```bash
$ python jira-dependency-graph.py --jira=url-of-your-jira-site --local issue-key > graph.dot
```

and then process it using `unflatten`:

```bash
unflatten -f -l 4 -c 16 graph.dot | dot | gvpack -array_t6 | neato -s -n2 -Tpng -o graph.png
```

For a slightly cleaner layout (that preserves the ranks), or if your system doesn't have `unflatten`, you can use `sed` to insert `rankdir=LR;` into the dot file before processing it:
```bash
sed -i 's/digraph{/digraph{ rankdir=LR;/g' graph.dot | dot -o graph.png -Tpng
```

Notes:
======
Based on: [draw-chart.py](https://developer.atlassian.com/download/attachments/4227078/draw-chart.py) and [Atlassian JIRA development documentation](https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Version+2+Tutorial#JIRARESTAPIVersion2Tutorial-Example#1:GraphingImageLinks), which seemingly was no longer compatible with JIRA REST API Version 2.

There is a limit on the query length: "The longest URL that Google accepts in a chart GET request is 2048 characters in length, after URL-encoding" (from [faq](https://developers.google.com/chart/image/faq)).

Apologies and Messy Changes (gfaza customizations WIP):
======
These hasty and large commits for the sake of sharing quickly, are less than congenial. I'd love to come back and clean both the code and the comments, especially since there are other tweaks to come.

**Please Note:** Backward compatibility with the above hasn't been asserted.

**FWIW:** These changes were developed and utilized with the following suggested runtime options:
```bash
-show-directions=outward --word-wrap --include-state --include-labels
```

Things included in these changes:

1. Getting started, you'll need to create then update `personal-config.ini` with your Jira credentials. **BEWARE**: do not commit this file, so you don't accidentally share your creds! Additionally, you'll likely enjoy updating the domain-specific configuration template in order to stylize your output.
```bash
> ./initialize-organization-configuration.sh
```
or in case that fails, the following:
```bash
> mkdir ./config
> echo "[EXAMPLE]\nJIRA_HOST = https://example.atlassian.net\nJIRA_USER = [email protected]\nJIRA_PASS = # Create an API key at https://id.atlassian.com/manage-profile/security/api-tokens\n\n" > ./config/personal-config.ini
> echo "### define the color scheme and state color progression to use. ###\ncolor-setting:\n color-scheme: ylgn9\n fill-colors: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n font-colors: [None, None, None, None, None, None, white, white, white ]\n### define any graph attributes particular to specific node types ###\nnodes:\n - name: [ epic ]\n node-options:\n shape: cylinder\n labelloc: b\n edge-options:\n color: orange\n - name: [ label ]\n node-options:\n shape: cds\n edge-options:\n color: grey85\n### define any graph attributes particular to specific edge types ###\nedges:\n - name: [ epic ]\n edge-options:\n color: orange\n - name: [ subtask ]\n edge-options:\n color: blue\n label: subtask\n - name: [ block ]\n edge-options:\n color: red\n### define the issue states to be colored according to the custom color scheme progression. any omitted will show according to the status category: yellow ('In Progress'), green ('Complete'), else (no color/white) ###\nworkflows:\n - issue-types: [ epic ]\n states:\n # - backlog\n - in progress\n - completed\n - issue-types: [ story, bug ]\n states:\n # - backlog\n # - ready for development\n - in development\n - ready for testing\n - in testing\n - ready for release\n - released\n### consolidate groups of labels to a single alias ###\nlabels:\n - name: Defect\n group: [ defect, bug, staging-bug, production-bug ]\n - name: Research & Development\n group: [ spike, arch, architecture, research, r&d ]\n ### labels to omit from diagrams ###\n - ignore: [ documentation, testing, tech-debt ]\n" > ./config/example-config.yml
```

3. For access to multiple organizations, add those additional creds in `personal-config.ini` then specify on the command line with the `--org` option. The script will default to the first `[SECTION]` it finds in your `personal-config.ini`, unless `--org` is specified.
```bash
--org=SOME_ADDITIONAL_ORGANIZATION_I_BELONG_TO
```

4. If you are aiming to use the docker version, you'll need to build the docker image. This is recommended if you're concerned about ruining your local Python environment or hesitant about installing Graphviz on your local machine.
```bash
> docker build -t jira .
```

5. When using the config directory, you'll need to add the share to that directory by adding the following to your command:
```bash
$PWD/config:/jira/config
```

6. If you prefer to use your own installation of Graphviz, you can pipe the output of using `--local` to it, such as
```bash
> docker run -v $PWD/config:/jira/config -v $PWD/out:/jira/out jira python jira-dependency-graph.py --local STORY-123 | dot -Tpng > ~/Desktop/STORY-123-graph.png
```

7. The non-`--local` version seemed broken since google isn't handling that endpoint anymore, so Graphviz is now included in the docker image. i.e., we're no longer required to use --local then pipe to dot (Graphviz) on your host machine.
```bash
> docker run -v $PWD/config:/jira/config -v $PWD/out:/jira/out jira python jira-dependency-graph.py STORY-123
```

8. An additional artifact when this script is executed without `--local`, will be a PDF version of the diagram, where each node on the diagram hyperlinks you to its corresponding card on Jira


8. New command line option: To automatically update a card with your diagram, specify a destination card. This destination can be any card, whether or not it's related to the diagram. The card specified will receive attachments of the PNG and PDF graphs, and will have it's description updated to include the graph as an embedded image:
```bash
--issue-update=<jira-card-key>
```

9. New command line options: Include additional issue elements on your node's label:
```bash
--include-state
--include-assignee
```

10. New command line option: Include issue labels as additional nodes on the graph. Can be a useful way of further helping the layout algorithm:
```bash
--include-labels
```

11. New command line option: Include the script command line arguments as the title of your graph:
```bash
--include-arguments
```

12. New command line option: Limit the depth of issues visited, from the issues searched:
```bash
--depth-limit=<some-int>
```

13. New command line option: Direction in which sequential nodes will be rendered, with a default of "TB" (Top to Bottom).
```bash
--graph-rank-direction=<TB|LR|BT|RL>
```

14. Graph configuration yaml: A default yaml will be generated along with the `personal-config.ini`, as a template for customizing the color scheme and other elements of the graphs. be sure to keep the org name in sync with your `personal-config.ini`. e.g., if your `personal-config.ini` section reads `[EXAMPLE]`, then the corresponding yaml file must be named `example-config.yml`.
1. ***color-setting:*** The name of the Graphviz color scheme to use (https://graphviz.org/doc/info/colors.html), and the ordered list of colors to use when rendering issues, as they progress through their given workflow.
1. e.g., `color-setting: { color-scheme: set16, fill-colors: [1, 5, 6, 3, 2, 4] }` would produce graphs in (close to) pride colors.
2. ***nodes:*** Customizations for rendering Epics and Labels (optionally included in diagrams).
3. ***edges:*** Customizations for rendering edges related to Epic, Subtask, and Blocking issues.
4. ***workflows:*** Definitions for your organization's issue types, and the ordered statuses for their respective workflows.
5. ***labels:*** A means of consolidating similar labels to simplify graphing, as well as a means of ignoring/omitting certain labels from appearing.
6. Executing the command for a value of `color-demo` in place of an issue key will produce a partial preview of the graph configuration.
```bash
> docker run -v $PWD/config:/jira/config -v $PWD/out:/jira/out jira python jira-dependency-graph.py color-demo
```


Wishlist/Planned changes:
======
* Verify backward and forward compatibility, in both docker and non-docker operation (i.e., ensure enhancements are strictly optional).
* Update/improve documentation.
* Improve output file naming.
* Investigate whether jira issue description embedded PNG can open PDF attachment on click (i.e., embedding PNG to serve as thumbnail href to the PDF).
* Investigate automating updates to a specified confluence page, similar to how this automates updates to jira issues.
* Investigate automatically opening the graph on the local machine after rendering.
* Consider prevent issues from being missed only because the story leading to them is ignored (distinguish ignore vs traverse).
* Develop further flexibility via the configuration yaml.
* Revisit dependencies, and whether they can be reduced/simplified.
Binary file modified examples/issue_graph_complex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading