Files
gitea-dashboard/docs/plans/v1.0.0-plan.md
sylvain e757c35767 docs(v1.0.0): version plan and ADR
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:43:29 +01:00

10 KiB

Plan de version v1.0.0 — gitea-dashboard

Objectif

Livrer un dashboard CLI fonctionnel qui affiche en une commande l'etat de tous les repos Gitea : issues ouvertes, derniere release, milestones. Premiere version utilisable.

Track

Major initial (v1.0.0, nouveau projet) : 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> (12) -> 13


Budget de scope

Critere Valeur
Max fichiers par phase 4
Total fichiers estimes 8 (4 modules + 4 tests)

Inclus

  • Client API Gitea avec auth token et pagination
  • Collecte des donnees : repos, issues (hors PRs), derniere release, milestones ouvertes
  • Affichage Rich : tableau repos + section milestones + indicateurs visuels
  • Point d'entree CLI avec configuration par variables d'environnement
  • Gestion des cas limites (repos sans release, sans milestone, forks, archives)

Exclus

  • Interface web ou GUI
  • Mode watch / rafraichissement automatique
  • Filtrage par owner/organisation
  • Modification de donnees Gitea (lecture seule)
  • Notifications ou alertes
  • Framework CLI (argparse, click, typer)

Differe (v1.1+)

  • Parallelisation des appels API (ThreadPoolExecutor)
  • Filtrage/tri des repos (par nom, activite, owner)
  • Cache des reponses API
  • Options CLI (--format, --filter, --sort)

Etapes skippees

Etape Nom Raison
12 Deploy Outil CLI local, pas de deploiement serveur

Phase 1 : Client API et collecte de donnees

Goal : Disposer d'un client API Gitea fonctionnel et d'un collecteur qui agrege les donnees de tous les repos.

Issues Gitea : fixes #1, fixes #2

Fichiers

Action Fichier Modifications Cross-references
Create src/gitea_dashboard/client.py Client API Gitea : auth, requetes GET, pagination collector.py (consommateur)
Create src/gitea_dashboard/collector.py Collecte et agregation des donnees repos client.py (dependance), display.py (producteur de donnees)
Create tests/test_client.py Tests unitaires du client API avec mocks client.py
Create tests/test_collector.py Tests unitaires du collecteur avec mocks collector.py

Interfaces

client.py

class GiteaClient:
    """Client API Gitea en lecture seule."""

    def __init__(self, base_url: str, token: str) -> None:
        """Initialise le client avec l'URL de base et le token API."""

    def get_repos(self) -> list[dict]:
        """Retourne tous les repos de l'utilisateur (pagination automatique).
        Endpoint: GET /api/v1/user/repos
        """

    def get_latest_release(self, owner: str, repo: str) -> dict | None:
        """Retourne la derniere release du repo, ou None si aucune.
        Endpoint: GET /api/v1/repos/{owner}/{repo}/releases/latest
        Gere HTTP 404 en retournant None.
        """

    def get_milestones(self, owner: str, repo: str) -> list[dict]:
        """Retourne les milestones ouvertes du repo.
        Endpoint: GET /api/v1/repos/{owner}/{repo}/milestones?state=open
        """

Methode privee interne pour la pagination :

    def _get_paginated(self, endpoint: str, params: dict | None = None) -> list[dict]:
        """Requete GET avec pagination automatique.
        Boucle tant que len(page) == limit (50).
        """

collector.py

@dataclass
class RepoData:
    """Donnees agregees d'un repo."""
    name: str
    full_name: str
    description: str
    open_issues: int       # open_issues_count - open_pr_counter
    is_fork: bool
    is_archived: bool
    is_mirror: bool
    latest_release: dict | None   # {tag_name, published_at} ou None
    milestones: list[dict]        # [{title, open_issues, closed_issues, due_on}]

def collect_all(client: GiteaClient) -> list[RepoData]:
    """Collecte les donnees de tous les repos.
    Pour chaque repo : enrichit avec release et milestones.
    """

Comportement attendu

  1. GiteaClient("http://192.168.0.106:3000", "token123") cree un client
  2. client.get_repos() retourne la liste complete (pagination transparente si > 50 repos)
  3. client.get_latest_release("admin", "mon-repo") retourne {"tag_name": "v1.0", "published_at": "..."} ou None
  4. collect_all(client) retourne une liste de RepoData pour chaque repo, meme ceux sans release ou milestone

Tests

  • test_client.py : mock de requests.Session pour tester auth header, pagination (1 page, 2 pages), 404 sur release
  • test_collector.py : mock de GiteaClient pour tester l'agregation, les cas limites (repo sans release, sans milestone, fork, archive)

