GitHub - jqassistant-plugin/jqassistant-github-plugin: @jqassistant plugin to scan GitHub repositories

This is a GitHub scanner for [jQAssistant](https://jqassistant.org/). It enables jQAssistant to scan and analyze GitHub repositories.

Using the jQAssistant GitHub Plugin

Note

This plugin requires authentication to the GitHub API by one of the options of the underlying GitHub API Library, i.e., via

  • A property file in the user home directory (~/.github), or

  • Environment variables, e.g.,

    GITHUB_OAUTH

    An API token with at least repo:read permissions.

    GITHUB_LOGIN

    The username on GitHub (a login name is mandatory, though a token should be enough for authorization).

To be able to use the plug-in, it must be specified as a plug-in to jQAssistant. Additionally, at least one GitHub repository needs to be configured to be scanned. Optionally, the branch to scan may be configured using the scanner property github.repository.branch. This property defaults to main.

jqassistant:
  plugins:
    - group-id: org.jqassistant.plugin # (1)
      artifact-id: jqassistant-github-plugin
      version: ${jqassistant.github-plugin.version}
  scan:
    properties:
      github.repository.branch: master # (2)
    include:
      urls:
        - github:repository::https://github.com/shopizer-ecommerce/shopizer # (3)
  1. Dependency to the GitHub plugin

  2. The branch to scan

  3. The repository to scan

Labels

The plugin uses the following labels in the resulting graph:

Label Description

GitHub

Parent label for all nodes related to the GitHub-Issues plugin.

Branch

Represents a GitHub Branch.

Commit

Represents a GitHub Commit.

Issue

Represents a GitHub Issue.

Label

Represents a GitHub Label.

Milestone

Represents a GitHub Milestone which is a collection of Issues.

PullRequest

Represents a Pull Request. A Pull Request always is an Issue.

Release

Represents a GitHub Release.

Repository

Represents a GitHub Repository.

Tag

Represents a Git tag.

User

Represents a GitHub User.

Here are the possible relations between those labels:

Use Cases

Overview

List all your open Issues over multiple repositories:

List all your open Issues over multiple repositories

MATCH
    (r:GitHub:Repository)-[:HAS_ISSUE]->(i:GitHub:Issue {state:"OPEN"})
RETURN
    r.owner + "/" + r.name AS Repository, i.title AS Issue

Count open Issues per repository

MATCH
    (r:GitHub:Repository)-[:HAS_ISSUE]->(:GitHub:Issue {state:"OPEN"})
RETURN
    r.owner + "/" + r.name AS Repository, count(*) AS issueCount
ORDER BY
    issueCount DESC

List open issues per user

MATCH
    (:GitHub:Issue {state:"OPEN"})-[:HAS_ASSIGNEE]->(u:GitHub:User)
RETURN
    u.username AS UserName, count(*) AS OpenIssues

Issue quality

Show issues without description

MATCH
    (i:GitHub:Issue)
WHERE
    i.body = ""
RETURN
    i.number AS Issue, i.title AS Title

Show issues without labels

MATCH
    (i:GitHub:Issue)
WHERE
    NOT (i)-[:HAS_LABEL]->()
RETURN
    i.number AS Issue, i.title AS Title

Show durations it needed to resolve an issue

MATCH
    (i:GitHub:Issue{state: "CLOSED"})
RETURN
    i.number AS Issue, i.title AS Title, duration.between(i.createdAt, i.closedAt)

Show issues older than 1 month that are still open

MATCH
    (i:Issue {state:"OPEN"})
WHERE
    i.createdAt <= datetime()-duration('P30D')
RETURN
    i.number AS Issue, i.title AS Title

Why are these issues still open?

Let’s have a look at a few indicators:

Find open issues without labels

MATCH
    (i:GitHub:Issue {state:"OPEN"})
WHERE
    NOT (i)-[:HAS_LABEL]->(:GitHub:Label)
RETURN
    i.number AS Issue, i.title AS Title

Find open issues without assignee

MATCH
    (i:GitHub:Issue {state:"OPEN"})
WHERE
    NOT (i)-[:HAS_ASSIGNEE]->(:GitHub:User)
RETURN
    i.number AS Issue, i.title AS Title