GitHub Issues¶
The GitHub connector provides four commands:
ubconnect github from-github: import issues from GitHub into a Sphinx-Needsneeds.json.ubconnect github to-github: create GitHub issues from selected needs and patch the source RST with the new issue numbers.ubconnect github validate-issue-refs: cross-check:issue:references on existing needs against the GitHub issue tracker.ubconnect github sync-issue-refs: reconcile GitHub sub-issues into the:issue:lists of the needs that own them.
Note
The github connector requires an active ubConnect license. See
License configuration for activation instructions.
Authentication¶
The connector reads its personal access token from the GH_TOKEN
environment variable, falling back to GITHUB_TOKEN. There is no
TOML field for the token.
The token must be a GitHub Personal Access Token with the following scope:
repo— for private repositories.public_repo— sufficient for public repositories only.
Fine-grained PATs work with the equivalent Issues: Read permission.
from-github¶
Imports issues into a Sphinx-Needs-compatible needs.json. Each
imported issue produces a primary need carrying an :issue: field set
to its GitHub issue number, so the output can be validated directly with
validate-issue-refs.
$ ubconnect github from-github --config ubproject.toml
The config declares where to import from and how to shape the output; per-run what to import (milestone, labels, a named set of issues) is supplied via CLI flags so one config can drive many imports.
Filter flags (from-github)¶
Flag |
Effect |
|---|---|
|
Limit the import to issues in this milestone (matched by title;
accepts |
|
Limit the import to issues carrying this label. Repeat the flag to require multiple labels (GitHub’s AND semantics). |
|
Import only the named issues. Each value is either an issue
number ( |
Examples:
# Import all issues in milestone "v1.0" labelled both "bug" and "P1"
$ ubconnect github from-github -c ubproject.toml \
--milestone v1.0 --label bug --label P1
# Import three specific issues by number / URL
$ ubconnect github from-github -c ubproject.toml \
--issue 1001 \
--issue https://github.com/owner/name/issues/1005 \
--issue 1009
Configuration¶
[ubconnect.from_github_issues]
repo = "owner/name"
requirements_section_aliases = ["Acceptance Criteria"]
outdir = "_build"
id_prefix = "GH_"
timeout_seconds = 30
Configuration options:
Field |
Type |
Default |
Description |
|---|---|---|---|
|
string |
required |
Repository in |
|
list[string] |
|
Markdown headings (case-folded) that mark a section whose
bullets become |
|
path |
directory of config file |
Output directory for |
|
string |
|
Prefix for emitted need ids (issue number is appended). |
|
int |
|
Per-request HTTP timeout for the GitHub API. |
Consuming the output in Sphinx-Needs¶
from-github writes a Sphinx-Needs needs.json. To render it, import
it into a Sphinx-Needs build with the needimport directive.
The consuming project’s conf.py must declare three things: the need
types the connector emits, the satisfies link, and the provenance
fields written onto every need. Two of those fields are not strings.
issue is an integer (the GitHub issue number, read back by
validate-issue-refs) and github_labels is an array, so they must
be declared with typed needs_fields (Sphinx-Needs 8). A plain
string-only needs_extra_options declaration is not sufficient.
# conf.py
extensions = ["sphinx_needs"]
# One entry per type the connector emits. With the default
# configuration that is "req" for issues and "spec" for bullets.
# Adjust to match fallback_type, bullet_type and type_mapping.
needs_types = [
{"directive": "req", "title": "Requirement", "prefix": "R_",
"color": "#BFD8D2", "style": "node"},
{"directive": "spec", "title": "Specification", "prefix": "S_",
"color": "#FEDCD2", "style": "node"},
]
needs_links = {
"satisfies": {"incoming": "satisfied by", "outgoing": "satisfies"},
}
needs_fields = {
"content_format": {"schema": {"type": "string"}},
"issue": {"schema": {"type": "integer"}},
"github_url": {"schema": {"type": "string"}},
"github_author": {"schema": {"type": "string"}},
"github_labels": {"schema": {"type": "array",
"items": {"type": "string"}}},
}
Import the file and render it from any document:
.. needimport:: needs.json
.. needtable::
:columns: id, title, type, satisfies
:style: table
Warning
If the provenance fields are not declared as typed needs_fields,
needimport drops every need that carries them. The drop is silent:
there is no error and no warning. The only visible symptom is
unknown outgoing link warnings for the satisfies links whose
target needs were dropped.
validate-issue-refs¶
Cross-checks :issue: extra fields on existing needs against the
GitHub issue tracker. Reports issues that:
404 (do not exist or are inaccessible) as failures (exit code 1).
Are closed on GitHub while the referencing need is still open as warnings (exit code 0 by default; promoted to 1 with
--strict).
$ ubconnect github validate-issue-refs --config ubproject.toml
$ ubconnect github validate-issue-refs --config ubproject.toml --strict
Flags (validate-issue-refs)¶
Flag |
Effect |
|---|---|
|
Promote closed-issue warnings to failures (exit code 1). |
|
Do not exit with code 1 when some needs have no |
|
Also report DRIFT: GitHub sub-issues that exist under a
tracked parent but are absent from the |
Configuration¶
[ubconnect.validate_github_issues]
repo = "owner/name"
needsjson_path = "_build/needs.json"
open_status_values = ["open", "in_progress"]
timeout_seconds = 30
[ubconnect.validate_github_issues.lifecycle]
done_status = ["implemented", "verified"]
Configuration options:
Field |
Type |
Default |
Description |
|---|---|---|---|
|
string |
required |
Repository in |
|
path |
required |
Path to the |
|
list[string] |
|
Need |
|
int |
|
Per-request HTTP timeout for the GitHub API. |
|
string or list[string] |
not set |
When all GitHub issues linked to a need are closed but the need’s
|
to-github¶
Creates GitHub issues from selected needs. One issue is created per
matched need by default. After creation the command patches the source
RST file in place, appending the new issue number to the need’s
:issue: field so the document stays in sync with the tracker.
$ ubconnect github to-github -c ubproject.toml \
--needsjson _build/needs.json \
--need REQ_001 --need REQ_002
# Dry run: print what would be created without touching GitHub or RST
$ ubconnect github to-github -c ubproject.toml \
--needsjson _build/needs.json \
--need "REQ_*" --dry
Flags (to-github)¶
Flag |
Effect |
|---|---|
|
Path to the TOML config file. Required. |
|
Path to the |
|
Need id or fnmatch glob to select needs for creation. Repeat to
select multiple. Examples: |
|
Label to apply to every created issue. Repeat for multiple labels. Labels must already exist in the repository. |
|
Create a new issue even when the need already carries an
|
|
Print what would be created (title, body preview, labels) but do not call the GitHub API and do not modify any RST file. |
Configuration¶
[ubconnect.to_github_issues]
repo = "owner/name"
template_path = ".github/ISSUE_TEMPLATE/feature.md"
content_marker = "Description"
timeout_seconds = 30
Configuration options:
Field |
Type |
Default |
Description |
|---|---|---|---|
|
string |
required |
Repository in |
|
path |
not set |
Path to a GitHub issue template (Markdown). When set, the need’s
content is inserted after the heading named by |
|
string |
|
Heading text under which the need’s content is inserted when
|
|
int |
|
Per-request HTTP timeout for the GitHub API. |
RST patching¶
After each successful issue creation the command performs an atomic
write to the source RST file that defines the need, appending the new
issue number to the :issue: field. The patch is applied before the
next issue is created so a partial run leaves the RST consistent with
what was actually created on GitHub.
sync-issue-refs¶
Reconciles native GitHub sub-issues into the :issue: lists of the
needs that own them. For each need that already has a :issue:
value, the command fetches any sub-issues linked under that parent on
GitHub and patches the source RST file with the discovered numbers.
This is useful when issues are created or linked directly in GitHub
rather than through to-github, and you want the RST to stay in
sync without running a full validate-issue-refs cycle first.
$ ubconnect github sync-issue-refs --config ubproject.toml
Flags (sync-issue-refs)¶
Flag |
Effect |
|---|---|
|
Path to the TOML config file. Required. |
Configuration¶
sync-issue-refs reuses the [ubconnect.validate_github_issues]
config section. No separate section is needed.
[ubconnect.validate_github_issues]
repo = "owner/name"
needsjson_path = "_build/needs.json"
timeout_seconds = 30
:issue: field schema¶
The :issue: extra field is now a list of integers. A single
integer value is still accepted when reading existing needs files so
that documents authored before this change continue to work. Going
forward, author :issue: as a list even when there is only one
linked issue:
.. req:: My requirement
:id: REQ_001
:issue: [42]
.. req:: Requirement linked to two issues
:id: REQ_002
:issue: [42, 99]
Declare the field in conf.py as an array so Sphinx-Needs stores it
correctly:
needs_fields = {
"issue": {"schema": {"type": "array", "items": {"type": "integer"}}},
}