Livrable

Le client peut interroger l'API Gitea et le collecteur produit une liste de RepoData prete pour l'affichage. Les tests passent.


Phase 2 : Affichage Rich et point d'entree CLI

Goal : Afficher les donnees collectees dans un dashboard terminal lisible et fournir le point d'entree executable.

Issues Gitea : fixes #3, fixes #4

Fichiers

Action Fichier Modifications Cross-references
Create src/gitea_dashboard/display.py Formatage et affichage Rich collector.py (consomme RepoData)
Modify src/gitea_dashboard/cli.py Orchestration : config -> client -> collecte -> affichage client.py, collector.py, display.py
Create tests/test_display.py Tests du formatage (capture console Rich) display.py
Create tests/test_cli.py Tests d'integration du point d'entree cli.py

Interfaces

display.py

from rich.console import Console

def render_dashboard(repos: list[RepoData], console: Console | None = None) -> None:
    """Affiche le dashboard complet dans le terminal.

    - Tableau principal : nom repo, indicateurs (fork/archive/mirror),
      issues ouvertes, derniere release (tag + date relative)
    - Section milestones : par repo ayant des milestones,
      nom, progression (closed/total), date echeance

    Le parametre console permet l'injection pour les tests.
    """

cli.py (modification)

import sys
import os

def main() -> None:
    """Point d'entree principal.

    1. Lit GITEA_URL (defaut: http://192.168.0.106:3000) et GITEA_TOKEN (requis)
    2. Cree le GiteaClient
    3. Collecte les donnees via collect_all()
    4. Affiche via render_dashboard()
    5. Gere les erreurs : config manquante, connexion refusee, timeout
    """

Comportement attendu

Execution nominale :

$ export GITEA_TOKEN=abc123
$ gitea-dashboard

                    Gitea Dashboard
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Repo             ┃ Issues ┃ Release             ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│ mon-projet       │      3 │ v1.2.0 (il y a 2j)  │
│ autre-repo [F]   │      0 │ —                    │
│ archive [A]      │      1 │ v0.1.0 (il y a 6m)  │
└──────────────────┴────────┴─────────────────────┘

  Milestones
  mon-projet / v2.0 : 3/5 (60%) — echeance 2026-04-01

Erreur de configuration :

$ gitea-dashboard
Erreur : GITEA_TOKEN non defini. Exportez la variable d'environnement.

Tests

  • test_display.py : capture de la sortie Rich via Console(file=StringIO()), verification du contenu (noms de repos, indicateurs, gestion des valeurs None)
  • test_cli.py : mock des variables d'environnement, mock du client API, verification des messages d'erreur

Livrable

gitea-dashboard est executable, affiche un dashboard lisible, et gere proprement les erreurs. Tous les tests passent.


Phase 3 : Smoke test et documentation

Goal : Valider le fonctionnement reel sur l'instance Gitea et documenter le projet.

Dependances : phases 1 et 2 terminees, acces a l'instance Gitea (192.168.0.106:3000)

Composants cles :

  • Test E2E manuel sur l'instance reelle
  • Checklist de validation (repos avec/sans release, avec/sans milestone, forks)
  • README.md a jour (installation, usage, configuration)
  • CHANGELOG.md pour la v1.0.0

Architecture des modules

Module Responsabilite Dependances
client.py Communication API Gitea (auth, requetes, pagination) requests
collector.py Agregation des donnees de tous les repos client.py
display.py Formatage et rendu terminal rich, collector.py (types)
cli.py Point d'entree, configuration, orchestration tous les modules

Risques d'audit

Zone Risque Severite estimee
client.py — pagination Boucle infinie si l'API repond toujours limit elements major
client.py — gestion erreurs Erreurs HTTP non-404 non gerees (500, timeout, connexion) major
cli.py — token en clair Affichage accidentel du token dans les logs/erreurs critical
collector.py — types Champs API manquants ou renommes entre versions Gitea minor

Issues Gitea rattachees

Issue Titre Phase
#1 Client API Gitea avec authentification et pagination Phase 1
#2 Collecte des donnees : repos, issues, releases, milestones Phase 1
#3 Affichage dashboard avec Rich (tableaux, couleurs) Phase 2
#4 Point d'entree CLI et configuration Phase 2

Milestone : v1.0.0


Dependances

Dependance Type Version
Python Runtime >= 3.10
requests Librairie >= 2.31
rich Librairie >= 13.0
pytest Dev >= 7.0
ruff Dev >= 0.4
Instance Gitea Service externe 1.25.1 a 192.168.0.106:3000