A Sphinx extension for linking to your project's issue tracker
npx @tessl/cli install tessl/pypi-sphinx-issues@5.0.0A Sphinx extension for linking to your project's issue tracker. Includes roles for linking to issues, pull requests, user profiles, commits, and PyPI packages, with built-in support for GitHub (though this works with other services like GitLab).
pip install sphinx-issuesimport sphinx_issuesExtension registration in conf.py:
extensions = [
# ...
"sphinx_issues"
]# docs/conf.py
# ...
extensions = [
# ...
"sphinx_issues"
]
# Path to GitHub repo {group}/{project} (note that `group` is the GitHub user or organization)
issues_github_path = "sloria/marshmallow"Then in reStructuredText documents:
See issue :issue:`42`
See issues :issue:`12,13`
See :issue:`sloria/konch#45`.
See PR :pr:`58`
Thanks to :user:`bitprophet` for the idea!
Fixed in :commit:`6bb9124d5e9dbb2f7b52864c3d8af7feb1b69403`.
:pypi:`sphinx-issues` - A Sphinx extension for linking to your project's issue tracker.Links to issue tracker issues with configurable URI templates and prefixes.
issue_role = IssueRole(config_prefix="issues")
"""
Sphinx role for linking to an issue. Must have
`issues_uri` or `issues_default_group_project` configured in conf.py.
Usage: :issue:`123` or :issue:`sloria/konch#123`
Parameters when called:
- name: Role name
- rawtext: Raw text content
- text: Issue reference (e.g., "123", "42,45", "sloria/konch#123")
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""Usage patterns:
:issue:123``:issue:42,45``:issue:sloria/konch#123``:issue:Fix critical bug <123>``Links to pull requests with configurable URI templates and prefixes.
pr_role = IssueRole(config_prefix="issues_pr")
"""
Sphinx role for linking to a pull request. Must have
`issues_pr_uri` or `issues_default_group_project` configured in conf.py.
Usage: :pr:`123` or :pr:`sloria/konch#43`
Parameters when called:
- name: Role name
- rawtext: Raw text content
- text: PR reference (e.g., "123", "42,45", "sloria/konch#43")
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""Usage patterns:
:pr:123``:pr:42,45``:pr:sloria/konch#43``:pr:Great feature <123>``Links to repository commits with shortened SHA display.
commit_role = IssueRole(config_prefix="issues_commit", pre_format_text=format_commit_text)
"""
Sphinx role for linking to a commit. Must have
`issues_commit_uri` or `issues_default_group_project` configured in conf.py.
Usage: :commit:`123abc456def` or :commit:`sloria/konch@123abc456def`
Parameters when called:
- name: Role name
- rawtext: Raw text content
- text: Commit reference (e.g., "123abc456def", "sloria/konch@123abc456def")
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""Usage patterns:
:commit:123abc456def`` (displays as @123abc4):commit:sloria/webargs@abc123def456``:commit:1.0.0 (2016-07-05) <170ce9>``Links to user profiles with configurable URI templates.
user_role = IssueRole(config_prefix="issues_user")
"""
Sphinx role for linking to a user profile. Defaults to linking to
GitHub profiles, but the profile URIs can be configured via the
issues_user_uri config value.
Usage: :user:`sloria` or :user:`Steven Loria <sloria>`
Parameters when called:
- name: Role name
- rawtext: Raw text content
- text: User reference (e.g., "sloria", "Steven Loria <sloria>")
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""Usage patterns:
:user:sloria`` (displays as @sloria):user:Steven Loria <sloria>``Links to PyPI package pages.
def pypi_role(name, rawtext, text, lineno, inliner, options=None, content=None):
"""
Sphinx role for linking to a PyPI package page.
Parameters:
- name: Role name
- rawtext: Raw text content
- text: Package name (e.g., "sphinx-issues")
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""Usage patterns:
:pypi:sphinx-issues``:pypi:Great Extension <sphinx-issues>``Main extension setup function that registers all roles and configuration options.
def setup(app):
"""
Sphinx extension setup function. Registers all roles and configuration options.
Parameters:
- app: Sphinx application instance
Returns:
dict: Extension metadata with version, parallel_read_safe, and parallel_write_safe flags
"""Automatically registers:
Control where links point to for different services:
# Issue tracker URI template
issues_uri = "https://github.com/{group}/{project}/issues/{issue}"
# Pull request URI template
issues_pr_uri = "https://github.com/{group}/{project}/pull/{pr}"
# Commit URI template
issues_commit_uri = "https://github.com/{group}/{project}/commit/{commit}"
# User profile URI template (defaults to GitHub sponsors)
issues_user_uri = "https://github.com/sponsors/{user}"Control the prefix symbols shown in rendered links:
# Issue number prefix (default: "#")
issues_prefix = "#"
# PR number prefix (default: "#")
issues_pr_prefix = "#"
# Commit prefix (default: "@")
issues_commit_prefix = "@"
# User prefix (default: "@")
issues_user_prefix = "@"Define default repository for relative references:
# GitHub repository path (legacy, group/project format)
issues_github_path = "sloria/marshmallow"
# Universal repository path (replaces issues_github_path)
issues_default_group_project = "sloria/marshmallow"Note: Only one of issues_github_path or issues_default_group_project should be set.
# docs/conf.py
extensions = ["sphinx_issues"]
# Default repo {group}/{project} of gitlab project
issues_default_group_project = "myteam/super_great_project"
issues_uri = "https://gitlab.company.com/{group}/{project}/-/issues/{issue}"
issues_prefix = "#"
issues_pr_uri = "https://gitlab.company.com/{group}/{project}/-/merge_requests/{pr}"
issues_pr_prefix = "!"
issues_commit_uri = "https://gitlab.company.com/{group}/{project}/-/commit/{commit}"
issues_commit_prefix = "@"
issues_user_uri = "https://gitlab.company.com/{user}"
issues_user_prefix = "@"All roles support external repository references using the format group/project{separator}reference:
sloria/konch#123sloria/konch#43sloria/konch@abc123def456Issue and PR roles support comma-separated lists:
See issues :issue:`12,13,14`
See PRs :pr:`42,45,58`All roles support custom anchor text:
:issue:`Fix critical bug <123>`
:pr:`Great feature <456>`
:commit:`1.0.0 Release <abc123>`
:user:`Steven Loria <sloria>`
:pypi:`Great Extension <sphinx-issues>`def format_commit_text(config, sha):
"""
Formats commit SHA to first 7 characters.
Parameters:
- config: Sphinx configuration object
- sha: Full commit SHA string
Returns:
str: Truncated SHA (first 7 characters)
"""
class IssueRole:
"""
Base class for creating issue tracker roles.
Attributes:
- ELEMENT_SEPARATORS (str): Valid separators "#@!"
- EXTERNAL_REPO_REGEX (Pattern): Regex for external repository references
"""
def __init__(self, config_prefix: str, pre_format_text: Callable[[Config, str], str] = None):
"""
Initialize IssueRole instance.
Parameters:
- config_prefix: Configuration prefix for URI and separator settings
- pre_format_text: Optional text formatting function
"""
def __call__(self, name, rawtext, text, lineno, inliner, options=None, content=None):
"""
Main role implementation method.
Parameters:
- name: Role name
- rawtext: Raw text content
- text: Reference text
- lineno: Line number in source
- inliner: Sphinx inliner object
- options: Optional rendering options
- content: Optional content list
Returns:
tuple: (list of nodes, list of messages)
"""
def make_node(self, name: str, issue_no: str, config: Config, options=None):
"""
Creates docutils reference nodes.
Parameters:
- name: Role name
- issue_no: Issue/PR/commit reference
- config: Sphinx configuration object
- options: Optional rendering options
Returns:
docutils.nodes.reference or None
"""
def format_text(self, config: Config, issue_no: str) -> str:
"""
Add supported separator in front of the issue or raise an error if invalid
separator is given.
Parameters:
- config: Sphinx configuration object
- issue_no: Issue number to format
Returns:
str: Formatted text with prefix
"""The extension validates configuration and raises helpful errors for: