Ajoute le README et le modele de configuration
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# Migration Gogs → Gitea (figureslibres.io)
|
||||
|
||||
Scripts utilisés pour migrer les dépôts d'une instance Gogs vers une instance Gitea
|
||||
sur le même serveur (YunoHost), en conservant les propriétaires d'origine.
|
||||
|
||||
**Portée volontairement limitée à :**
|
||||
- les dépôts git (branches, tags, historique complet) ;
|
||||
- les collaborateurs (contributeurs) de chaque dépôt ;
|
||||
- les webhooks ;
|
||||
- les dates de création/mise à jour affichées.
|
||||
|
||||
**Explicitement hors scope** : issues, wiki, labels, milestones, releases, pull
|
||||
requests. Les webhooks pointant vers des services internes avec secret non exposé
|
||||
par l'API (ex: Kanboard) sont exclus par défaut.
|
||||
|
||||
## Contexte
|
||||
|
||||
Gogs et Gitea tournent tous les deux en local sur le même serveur (loopback,
|
||||
`127.0.0.1`), ce qui permet de scripter la migration sans jamais passer par les
|
||||
domaines publics ni par le SSO. Le script part du principe que les comptes
|
||||
utilisateurs (individus) sont déjà identiques des deux côtés (ex: synchronisés via
|
||||
un LDAP commun) — il ne crée jamais de compte utilisateur automatiquement. Les
|
||||
organisations, en revanche, peuvent être créées automatiquement si absentes.
|
||||
|
||||
### Pièges rencontrés (et déjà gérés par le script)
|
||||
|
||||
- **L'authentification HTTP Basic Auth de l'API Gogs est cassée sur cette
|
||||
instance** (401 identique avec de bons ou de mauvais identifiants) → l'API Gogs
|
||||
s'utilise donc avec un **token**, jamais avec login/mot de passe.
|
||||
- **`GET /api/v1/repos/search` de Gogs ne fait pas une vraie recherche
|
||||
site-wide**, même avec un compte admin : il ne renvoie que les dépôts publics +
|
||||
ceux du compte du token. La découverte se fait donc propriétaire par
|
||||
propriétaire (`/users|orgs/{login}/repos`), en partant de la liste des comptes
|
||||
connus côté Gitea.
|
||||
- **Les dépôts privés d'un propriétaire n'apparaissent dans cette liste que si le
|
||||
compte utilisé par le script a explicitement accès au dépôt** (ajouté comme
|
||||
collaborateur) — l'admin ne "voit" pas tout par magie via cet endpoint.
|
||||
- **`GET /api/v1/orgs/{login}` de Gogs ne vérifie pas le type** : il renvoie `200`
|
||||
pour n'importe quel login existant, user ou org. La détection des vraies
|
||||
organisations se fait donc en scrapant `/explore/organizations`, pas via cet
|
||||
endpoint.
|
||||
- **Le service `"gogs"` de l'API `/repos/migrate` de Gitea interroge d'abord
|
||||
l'API Gogs et récupère son `clone_url` public**, qui repasse par le mur SSO et
|
||||
fait échouer le clonage. Le script utilise le service générique `"git"` à la
|
||||
place, qui clone brutalement l'adresse fournie (le loopback), sans ce détour.
|
||||
- **`ALLOW_LOCALNETWORKS` doit être activé côté Gitea** (`app.ini`, section
|
||||
`[migrations]`) pour autoriser une migration dont la source est une adresse
|
||||
locale/loopback (protection anti-SSRF activée par défaut).
|
||||
- **Un compte de service synchronisé LDAP se fait périodiquement réécraser son
|
||||
statut admin** par la resynchronisation. Utiliser un compte **local** (pas
|
||||
LDAP) pour le compte de service du script, des deux côtés (Gogs et Gitea).
|
||||
- **L'API Gitea n'expose aucun moyen d'éditer `created_at`/`updated_at`** d'un
|
||||
dépôt existant. `fix_creation_dates.py` compare les dates via les deux API
|
||||
(lecture seule) et génère un script SQL à exécuter soi-même après vérification
|
||||
du schéma et sauvegarde de la base.
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Python 3 + `pip install requests`
|
||||
- `git` installé
|
||||
- Un **token API Gogs** admin (Gogs → Settings → Applications → Generate New Token)
|
||||
- Un **compte Gitea admin local** (pas LDAP) avec mot de passe
|
||||
|
||||
## Configuration
|
||||
|
||||
```bash
|
||||
cp config.env.example config.env
|
||||
# éditer config.env et renseigner les valeurs -- ce fichier ne doit JAMAIS être commité
|
||||
```
|
||||
|
||||
## Utilisation
|
||||
|
||||
### `migrate_gogs_to_gitea.py` — dépôts, collaborateurs, webhooks
|
||||
|
||||
Toujours en **dry-run par défaut** (rien n'est écrit) :
|
||||
|
||||
```bash
|
||||
python3 migrate_gogs_to_gitea.py # dry-run, tous les dépôts
|
||||
python3 migrate_gogs_to_gitea.py --only owner/repo # dry-run, un seul dépôt
|
||||
python3 migrate_gogs_to_gitea.py --limit 3 # dry-run, 3 premiers dépôts
|
||||
python3 migrate_gogs_to_gitea.py --apply --only owner/repo # exécution réelle, ciblée
|
||||
python3 migrate_gogs_to_gitea.py --apply # exécution réelle, tout
|
||||
```
|
||||
|
||||
Un dépôt déjà présent côté Gitea n'est **jamais recréé ni écrasé** — seuls les
|
||||
collaborateurs, webhooks et le topic `migrated-from-gogs` peuvent être complétés.
|
||||
|
||||
### Vérifier l'historique git des dépôts déjà migrés à la main
|
||||
|
||||
Compare les branches/tags Gogs vs Gitea des dépôts déjà présents (lecture seule) :
|
||||
|
||||
```bash
|
||||
python3 migrate_gogs_to_gitea.py --verify-existing
|
||||
```
|
||||
|
||||
Ajoute les refs **totalement absentes** côté Gitea (jamais les branches
|
||||
divergentes, jamais de `--force`) :
|
||||
|
||||
```bash
|
||||
python3 migrate_gogs_to_gitea.py --verify-existing --apply
|
||||
```
|
||||
|
||||
### `fix_creation_dates.py` — dates de création/mise à jour
|
||||
|
||||
Ne se connecte jamais à la base de données. Compare via les deux API (lecture
|
||||
seule) et génère un script SQL à vérifier puis exécuter soi-même :
|
||||
|
||||
```bash
|
||||
python3 fix_creation_dates.py # tous les dépôts communs
|
||||
python3 fix_creation_dates.py --only owner/repo # un seul dépôt (test)
|
||||
```
|
||||
|
||||
Avant d'exécuter le `fix_dates.sql` généré :
|
||||
1. Vérifier le nom des colonnes (`DESCRIBE repository;`) — `created_unix` /
|
||||
`updated_unix` sont les noms standards des versions récentes de Gitea, mais à
|
||||
confirmer sur la version en place.
|
||||
2. Faire une sauvegarde de la table `repository` (ou de la base entière).
|
||||
3. Exécuter avec le nom de la base en argument :
|
||||
```bash
|
||||
mysql -u USER -pMOTDEPASSE NOM_BASE < fix_dates.sql
|
||||
```
|
||||
(le script valide lui-même avec un `COMMIT;` en fin de fichier)
|
||||
Reference in New Issue
Block a user