This is a GitHub issue scanner for jQAssistant. It enables jQAssistant to scan and analyze GitHub issues.
To use the GitHub-Issues plugin create a file named githubissues.xml
.
The plugin can scan multiple repositories owned by different users. Please note that
the GitHub REST-API requires login credentials to
access any of its functions. Therefore, login credentials can be provided per
repository.
<github-issues-configuration>
<github-repository>
<user>github-user</user>
<name>github-repository-name</name>
<credentials>
<user>authentication-user</user>
<password>authentication-password</password>
</credentials>
</github-repository>
<github-repository>
...
</github-repository>
</github-issues-configuration>
Put the githubissues.xml
inside an artifact that shall be scanned
or simply scan it standalone:
Download jQAssistant for command line usage
and put the plugin JAR in the plugins
folder. Then run:
# Scan the GitHub-Repositories
jqassistant-commandline-neo4jv3-1.4.0/bin/jqassistant.sh scan -f githubissues.xml
# Start a Neo4J web UI to explore the result:
jqassistant-commandline-neo4jv3-1.4.0/bin/jqassistant.sh server
The GitHub-Issues plugin uses the following labels in the resulting graph:
Label | Description | ID |
---|---|---|
GitHub | Parent label for all nodes related to the GitHub-Issues plugin. | - |
Repository | Represents a GitHub Repository. | "repo-user/repo-name" |
Issue | Represents a GitHub Issue. | "repo-user/repo-name#issue-number" |
Milestone | Represents a GitHub Milestone which is a collection of Issues. | "repo-user/repo-name#milestone-id" |
Comment | Represents a Comment under a GitHub Issue. | - |
PullRequest | Every PullRequest is an Issue, but not every Issue is a PullRequest. | "repo-user/repo-name#issue-number" |
User | Represents a GitHub User. | "user-name" |
Commit | Represents a GitHub Commit. | "repo-user/repo-name#commit-sha" |
Here are the possible relations between those labels:
(Repository) -[:HAS_ISSUE] -> (Issue)
(Repository) -[:HAS_MILESTONE] -> (Milestone)
(Issue) -[:HAS_LABEL] -> (Label)
(Issue) -[:HAS_COMMENT] -> (Comment)
(Issue) -[:HAS_ASSIGNEE] -> (User)
(Issue) -[:CREATED_BY] -> (User)
(Issue) -[:IS_PART_OF] -> (Milestone)
(PullRequest) -[:HAS_LAST_COMMIT] -> (Commit)
(Milestone) -[:CREATED_BY] -> (User)
(Comment) -[:FOLLOWED_BY] -> (Comment)
(Comment) -[:CREATED_BY] -> (User)
List all your open Issues over multiple repositories:
MATCH
(r:Repository)-[:HAS_ISSUE]->(i:Issue {state:"open"})
RETURN
r.repositoryId, i.title, i.body
Count open Issues per repository:
MATCH
(r:Repository)-[:HAS_ISSUE]->(Issue {state:"open"})
RETURN
r.repositoryId, count(*) AS issueCount
ORDER BY
issueCount DESC
List open issues per user:
MATCH
(Issue {state:"open"})-[:HAS_ASSIGNEE]->(u:User)
RETURN
u.login, count(*)
Show issues without description:
MATCH
(i:Issue)
WHERE
i.body = ""
RETURN
i.issueId, i.title
Show issues without labels:
MATCH
(i:Issue)
WHERE
NOT (i:Issue)-[:HAS_LABEL]->()
RETURN
i.title, i.issueId
Show issues ordered descending by the amount of comments:
MATCH
path=((i:Issue)-[:HAS_COMMENT]->()-[:FOLLOWED_BY*]->())
RETURN
i.title, i.issueId, length(path) AS pathLength, i.state
ORDER BY
pathLength DESC, i.state DESC
Show durations it needed to resolve an issue:
WITH
issue, duration.inDays(date(issue.createdAt), date(issue.updatedAt)).days AS duration
RETURN
issue.issueId, issue.title, duration + " days" AS timToSolve
ORDER BY
duration DESC
Show issues older than 1 month that are still open:
MATCH
(issue:Issue {state:"open"})
WHERE
date(issue.createdAt) <= date('20180713')
RETURN
*
Let's have a look at a few indicators:
- Do these Issues have labels?
MATCH
(issue:Issue {state:"open"})
WHERE
date(issue.createdAt) <= date('20180713') AND NOT (issue:Issue)-[:HAS_LABEL]->()
RETURN
*
→ If not, then probably no one looked at these issues.
- Is anyone assigned to this issue?
MATCH
(issue:Issue {state:"open"})
WHERE
date(issue.createdAt) <= date('20180713') AND NOT (issue:Issue)-[:HAS_ASSIGNEE]->(:User)
RETURN
issue
→ If not, then probably no one feels responsible for this issue.
If you want to contribute here are a few tips to get you started:
Build the GitHub-Issues plugin:
cd plugin
# Build a fat-JAR
mvn clean package
# Copy the resulting JAR into the jQAssistant CLI plugins folder
cp target/jqa-githubissues-plugin-0.1-jar-with-dependencies.jar ../run/jqassistant-commandline-neo4jv3-1.4.0/plugins/
Run code coverage via Corbertura:
mvn cobertura:cobertura
The coverage reports can be found under target/site/cobertura
.