52 lines
3.2 KiB
Python
52 lines
3.2 KiB
Python
import requests
|
|
from pathlib import Path
|
|
|
|
p = Path('/root/.openclaw/secrets/gitea.env')
|
|
env = {}
|
|
for line in p.read_text().splitlines():
|
|
if '=' in line:
|
|
k, v = line.split('=', 1)
|
|
env[k.strip()] = v.strip()
|
|
token = env['GITEA_TOKEN']
|
|
base = 'http://192.168.6.31:3000/api/v1'
|
|
repo = 'pino/sillyhome-next'
|
|
session = requests.Session()
|
|
session.headers.update({'Authorization': f'token {token}', 'Content-Type': 'application/json'})
|
|
|
|
label_names = ['enhancement','bug','documentation','ai','integration','infra','frontend','backend','tests','devops']
|
|
labels = {}
|
|
for name in label_names:
|
|
r = session.post(f'{base}/repos/{repo}/labels', json={'name': name, 'color': '0e8a16'})
|
|
if r.status_code not in (201, 200):
|
|
print('label create failed', name, r.status_code, r.text[:120])
|
|
else:
|
|
labels[name] = r.json()['id']
|
|
print('labels:', labels)
|
|
|
|
issues = [
|
|
('ARCH-001: Projektstruktur und Entwicklungsrichtlinien', '## Aufgabe\n- CONTRIBUTING.md vervollständigen\n- Sprint-Rhythmus festlegen: 2 Wochen, Review Montag\n\n## Akzeptanz\n- CONTRIBUTING.md aktuell', [labels.get('documentation')], 10),
|
|
('ARCH-002: ADRs finalisieren und Entscheidungen fixieren', '## Aufgabe\n- ADR-005 Explainability\n- ADR-006 Retention\n\n## Akzeptanz\n- Mindestens 6 ADRs dokumentiert', [labels.get('documentation')], 10),
|
|
('INFRA-001: Docker Compose Grundgerüst für lokalen Betrieb', '## Aufgabe\n- docker-compose.yml für API, Scheduler, Worker\n- .env.example und README-Quickstart\n\n## Akzeptanz\n- Lokaler Start in <5 Minuten', [labels.get('infra'), labels.get('devops')], 10),
|
|
('DOC-001: README, CHANGELOG und Release-Checkliste pflegen', '## Aufgabe\n- README finalisieren\n- CHANGELOG starten\n- Release-Checkliste anlegen', [labels.get('documentation')], 10),
|
|
('INT-001: Home Assistant Datenintegration (REST + Recorder-Lesezugriff)', '## Aufgabe\n- HA REST Client\n- Historische States auslesen\n- Entities erkennen\n\n## Akzeptanz\n- Sensoren/Aktoren erkannt', [labels.get('integration'), labels.get('backend')], 11),
|
|
('ML-001: Datenvorverarbeitung und Feature-Pipeline', '## Aufgabe\n- Normalisierung und Zeitfeatures\n- Trainingsformat definieren\n\n## Akzeptanz\n- Reproduzierbare Transformation', [labels.get('backend'), labels.get('ai')], 11),
|
|
('ML-002: Regelbasierte Empfehlungen (Ebene 1)', '## Aufgabe\n- Heuristiken implementieren\n- Empfehlungs-API\n\n## Akzeptanz\n- Erste Empfehlungen ausgespielt', [labels.get('ai'), labels.get('backend')], 11),
|
|
('API-001: FastAPI-Kern und OpenAPI-Spezifikation', '## Aufgabe\n- FastAPI Grundgerüst\n- Basisendpunkte und Swagger\n\n## Akzeptanz\n- Swagger UI erreichbar', [labels.get('backend'), labels.get('infra')], 11),
|
|
]
|
|
|
|
existing = session.get(f'{base}/repos/{repo}/issues?state=all&per_page=100').json()
|
|
existing_titles = {i['title'] for i in existing}
|
|
|
|
for title, body, label_ids, milestone_id in issues:
|
|
if title in existing_titles:
|
|
print('skip existing', title)
|
|
continue
|
|
payload = {
|
|
'title': title,
|
|
'body': body,
|
|
'labels': [lid for lid in label_ids if lid],
|
|
'milestone': milestone_id,
|
|
}
|
|
r = session.post(f'{base}/repos/{repo}/issues', json=payload)
|
|
print('issue', title, r.status_code, r.text[:120] if r.status_code not in (201,) else 'created')
|