Skip to main content

heinzel-github

Read pull requests and issues from GitHub, the code-host and tracker capabilities (ADR 0028): a first-party Heinzelmännchen plugin. It is independently released and installed explicitly:

hz system plugin add github --confirm             # a compatible plugin release; run it again to upgrade
hz system plugin remove heinzel-github

Set up

The adapter talks to GitHub only through the GitHub CLI gh (2.40.0 or later), which owns authentication (ADR 0035). It reads what you can read, as you: no app to register, no token to create or store. Install gh and log in once:

gh auth login                           # or: gh auth login --hostname ghe.example.com

The adapter acts with whatever that login may do, which is usually more than reading; it only ever sends GET requests. As for any gh command, a GH_TOKEN or GITHUB_TOKEN (GH_ENTERPRISE_TOKEN for a GitHub Enterprise Server) in your environment takes precedence over the stored login: it is gh's own variable, passed to gh and never read by Heinzelmännchen. If you stored a token for an earlier version, remove it: hz system credential remove github-token --service github (or unset HZ_CREDENTIAL_GITHUB_GITHUB_TOKEN).

Bind the adapter in your user configuration, never in a project hz.toml, which Heinzelmännchen ignores for bindings:

hz system config set capabilities.code_host github
hz system config set capabilities.tracker github

which writes

[capabilities]
code_host = "github"
tracker = "github"

Or per shell: HZ_CAPABILITIES__CODE_HOST=github, HZ_CAPABILITIES__TRACKER=github.

For GitHub Enterprise Server, name its host in your user configuration or HZ_GITHUB__HOST; the adapter passes it to gh as --hostname and GH_HOST, so gh uses its login for that host:

hz system config set github.host ghe.example.com

or in the file (api_url from earlier versions is refused; host replaced it):

[github]
host = "ghe.example.com"
gh = "gh"      # the GitHub CLI: a name on PATH (absolute entries only) or an absolute path
timeout = 60   # seconds per gh call

host, gh and timeout are ignored in a project hz.toml, so a repository can't send your login elsewhere or pick the program that runs. The adapter's hosts come from it: hz system capability list shows api.github.com, or your GitHub Enterprise Server's host.

Is it connected?

Bound automatically while it is the only installed adapter of a capability (usually code-host; tracker once another tracker is installed needs a choice), ADR 0055. hz system connector list (or Settings → Connectors in hz ui) shows whether gh is logged in and as whom, read from gh's hosts file without asking GitHub; hz system connector test github asks GitHub who gh is (gh api user, 15 s at most), and only when you run it.

Use

Workflows ask for code-host and tracker, never for GitHub:

from datetime import datetime

from heinzel import CodeHost, Module, PullRequest, Window

module = Module("digest", "Weekly digest.", requires=["code-host:read", "tracker:read"])


@module.operation
def merged(code_host: CodeHost, since: datetime, until: datetime) -> list[PullRequest]:
    """Pull requests merged this week."""
    return code_host.merged_pull_requests("acme/widgets", Window(since=since, until=until))
Method Capability gh api call
merged_pull_requests(repository, window) code-host:read repos/{owner}/{repo}/pulls?state=closed&sort=updated&direction=desc, kept when merged_at is in the window; paging stops before the window
issues_updated(project, window) tracker:read repos/{owner}/{repo}/issues?state=all&since=...&sort=updated&direction=asc, without pull requests

Repositories and projects are written owner/repo; windows are half-open [since, until) with timezone-aware times; results are oldest first. The adapter pages with the API's page and per_page parameters rather than gh api --paginate, so it can stop as soon as the window is covered. A call reads at most 100 pages of 100 (10,000 items), 50 MiB in all and ten times github.timeout, then fails and says what to ask for instead: merged pull requests page through every pull request updated since since, even after until, so they need a window that starts more recently; issues stop at until, so they need a shorter window. Why the pulls list and not the search API: ADR 0033; why gh: ADR 0035.

hz github info                  # this plugin, its version and the GitHub host it reads
hz system capability list       # who reads what, through which adapter and hosts
hz system doctor                # gh on PATH, its version and login, the bindings; never contacts GitHub

Errors say what to do: no gh, or one too old, names where to get it; no login, or a login GitHub rejects, names gh auth login --hostname <host>; a rate limit says to wait and how to see when it resets; a missing or forbidden repository says to check the spelling and what your account can see; a slow call names the timeout setting.

How gh is run: with an argument list, never a shell, from your home directory, in its own process group, stopped (SIGTERM, then SIGKILL) at the timeout, with its output capped, and with an allowlisted environment: never Heinzelmännchen's HZ_CREDENTIAL_* variables or debug switches such as GH_DEBUG, which would print request headers. Doctor runs only gh --version and looks for the host in gh's hosts file (or a token variable gh reads); it never runs a command that prints a token. Everything GitHub or gh says is redacted of anything shaped like a GitHub token, stripped of control and bidirectional characters, and only then cut to length; every string the adapter returns is cleaned too.

Development and release commands: repository guide.

Migration provenance: heinzel, before the 0.9 plugin-boundary migration.

Metadata

Release files for heinzel-github 0.9.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for heinzel-github 0.9.1
File Size Uploaded Provenance Actions
heinzel_github-0.9.1.tar.gz 84.5 kB Without provenance Details for heinzel_github-0.9.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for heinzel-github 0.9.1
File Interpreter ABI Platform Actions
heinzel_github-0.9.1-py3-none-any.whl Python 3 none any Details for heinzel_github-0.9.1-py3-none-any.whl

Total release size: 109.2 kB

Release files / heinzel_github-0.9.1.tar.gz

Download URL heinzel_github-0.9.1.tar.gz
Size 84.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e90639a4752313e198d3e7391ce91e9ca069e97057fc5a23a907e3279f8c346b
BLAKE2b-256 checksum
How to use checksums
e9c7e196089a40b1d50cc3eec6e9161035e4aa79d59f0751112ba1d87476c8de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / heinzel_github-0.9.1-py3-none-any.whl

Download URL heinzel_github-0.9.1-py3-none-any.whl
Size 24.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
407fa942d8253f8e5ccb646f2f3ef3af2b79b9b0143ebcc3ef24e2d317056dfa
BLAKE2b-256 checksum
How to use checksums
b95f12997eb1d69b711da976b3b342cdea4e9c7c037f97b6a33577d1ad3eb9c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for heinzel-github 0.9.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.9.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page