Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.12"]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: ${{ matrix.python-version }}
- name: Install
run: python -m pip install -e ".[dev]"
- name: Lint
run: ruff check .
- name: Unit and contract tests
run: python -m pytest -q
- name: Consumer install test (fresh venv)
env:
GITHUBBOT_CORE_CONSUMER_TEST: "1"
run: python -m pytest -q tests/test_consumer_install.py
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Changelog / Änderungsprotokoll

Alle wesentlichen Änderungen an diesem Projekt werden hier dokumentiert.
All notable changes to this project are documented here.
Format: [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), [Semantic Versioning](https://semver.org/).

## [Unreleased]

## [0.1.0] - 2026-10-11

### Hinzugefügt / Added

- Installierbares Paket `githubbot-core` mit CLI `githubbot-core` und JSON-Ergebnishülle
`githubbot-core.result/v1` / installable package with CLI and JSON result envelope.
- Issue-Triage, Duplikaterkennung, PR-Zusammenfassung, Health-/Traffic-/Sterne-Berichte /
issue triage, duplicate detection, PR summary, health/traffic/star reports.
- Vorschau/Ausführen-Vertrag mit Rechteobergrenze, Belegen und Idempotenz /
preview/apply contract with permission ceiling, receipts and idempotency.
- Geschichtete Konfiguration, Obergrenzen nur einengbar / layered configuration, ceilings narrow-only.
- Plugin-SPI v1 (Entry-Point-Gruppe `githubbot_core.plugins`) / plugin SPI v1.
- Credential-Adapter (Umgebung, `gh auth token`) mit Schwärzung / credential adapter with redaction.
- Namensraumunabhängiges Exact-SHA-Review-Gate samt Workflow-Scaffold /
namespace-independent exact-SHA review gate with workflow scaffold.
73 changes: 73 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Verhaltenskodex / Code of Conduct

## Deutsch

### Unser Versprechen

Wir als Mitglieder, Beitragende und Projektverantwortliche verpflichten uns,
die Teilnahme an unserer Community zu einer belästigungsfreien Erfahrung für
alle zu machen, unabhängig von Alter, Körpergröße, sichtbarer oder
unsichtbarer Behinderung, ethnischer Zugehörigkeit, Geschlechtsmerkmalen,
Geschlechtsidentität und -ausdruck, Erfahrungsgrad, Bildung,
sozioökonomischem Status, Nationalität, persönlichem Aussehen, Herkunft,
Religion oder sexueller Identität und Orientierung.

### Unsere Standards

Beispiele für Verhalten, das zu einem positiven Umfeld beiträgt:
- Verwendung einladender und inklusiver Sprache
- Respektvoller Umgang mit unterschiedlichen Standpunkten und Erfahrungen
- Konstruktive Kritik höflich annehmen
- Fokus auf das Beste für die Community

Inakzeptables Verhalten umfasst:
- Trolling, beleidigende Kommentare und persönliche oder politische Angriffe
- Öffentliche oder private Belästigung
- Veröffentlichung privater Informationen anderer ohne ausdrückliche Erlaubnis

### Meldung und Durchsetzung

Wenn Sie problematisches Verhalten beobachten, melden Sie es bitte über die im
jeweiligen Repository vorgesehenen GitHub-Kanäle oder nehmen Sie direkt über
GitHub Kontakt mit den Maintainern auf. Sensible Meldungen sollen nicht in
öffentlichen Issues gepostet werden.

Alle Beschwerden werden geprüft und angemessen bearbeitet.

---

## English

### Our Pledge

We as members, contributors, and project maintainers pledge to make
participation in our community a harassment-free experience for everyone,
regardless of age, body size, visible or invisible disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.

### Our Standards

Examples of behavior that contributes to a positive environment:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community

Unacceptable behavior includes:
- Trolling, insulting comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission

### Reporting and Enforcement

If you observe abusive behavior, please use the GitHub contact channels
provided by the repository or contact the maintainers directly through GitHub.
Sensitive reports should not be posted in public issues.

All complaints will be reviewed and handled appropriately.

---

*Basierend auf dem [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/)*
87 changes: 87 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Beitragsrichtlinie / Contributing Guide

## Deutsch

Vielen Dank für Ihr Interesse, zu diesem Projekt beizutragen!

### Wie Sie beitragen koennen

1. **Bug melden:** Erstellen Sie ein Issue mit dem Label `bug`
2. **Feature vorschlagen:** Erstellen Sie ein Issue mit dem Label `enhancement`
3. **Code beitragen:** Erstellen Sie einen Pull Request

### Pull Requests

1. Forken Sie das Repository
2. Erstellen Sie einen Feature-Branch: `git checkout -b feature/mein-feature`
3. Committen Sie Ihre Änderungen: `git commit -m "Beschreibung der Änderung"`
4. Pushen Sie den Branch: `git push origin feature/mein-feature`
5. Erstellen Sie einen Pull Request

### Lizenz- und Rechtehinweise

Falls dieses Projekt ein CLA, DCO oder eine andere Beitragsvereinbarung nutzt,
ist dies im Repository gesondert dokumentiert. Ohne ausdrückliche Zusatzregel
gelten Pull Requests unter der Lizenz des Projekts.

### Code-Richtlinien

- Python: PEP 8 Stil, nur Standardbibliothek zur Laufzeit
- Encoding: UTF-8 für alle Dateien
- Sprache: Code und Kommentare auf Deutsch oder Englisch
- Keine hardcoded Pfade oder API-Keys

### Erste Schritte

```bash
pip install -e ".[dev]"
python -m pytest
ruff check .
```

Schreibende Funktionen laufen ausschließlich über `githubbot_core.actions` (Vorschau/Ausführen,
Rechteobergrenze, Belege). Neue Schreibaktionen bitte dort ergänzen, nicht direkt per API.

---

## English

Thank you for your interest in contributing to this project!

### How to Contribute

1. **Report bugs:** Create an issue with the `bug` label
2. **Suggest features:** Create an issue with the `enhancement` label
3. **Contribute code:** Create a Pull Request

### Pull Requests

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-feature`
3. Commit your changes: `git commit -m "Description of change"`
4. Push the branch: `git push origin feature/my-feature`
5. Create a Pull Request

### Licensing and Contribution Terms

If this project uses a CLA, DCO, or any other contribution agreement, it
should be documented separately in the repository. Unless stated otherwise,
pull requests are understood to be submitted under the project's license.

### Code Guidelines

- Python: PEP 8 style, standard library only at runtime
- Encoding: UTF-8 for all files
- Language: Code and comments in German or English
- No hardcoded paths or API keys

### Getting Started

```bash
pip install -e ".[dev]"
python -m pytest
ruff check .
```

Every write goes through `githubbot_core.actions` (preview/apply, permission
ceiling, receipts). Please add new write actions there, not as direct API calls.
168 changes: 168 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# githubbot-core

**English** | [Deutsch](README_de.md)

Neutral, installable core for GitHub repository maintenance: issue triage, duplicate detection,
pull-request summaries, read-only health/traffic/star reports, a preview/apply contract for every
write, a plugin SPI and signed exact-SHA review receipts. Pure Python standard library, no runtime
dependencies.

> Status: alpha (0.1.0). The CLI, the JSON result envelope and SPI version 1 are the contract;
> everything else may still change.

## Features

- **Triage** – classifies open issues with configurable keyword criteria and plans labels and
auto comments (with an invisible marker so a comment is never posted twice).
- **Duplicates** – Jaccard similarity on word tokens, offline on a JSON file.
- **Pull-request summary** – size check and summary; project-specific policy checks come from
plugins only.
- **Reports** – Dependabot / Actions / issues / PRs / code- and secret-scanning health, traffic
(14 days) and star rankings. Read-only.
- **Preview / apply** – nothing is written unless you pass `--apply`. Every write is an `Action`,
checked against a permission ceiling, and leaves a receipt. With a receipt store, repeated runs
skip actions that were already applied.
- **Plugin SPI** – extensions propose actions or add pull-request checks through an entry point.
A missing extension is reported as "not available"; the core keeps working.
- **Credential adapter** – tokens come from `GH_TOKEN` / `GITHUB_TOKEN` or `gh auth token` at
runtime. Nothing is stored or bundled.
- **Review gate** – signed (OpenSSH), time-limited receipts bound to repository, PR number and the
exact head SHA, verified by a GitHub Actions workflow that never executes pull-request code.

## Installation

Requirements: Python 3.10+, the [GitHub CLI](https://cli.github.com/) (`gh auth login`) for
commands that talk to GitHub, OpenSSH `ssh-keygen` for review-gate signatures.

```bash
pip install git+https://github.com/dev-bricks/githubbot-core.git
githubbot-core --version
githubbot-core doctor
```

From a checkout: `pip install .` (development: `pip install -e ".[dev]"`).

## Usage

```bash
# Read-only reports
githubbot-core health --repo owner/repo --repo owner/other
githubbot-core traffic --repo owner/repo
githubbot-core stars --repo owner/repo

# Triage: preview (default) -> apply the very same plan
githubbot-core triage --repo owner/repo
githubbot-core --json triage --repo owner/repo # note plan_sha256
githubbot-core triage --repo owner/repo --apply --expect-plan <plan_sha256> --receipts receipts.jsonl

# Offline helpers (JSON file in gh or REST issue format)
githubbot-core classify --input issues.json
githubbot-core duplicates --input issues.json --threshold 0.8

# Pull-request summary (+ checks from installed plugins)
githubbot-core review-pr --repo owner/repo --pr 12

# Plugins
githubbot-core plugins
githubbot-core run <plugin> [--plugin-arg ...] [--apply]
```

`python -m githubbot_core ...` works the same way.

### JSON contract

With `--json` every command prints one envelope:

```json
{"schema": "githubbot-core.result/v1", "command": "triage", "ok": true,
"mode": "preview", "data": {"plan_sha256": "…", "actions": [], "writes": 0}, "errors": []}
```

`mode` is `read`, `preview` or `apply`. Exit codes: `0` ok, `1` runtime error (for example GitHub
not reachable or a write failed), `2` configuration or usage error, `3` plugin not available.

The Python API is the package itself: `githubbot_core.triage.IssueTriage`,
`githubbot_core.actions.preview/apply`, `githubbot_core.health.RepoHealthCollector`,
`githubbot_core.plugins`, `githubbot_core.review_gate`, `githubbot_core.credentials`.

## Configuration and permissions

The packaged defaults (`githubbot_core/default_config.json`) are extended with `--config file.json`
layers, applied in order (for example a profile, then a host-local file). Ordinary keys are merged,
later layers win. Permission ceilings are different: a later layer may only **narrow**
`permissions.ceiling` and `permissions.api_write_prefixes`; an attempt to widen them is an error,
not a silent override. `permissions.enabled` must stay inside the ceiling.

| Action kind | Default | Executes |
|---|---|---|
| `issue.add_labels` | enabled | `POST /repos/{repo}/issues/{n}/labels` |
| `issue.comment` | enabled | `POST /repos/{repo}/issues/{n}/comments` |
| `api.request` | disabled | any write method on an endpoint that starts with one of `permissions.api_write_prefixes` |

```json
{"permissions": {"enabled": ["issue.add_labels", "issue.comment", "api.request"],
"api_write_prefixes": ["user/starred/"]}}
```

## Writing a plugin (SPI v1)

Declare an entry point in the group `githubbot_core.plugins` that points to a zero-argument
factory:

```toml
[project.entry-points."githubbot_core.plugins"]
my-extension = "my_extension:create"
```

```python
from githubbot_core.actions import Action
from githubbot_core.plugins import SPI_VERSION

class MyExtension:
name = "my-extension"
spi_version = SPI_VERSION

def describe(self):
return {"version": "1.0.0", "capabilities": ["plan"]}

def plan(self, ctx): # ctx.config, ctx.transport (read-only), ctx.args
data, error = ctx.transport.get("repos/owner/repo")
return [Action("api.request", {"method": "PUT", "endpoint": "user/starred/owner/repo"},
reason="example")]

def pr_policy_checks(self, pr, files, diff): # optional
return [("no_large_binaries", True, "OK")]

def create():
return MyExtension()
```

Plugins never write themselves: the core previews or applies their plan under the configured
permissions. During planning they only get a read-only transport.

## Review gate

`githubbot-core gate-scaffold --dest <checkout> [--namespace name]` previews, and with `--apply`
writes, `.github/workflows/review-gate.yml` plus the standalone verifier
`.github/review-gate/review_gate.py` into a target repository. Receipts are created, signed,
verified and dispatched with `githubbot-core review-gate create|sign|verify|dispatch`. Details,
trust boundaries and rollback: [docs/REVIEW_GATE.md](docs/REVIEW_GATE.md).

## Development

```bash
pip install -e ".[dev]"
python -m pytest # unit and contract tests
ruff check .
GITHUBBOT_CORE_CONSUMER_TEST=1 python -m pytest tests/test_consumer_install.py # fresh-venv install test
```

## Provenance

Written by Lukas Geiger with AI assistance (code generation and review by large language models),
extracted from a private maintenance tool and rebuilt as a new tree without that tool's history.
No third-party code is included; see [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).

## License

[MIT](LICENSE)
Loading
Loading