Aller au contenu principal

Migrer de GitHub vers fremforge

Ce guide accompagne une équipe GitHub type dans sa migration vers fremforge. Il couvre GitHub.com, GitHub Enterprise Cloud (GHEC) et GitHub Enterprise Server (GHES). Lisez-le en entier avant de commencer : les surprises en cours de migration coûtent cher.

Vous n’êtes pas prêt à tout déplacer d’un coup ? Utiliser fremforge en parallèle de GitHub explique comment mettre vos dépôts en miroir pour que fremforge les analyse, et comment téléverser des SBOM depuis GitHub Actions pendant la migration.

Si vous n’avez pas encore exécuté la liste de contrôle avant migration sur votre tenant GitHub actuel, commencez par là. Elle met en évidence les dépôts volumineux, l’usage de LFS, les dépendances à des actions de la Marketplace et les intégrations tierces qui demandent une attention particulière.

Avant de commencer

Ce dont vous avez besoin de votre côté :

  • Un compte avec le rôle de propriétaire dans l’organisation GitHub que vous quittez.
  • Un jeton d’accès personnel GitHub avec les portées repo, admin:org, workflow et admin:public_key (PAT classique) ou l’équivalent à granularité fine.
  • Un accès administrateur à l’organisation fremforge vers laquelle vous migrez (l’organisation est créée à l’inscription).
  • Pour la migration d’Actions : un inventaire des actions de la GitHub Marketplace que vous utilisez actuellement, avec leurs versions.

Ce que nous recommandons :

  • Gelez les nouvelles PR et les fusions sur les branches principales que vous migrez pendant la fenêtre de migration. Des écritures concurrentes pendant la migration entraînent un travail de réconciliation dont vous pouvez vous passer.
  • Faites d’abord la migration vers une organisation de test fremforge hors production si vous avez le moindre doute sur l’adaptation de vos workflows. L’essai gratuit de 30 jours est conçu exactement pour cela.
  • Migrez un dépôt de bout en bout et vérifiez qu’il se construit proprement avant de migrer le reste en masse.

Estimation de durée (fourchettes de planification, pas des engagements) :

  • Un petit dépôt (≤ 100 Mo, sans LFS, Actions simples) : 15 à 30 minutes de travail effectif, plus la vérification CI.
  • Un dépôt moyen (≤ 1 Go, un peu de LFS, Actions de complexité modérée) : 1 à 2 heures, adaptation des workflows comprise.
  • Une migration en masse de 20 à 50 dépôts : 1 à 2 jours d’ingénierie répartis sur une semaine, dominés par l’adaptation des Actions plutôt que par la migration des dépôts elle-même.

Ces fourchettes proviennent d’une revue de la documentation au regard des caractéristiques de performance de Forgejo en amont et de 2 migrations internes à fremverk avant le lancement ; les durées réelles seront affinées par nos 5 premières migrations clients. Ce sont des aides à la planification, pas des SLA contractuels. La durée réelle d’une migration dépend : (a) du nombre de dépôts et du volume LFS total ; (b) de la complexité des Actions et du nombre de références uses: à réécrire vers le miroir du runner fremforge ; (c) de la taille de l’équipe capable d’absorber la charge de vérification. Si vous migrez plus de 50 dépôts ou si votre usage d’Actions n’est pas trivial, prévoyez au moins 2× la borne haute comme marge et faites d’abord un pilote sur un seul dépôt.

Matrice de parité fonctionnelle

Ce que fremforge propose aujourd’hui par rapport à GitHub Enterprise Cloud, en se concentrant sur la sécurité et l’authentification, les sujets sur lesquels les clients nous interrogent le plus :

fremforge configure par défaut les nouvelles organisations en accès Git HTTPS uniquement (SSH désactivé par défaut depuis le 2026-05-22) avec l’application OAuth Git Credential Manager préenregistrée : les développeurs passent par la MFA de l’IdP de votre organisation à chaque renouvellement lors d’un push. Le tableau ci-dessous indique où se situe chaque capacité.

CapacitéGHECfremforgeRemarques
HTTPS + GCM (OAuth interactif, MFA via l’IdP)✅✅ Option par défaut recommandéeApplication OAuth préenregistrée : les développeurs exécutent deux lignes git config tirées du guide de connexion sécurisée. La MFA de l’IdP de votre organisation se déclenche à chaque renouvellement de jeton.
Push HTTPS + PAT (portées + expiration)✅✅Les administrateurs fremforge peuvent plafonner la durée de vie des PAT pour toute l’organisation. À utiliser pour la CI et les scripts, pas pour les push humains.
Push par clé SSH (tout algorithme)✅⚠️ Désactivé par défautOption par organisation sur <org>/_admin/auth-policy/ : réactivez-la si votre workflow a besoin de SSH. Raison : l’application d’une restriction par adresse IP source est structurellement impossible en SSH (voir ci-dessous).
Autorité de certification SSH✅✅Interface d’administration native sur <org>/_admin/auth-policy (sous-section de « Autoriser le protocole SSH ») pour les organisations qui ont réactivé SSH : collez la clé publique de l’AC, choisissez la politique de principal et, si vous le souhaitez, « require cert auth ».
Jetons OIDC pour l’identité des charges CI✅✅L’émetteur runner-OIDC de fremforge, https://frem.sh/_app/runner/oidc (découverte + JWKS), voir Runner OIDC. La fédération avec AWS, Azure, GCP et T Cloud Public fonctionne dès aujourd’hui.
Exigence de clés SSH matérielles⚠️ Politique seule✅ Politique + surveillanceOption sur <org>/_admin/auth-policy/ ; une surveillance horaire émet un événement d’audit tenant.auth_policy.hw_key_violation pour chaque clé non matérielle.
Obligation de commits signés✅✅Option à l’échelle de l’organisation + propagateur actif qui crée ou modifie (PATCH) les règles de protection de branche de chaque dépôt.
Analyse des secrets par hook pre-receive✅ Push protection✅ Gitleaks en pre-receiveFournisseur différent, même barrière de sécurité.
Liste d’adresses IP autorisées par organisation : interface web + API REST✅✅Une seule liste d’adresses IP autorisées sur <org>/_admin/security/access/ip-allowlist couvre l’administration web, l’API fremforge, l’interface web des dépôts et l’API REST de Forgejo.
Liste d’adresses IP autorisées par organisation : Git HTTPS, LFS, paquets✅✅La même liste couvre Git sur HTTPS (push, pull, clone), Git LFS et tous les registres de paquets.
Liste d’adresses IP autorisées par organisation : push/pull Git en SSH✅❌ Non couvertSSH atteint fremforge via un équilibreur de charge qui remplace l’adresse source par celle d’un nœud du cluster ; l’adresse du développeur n’est donc pas visible, et fremforge ne juge pas une connexion sur une adresse qu’il sait fausse. SSH est désactivé par défaut (ssh_disabled=true) ; les organisations qui ont besoin d’un filtrage IP sur chaque opération Git le laissent désactivé et utilisent HTTPS, que la liste couvre.
Piste d’audit SSH (horodatage + résolution de l’empreinte)⚠️ Selon le fournisseur✅Un collecteur LTS résout empreinte → utilisateur via la table public_key de Forgejo et émet les événements d’audit git.ssh_pull.ip_allowlist_observed_violation et git.ssh.tenant_disabled_observed. Utile pour les alertes « utilisation d’une clé après le départ d’une personne ».
Mode aperçu « audit seul » de la liste d’adresses IP❌✅Option « Audit only » qui journalise les refus qui auraient eu lieu sans rien bloquer : pratique pour déployer une liste en toute sécurité avant de l’appliquer.
BYOIDC par tenant❌ Une seule organisation SAML/Entra par tenant GHEC✅ Natif : chaque organisation cliente associe son propre IdPImportant pour l’hébergement de SaaS multi-tenant sur fremforge.
SSO OIDC multi-source⚠️ Un seul SAML/OIDC✅ Multi-sourcePlusieurs boutons d’IdP sur la page de connexion du tenant.
Plan de données uniquement dans l’UE❌ États-Unis✅ Natif (T Cloud Public EU-DE)Exigence ferme pour de nombreux clients réglementés de l’UE.
Tarification par utilisateur21 $/utilisateur/mois (GHEC)30 €/utilisateur/mois (306 €/utilisateur/an avec l’engagement annuel)Un tarif unique pour chaque utilisateur, sans paliers par utilisateur. Voir Facturation.
Appliquer les suggestions de revue dans une PR✅✅Commit en un clic depuis le bloc ```suggestion d’une revue de PR ; SHA de tête et branche vérifiés côté serveur. Documentation : Développer → Tickets et PR → Appliquer les suggestions de revue. Disponible depuis le 2026-05-24.
Wiki de documentation public sur des dépôts privés❌ GitHub Pages exige un dépôt public ou le module GHEC Pages✅ Natif, activable par dépôtLecture publique anonyme du wiki du dépôt sur frem.sh/<org>/<repo>/wiki[/...], que le dépôt sous-jacent soit public ou privé. Documentation : Développer → Wiki et documentation publique. Disponible depuis le 2026-05-24.
Durée de conservation de l’audit réglable par le client❌ 7 ans fixes (aucun contrôle client)✅ Par tenant : niveau chaud de {90 / 180 / 365 / 730} j + 3 ans en WORML’administrateur du tenant règle la fenêtre interrogeable du niveau chaud dans Politique d’authentification → Conservation du journal d’audit ; l’archive WORM à chaîne de hachage de 3 ans est inchangée. Valeurs par défaut : 90 j pour le plan standard, 365 j pour l’entreprise. Disponible depuis le 2026-05-24.

La différence stratégique avec GHEC : fremforge fait de HTTPS + GCM la voie principale, parce que la MFA se propage naturellement via l’IdP à chaque renouvellement de jeton ; SSH est activable par organisation, car son contrôle par adresse IP est structurellement plus faible sur cette pile. Pour la plupart des exigences de sécurité en entreprise (« MFA à chaque push », « restreindre par IP les endroits d’où les développeurs peuvent pousser »), l’option par défaut HTTPS + GCM est strictement plus solide que l’option par défaut par clé SSH dont GHEC hérite de l’histoire de GitHub.

Étape 1 : migration des dépôts et de l’historique

fremforge exécute Forgejo tel qu’en amont, qui intègre un importateur natif pour les dépôts GitHub. L’importateur copie tout l’historique Git, les tickets, les pull requests, les commentaires, les étiquettes, les jalons, le contenu du wiki et les versions, pas seulement la branche par défaut.

Avec l’importateur natif (interface)

Depuis l’interface d’administration fremforge de votre organisation :

  1. Cliquez sur + → Nouvelle migration.
  2. Sélectionnez GitHub comme source.
  3. Collez l’URL du dépôt GitHub (par exemple https://github.com/acme/backend).
  4. Collez votre jeton d’accès personnel GitHub. Le jeton ne sert qu’à cette importation et n’est pas conservé une fois l’importation terminée.
  5. Cochez les types de contenu à importer : Wiki, Issues, Pull requests, Releases, Labels, Milestones.
  6. Choisissez l’organisation cible et le nom du dépôt sur fremforge. Par défaut, ils reprennent ceux de la source GitHub.
  7. Cliquez sur Migrate repository.

L’importateur s’exécute en arrière-plan. Pour un dépôt type de 100 à 500 Mo avec un historique de tickets et de PR modéré, comptez 2 à 10 minutes. Un indicateur de progression dans l’interface d’administration affiche l’étape en cours (clonage de l’historique Git, importation des tickets, des PR, des versions).

Avec l’API (scriptable)

Pour les migrations en masse, scriptez l’importation avec l’API fremforge. Les points de terminaison de migration, de dépôt, de ticket et de PR appartiennent à la surface d’API native de Forgejo, que fremforge expose telle quelle sur frem.sh/_app/api/v1/... ; ils ne sont pas documentés séparément dans la spécification OpenAPI de fremforge (qui ne couvre que les ajouts du plan de contrôle fremforge : utilisateurs, politique, résultats, exports, mandats). Pour la référence à jour des points de terminaison natifs de Forgejo, consultez docs.frem.sh/api/openapi.yaml ou la documentation OpenAPI de Forgejo en amont sur docs.codeberg.org/api/. fremforge n’héberge pas la Swagger UI de Forgejo en production (désactivée volontairement, car c’est une cible de reconnaissance connue). Tous les points de terminaison ci-dessous font partie de l’API standard Forgejo/Gitea.

# Build the JSON body via jq so the token is JSON-string-escaped safely
# (a token containing `"` or `\` would otherwise break the body or
# corrupt your migration auth).
jq -nc \
  --arg clone_addr "https://github.com/acme/backend.git" \
  --arg auth_token "$GITHUB_TOKEN" \
  --arg repo_owner "acme" \
  --arg repo_name  "backend" \
  '{clone_addr: $clone_addr, auth_token: $auth_token,
    service: "github", repo_owner: $repo_owner, repo_name: $repo_name,
    wiki: true, issues: true, pull_requests: true,
    releases: true, labels: true, milestones: true,
    lfs: true}' \
| curl -X POST "https://frem.sh/api/v1/repos/migrate" \
    -H "Authorization: Bearer ${FREMFORGE_TOKEN}" \
    -H "Content-Type: application/json" \
    -d @-

Parallélisez sur plusieurs dépôts avec GNU parallel ou un petit script pilote. Limitez-vous à 3 à 5 importations simultanées pour ne saturer ni la limite de débit du PAT GitHub ni votre bande passante locale.

Ce que l’importateur importe ou non

Importé correctement :

  • Toutes les branches et tous les tags, avec l’historique complet des commits.
  • Les tickets avec titres, descriptions, commentaires, étiquettes, jalons et personnes assignées (associées par adresse e-mail lorsque l’utilisateur existe sur fremforge).
  • Les pull requests, y compris les commentaires de revue, l’état de fusion et le motif de fermeture. Les PR ouvertes restent ouvertes, les PR fermées restent fermées.
  • Les versions, pièces jointes binaires comprises (déplacées vers le stockage LFS de fremforge hébergé dans l’UE).
  • Les pages du wiki.

Non importé :

  • L’historique des exécutions de workflows GitHub Actions. Les anciennes exécutions restent sur GitHub ; les nouvelles repartent de zéro sur fremforge.
  • Les valeurs des secrets et les variables d’environnement : vous les saisissez à nouveau (voir l’étape 2).
  • Les intégrations tierces configurées sur GitHub. Elles doivent être reconnectées (voir l’étape 5).
  • GitHub Projects (classique ou Projects v2). Forgejo n’a pas d’équivalent direct ; le contenu de base des tableaux de projet peut être recréé à la main ou via la fonctionnalité Projects de fremforge (phase 1.5).
  • Les alertes Dependabot. L’analyse des dépendances de fremforge fonctionne indépendamment, avec Trivy et osv-scanner, et produit ses propres résultats.
  • Les avis de sécurité des dépôts. Recréez ceux que vous voulez garder sous Sécurité › Rapports › Avis de sécurité (Avis de sécurité), ou via son API à partir du GET /repos/{owner}/{repo}/security-advisories de GitHub ; les avis publiés reçoivent un nouvel identifiant FFSA-, gardez donc l’identifiant GHSA dans les références.
  • GitHub Discussions. Pas d’équivalent dans Forgejo aujourd’hui.
  • Les préférences de notification de chaque utilisateur. Les membres se réabonnent sur fremforge.

Dépôts volumineux

Si votre dépôt dépasse 2 Go ou si votre volume LFS dépasse 5 Go, l’importateur de l’interface peut expirer. Le point de terminaison Forgejo /repos/migrate ne propose pas de réglage de délai par appel ; la solution de repli recommandée consiste donc à faire un clone miroir Git en local, puis un git push --mirror vers un dépôt fremforge vide créé au préalable :

# Clone the GitHub repo bare with full history
git clone --mirror https://github.com/acme/backend.git
cd backend.git

# If the repo uses LFS, fetch all LFS content
git lfs fetch --all

# Create an empty repo on fremforge (via admin UI or API), then:
git remote set-url origin https://frem.sh/acme/backend.git
git push --mirror
git lfs push --all origin

Par cette voie, l’historique des tickets et des PR n’est pas inclus. Importez-le séparément via l’API de migration de Forgejo (POST /api/v1/repos/migrate, voir l’exemple curl de référence en haut de cette page) avec "wiki": false, "issues": true, "pull_requests": true, en faisant pointer la requête vers l’URL du dépôt fremforge déjà poussé, afin que seules les métadonnées soient récupérées depuis GitHub.

L’analyse des secrets en pre-receive filtrera ce push. fremforge exécute gitleaks comme hook pre-receive de Forgejo sur chaque push, y compris le --mirror ci-dessus. Si vos anciens commits contiennent de vrais secrets (clés AWS divulguées, jetons Stripe expirés, clés privées intégrées), le push est refusé avec l’affichage des SHA des commits concernés, et toute l’opération de miroir échoue de manière atomique. C’est voulu : importer dans fremforge un secret présent dans un historique public ne le révoque PAS chez le fournisseur d’origine ; la voie sûre consiste donc à nettoyer puis importer. Deux possibilités pour s’en sortir :

  1. Nettoyer d’abord l’historique avec git-filter-repo (recommandé) ou BFG Repo-Cleaner, puis pousser à nouveau. Prévenez le propriétaire du secret que l’historique chez le fournisseur d’origine reste compromis quoi que vous fassiez côté destination : renouvelez les identifiants divulgués à la source.
  2. Demander une dérogation ponctuelle à support@frem.sh pour des secrets déjà révoqués dans un historique archivé. La dérogation est journalisée, auditée et liée à une confirmation écrite que les secrets ont déjà été renouvelés.

Poussez d’abord main pour que le push LFS serve à quelque chose. Comme git push --mirror est atomique face à gitleaks (toutes les refs dans une seule transaction ; un refus = un miroir vide = le push LFS n’a nulle part où pousser), il vaut la peine de faire d’abord un push d’une seule branche pour valider le jeu de règles avant de pousser toutes les refs. Entre git remote set-url et git push --mirror :

git push origin main --force-with-lease

Si main passe, le reste des refs passe presque toujours (les règles gitleaks portent sur le contenu, pas sur la branche). Si main est refusée, nettoyez ou demandez une dérogation avant de retenter le miroir : rien ne sert de pousser d’autres refs tant que le commit contenant le secret est toujours sur main.

Le hook applique le même jeu de règles gitleaks qui protège chaque dépôt fremforge ; ce n’est pas une vérification propre à la migration. Exécutez pre-migration-check.sh avant de commencer : il fait remonter les mêmes résultats que le hook détecterait, ce qui vous permet de nettoyer avant l’ouverture de la fenêtre de migration.

Quota de stockage LFS et capacité pour les gros dépôts

git lfs push --all origin écrit les objets dans le quota LFS de votre tenant fremforge. Quotas par plan :

PlanStockage LFS inclusPlafond souple avant limitation
Standard (30 €/utilisateur/mois)5 Go par utilisateur, mutualisés au niveau de l’organisation90 % du volume mutualisé ; les téléversements commencent à renvoyer 429 quota_warning
Enterprise à la demandeNégociéSelon le contrat

Deux limites pratiques s’ajoutent au quota du plan :

  • Taille du dépôt Git nu. Si le .git nu du dépôt (après git gc --aggressive) dépasse environ 5 Gio, contactez support@frem.sh avant la migration afin que nous confirmions la marge disponible pour votre dépôt.
  • Très gros push LFS. Un git lfs push de plus de 100 Gio environ en une seule session peut devoir être découpé en lots de 50 Gio maximum pour éviter la limitation de débit. L’erreur prend la forme d’un HTTP 503 avec X-Reserved: ratelimit dans la réponse : attendez 60 s puis reprenez ; LFS sait reprendre.

Si vous ne savez pas quelle taille aura le volume LFS, exécutez git lfs ls-files --size --all | awk '{s+=$2} END {print s/1024/1024/1024 " GiB"}' sur le dépôt source avant de lancer le push du miroir.

Étape 2 : secrets et variables d’environnement

GitHub stocke les secrets au niveau de l’organisation, de l’environnement et du dépôt. fremforge utilise les trois mêmes portées.

Important : les valeurs des secrets ne peuvent pas être exportées depuis GitHub. L’API GitHub renvoie les noms des secrets, jamais leurs valeurs. Soit vous connaissez la valeur (renouvelez-la lors de la migration, c’est recommandé), soit vous la récupérez dans votre source de référence pour les secrets (gestionnaire de mots de passe, coffre, outillage d’orchestration CI).

Saisir à nouveau les secrets

Pour chaque secret, posez-vous la question :

  • S’agit-il d’un identifiant de longue durée qui devrait de toute façon être remplacé par une fédération OIDC ? Si oui, configurez la fédération OIDC avec T Cloud Public (voir l’étape 3) et supprimez le secret au lieu de le migrer.
  • S’agit-il d’une clé d’API tierce ou d’un identifiant de service sans alternative OIDC ? Renouvelez l’identifiant à la source, puis définissez la nouvelle valeur dans fremforge.
  • S’agit-il d’une clé cryptographique utilisée pendant les builds ? Renouvelez-la, puis définissez-la dans fremforge.

Définissez les secrets à la portée adaptée dans l’interface d’administration fremforge :

  • Secrets d’organisation, disponibles pour tous les dépôts de l’organisation. À définir dans Administration de l’organisation → Secrets (frem.sh/<org>/_admin/secrets).
  • Secrets d’environnement, disponibles uniquement dans l’environnement nommé (par exemple production, staging). À définir dans Administration de l’organisation → Environnements → <env> → Secrets d’environnement.
  • Secrets de dépôt, limités à un seul dépôt. À définir dans Dépôt → Paramètres → Actions → Secrets.

Variables d’environnement (configuration non secrète)

GitHub Actions prend en charge env: et vars: au niveau du workflow, du job et de l’étape. Les Actions de fremforge acceptent la même syntaxe ; les variables en ligne ne demandent aucune migration.

Pour les variables au niveau de l’organisation et du dépôt (contexte vars: chez GitHub), fremforge propose les mêmes portées. À définir dans Paramètres → Actions → Variables, dans les paramètres Forgejo de l’organisation ou du dépôt.

Étape 3 : adaptation des workflows Actions

Forgejo Actions est largement compatible avec GitHub Actions, sans être identique au bit près. Un workflow qui tourne sur GitHub tourne généralement sur fremforge moyennant deux ou trois ajustements précis. La matrice de compatibilité des 20 actions les plus utilisées de la Marketplace, sur docs.frem.sh/marketplace-compat, indique quelles actions fonctionnent telles quelles, lesquelles demandent une couche d’adaptation et lesquelles n’ont pas d’équivalent fremforge.

Changements valables pour presque tous les workflows

1. Les références uses: peuvent rester en actions/*@version pour les principales actions GitHub.

Le runner fremforge résout les directives uses: via les miroirs de fremverk hébergés uniquement dans l’UE sur https://frem.sh/<owner>/<repo> (une organisation miroir par éditeur en amont, si bien que actions/checkout se résout en frem.sh/actions/checkout) ; les VM des runners n’accèdent pas directement à github.com au démarrage d’un job (annexe A.6 du DPA). Cela fonctionne pour actions/checkout, actions/setup-node, actions/setup-go, actions/setup-python, actions/setup-java, actions/cache, actions/upload-artifact, actions/download-artifact et le reste des actions officielles actions/* déjà en miroir. Aucune modification de vos lignes uses: n’est nécessaire pour les actions en miroir ; si une référence manque, voir Pièges courants ci-dessous.

2. La sémantique de ${{ secrets.GITHUB_TOKEN }} diffère légèrement.

GitHub fournit à chaque workflow un jeton automatique dont les permissions sont limitées au dépôt appelant. Forgejo en fournit l’équivalent sous ${{ secrets.FORGEJO_TOKEN }}, et ${{ secrets.GITHUB_TOKEN }} est un alias du même jeton : la plupart des workflows fonctionnent donc sans rien changer. Utilisez l’un de ces deux noms plutôt que l’ancien ${{ secrets.GITEA_TOKEN }}. Depuis le 21 octobre 2026, les runners hébergés (forgejo-runner 13) ne définissent plus aucune variable d’environnement GITEA_* : remplacez donc GITEA_ACTIONS par FORGEJO_ACTIONS ou GITHUB_ACTIONS, et GITEA_ACTIONS_RUNNER_VERSION par FORGEJO_ACTIONS_RUNNER_VERSION. Si un workflow attend derrière ce jeton des comportements spécifiques de l’API GitHub (par exemple déclencher l’API GitHub Checks), il doit être adapté. Pour les check runs natifs de Forgejo, l’API équivalente se trouve sur frem.sh/api/v1/repos/{owner}/{repo}/check-runs.

3. Les actions qui appellent directement l’API REST de GitHub doivent être adaptées.

Si un workflow utilise curl https://api.github.com/... ou octokit pour appeler directement l’API REST de GitHub, ces appels doivent cibler https://frem.sh/_app/api/v1/... avec l’API fremforge (largement compatible avec GitHub au niveau REST). Voir la spécification OpenAPI.

4. Le shell par défaut des étapes diffère.

Le shell par défaut du runner Forgejo est bash avec les options POSIX. Les valeurs par défaut du runner GitHub diffèrent subtilement entre Linux et Windows/macOS. Si votre workflow dépend d’un comportement de guillemets particulier du shell, définissez explicitement shell: bash (Linux), shell: pwsh (Windows) ou shell: sh (POSIX uniquement).

Changements valables pour certains workflows

Contexte if: github.*.

Forgejo Actions fournit les variables de contexte github.* avec les mêmes noms que GitHub Actions. Presque toutes les expressions if se transposent sans changement. Les cas limites concernent des métadonnées propres à GitHub (par exemple github.event.pull_request.auto_merge) que Forgejo n’expose pas forcément de la même façon.

Actions de la Marketplace propres à l’API GitHub.

Exemples : peter-evans/create-pull-request, marocchino/sticky-pull-request-comment, nwtgck/actions-netlify. La plupart fonctionnent d’emblée, car la surface REST de fremforge accepte leurs appels d’API. Quelques-unes demandent de petits correctifs. La matrice des 20 actions documente les contournements précis.

Workflows à réécrire

Si votre workflow utilise des fonctionnalités propres à GitHub Enterprise (API des rulesets d’organisation, points de terminaison de métriques propres à GHES, API des extensions Copilot, GitHub Packages au-delà de npm/Docker/Maven), ces fonctionnalités doivent être remplacées. Le remplacement est généralement natif à fremforge :

  • Rulesets d’organisation → politique au niveau de l’organisation fremforge (Administration de l’organisation → Sécurité → Politiques → Règles des dépôts).
  • GitHub Packages → registre de paquets fremforge (npm, Maven, Docker, NuGet, PyPI, RubyGems, Composer, Go).
  • Extensions Copilot → hors du périmètre de fremforge par choix (voir l’article sur notre position en matière d’IA sur www.frem.sh).

Étape 4 : réenregistrement des clés SSH

Les clés publiques SSH sont propres à chaque utilisateur et ne sont pas migrées. Chaque développeur ajoute sa clé publique SSH à son compte fremforge :

  1. Connectez-vous à fremforge.
  2. Paramètres utilisateur → Clés SSH / GPG → Ajouter une clé.
  3. Collez la clé publique (~/.ssh/id_ed25519.pub ou équivalent).

Les empreintes de la clé d’hôte de frem.sh sont publiées sur www.frem.sh/ssh-fingerprints. Les développeurs doivent les vérifier lors de la première connexion SSH pour éviter une attaque de l’homme du milieu passée inaperçue. L’empreinte s’affiche à la première connexion ; le développeur la compare à la page de confiance, confirme, et la clé est épinglée pour les connexions suivantes.

Pour les équipes qui utilisent des autorités de certification SSH, fremforge permet de configurer une AC de confiance directement depuis l’interface d’administration de l’organisation, sur <your-org>/_admin/auth-policy : la section SSH CA se trouve sous l’option « Autoriser le protocole SSH » (intégrée à la politique d’authentification le 2026-05-26 ; l’ancienne page /admin/ssh-ca/ redirige ici). Collez la clé publique OpenSSH de votre AC, choisissez une politique de principal (nom d’utilisateur / e-mail / opaque) et, si vous le souhaitez, imposez « require cert auth » afin que la connexion par simple clé publique soit refusée. Consultez la section Autorité de certification SSH du guide de la politique d’authentification pour la configuration complète, avec des exemples d’intégration Smallstep et Vault. Tout utilisateur qui s’authentifie avec un certificat émis par l’AC est admis avec les permissions du compte fremforge correspondant.

Pour les équipes où le SSO est obligatoire (sso_required = true au niveau de l’organisation), l’authentification SSH valide en plus, à chaque connexion, un jeton d’actualisation OIDC auprès de l’IdP du tenant (mis en cache 15 minutes). Ainsi, le déprovisionnement d’un utilisateur côté IdP bloque son accès SSH en 15 minutes, même si sa clé SSH est encore enregistrée sur fremforge. Aucun nettoyage séparé des clés n’est nécessaire.

Étape 5 : reconnexion des intégrations tierces

Les intégrations configurées sur GitHub (webhooks, notifications CI vers Slack/Teams, hooks de déploiement vers Vercel/Netlify, synchronisation avec un gestionnaire de tickets comme Jira/Linear, outils de revue de code comme Sourcegraph ou Graphite) ne migrent pas automatiquement. Chacune doit être reconnectée.

Webhooks

Les webhooks GitHub se trouvent dans Repository → Settings → Webhooks. Les webhooks fremforge sont au même endroit dans l’interface d’administration. La forme des charges utiles est largement compatible ; les principales différences :

  • L’en-tête X-GitHub-Event de GitHub devient X-Forgejo-Event sur fremforge (ou X-Gitea-Event pour les consommateurs compatibles Gitea). La plupart des récepteurs de webhooks génériques acceptent les deux.
  • L’identifiant de livraison est X-Gitea-Delivery + X-Hook-UUID (l’équivalent du X-GitHub-Delivery de GitHub). Les deux sont présents à chaque déclenchement d’un webhook fremforge ; la plupart des récepteurs s’appuient sur l’un ou l’autre.
  • Les types d’événements forment un sur-ensemble proche des événements principaux de GitHub. push, pull_request, pull_request_review, issues, issue_comment, release, create, delete, fork et star sont tous présents.
  • L’en-tête de signature est X-Forgejo-Signature (HMAC-SHA256 avec le secret de votre webhook).

Pour les récepteurs écrits pour l’API GitHub (intégrations Slack, Discord, PagerDuty), deux options :

  1. Reconfigurer le récepteur pour utiliser son intégration Forgejo native. L’intégration Forgejo de Slack, la cible de webhook Forgejo de Discord, etc. existent généralement et constituent la voie la plus propre.
  2. Adapter le webhook côté récepteur. Si le récepteur est un service interne sur mesure, ajoutez la prise en charge des événements Forgejo à côté de celle des événements GitHub. C’est généralement une petite modification.

Intégrations CI (CircleCI, TravisCI, Jenkins)

Si vous exécutez votre CI en dehors de la forge (CircleCI, Jenkins externe, Buildkite), la migration est simple : faites pointer ces systèmes CI vers les dépôts fremforge au lieu des dépôts GitHub. La plupart des systèmes CI externes acceptent Forgejo/Gitea comme source ; la modification se fait dans le système CI, pas dans fremforge.

La plupart des équipes qui migrent vers fremforge en profitent pour se regrouper sur les runners hébergés de fremforge et abandonner la CI externe. Les minutes de runner sont comprises dans le prix forfaitaire par utilisateur. Voir l’article sur le coût total de possession sur le blog de fremverk pour les calculs.

Cibles de déploiement (Vercel, Netlify, Cloudflare Pages)

Chaque service se reconnecte à fremforge soit par une prise en charge native (Vercel et Netlify proposent des intégrations de source Git Forgejo/Gitea), soit par un hook de déploiement générique déclenché par un push Git. Notez vos nouvelles URL de webhook et mettez-les à jour dans le tableau de bord de chaque service.

Synchronisation avec un gestionnaire de tickets (Jira, Linear, Zendesk)

Si votre synchronisation repose sur les commits Git (lien entre commits et tickets par identifiant), elle continue de fonctionner : les SHA des commits sont préservés par la migration. Si elle repose sur l’API GitHub (écoute des événements de PR, requêtes sur les tickets GitHub), reconfigurez-la pour cibler les webhooks fremforge, ou désactivez-la.

Étape 6 : DNS et domaines personnalisés (le cas échéant)

fremforge sert le contenu des dépôts uniquement sur frem.sh/<org>/<repo>. Les domaines Git personnalisés appartenant au client ne sont pas pris en charge : il n’existe pas d’équivalent de la fonctionnalité « custom hostname » de GitHub Enterprise Server, où TLS se termine avec votre certificat sur git.company.com. Deux conséquences à expliciter :

CNAME de confort sans TLS

Un CNAME de confort dans le DNS du client (par exemple un git.company.com interne en CNAME vers frem.sh) est techniquement possible, mais le certificat TLS servi est toujours le certificat *.frem.sh de fremforge, et NON un certificat *.company.com. Un navigateur qui accède à https://git.company.com/... affichera un avertissement de non-correspondance du nom, à moins que le client ne fournisse et ne serve aussi son propre certificat via son propre proxy inverse placé devant. Cela relève entièrement du client : fremforge ne termine pas TLS pour les noms d’hôte de confort, n’accepte pas de certificats fournis par le client et n’exploite pas de couche SNI multi-certificats.

Voie recommandée pour les clients qui quittent GitHub Enterprise Server : adoptez directement le format d’URL frem.sh/<org>/*. Mettez à jour les liens internes, les configurations CI et la documentation vers les nouvelles URL. La voie du CNAME de confort avec certificat client ajoute une dette opérationnelle (renouvellement des certificats, exploitation du proxy) et n’est pas une configuration prise en charge par fremforge.

Si vos achats exigent un SLA sur un domaine de confort, venez avec un contrat Enterprise à la demande : cela ouvre une discussion sur un niveau de périphérie dédié avec terminaison TLS par le certificat du client, mais c’est hors du périmètre de l’offre en libre-service.

Ce qui migre et ce qui ne migre pas

Cette section énumère les artefacts GitHub qui passent la migration, et avec quelle fidélité. Servez-vous-en comme liste d’alignement avant migration.

ArtefactMigré ?Remarques sur la fidélité
Contenu du dépôt (commits, branches, tags)✓SHA inchangés ; historique complet préservé
Objets LFS✓ (volume ≤ 5 Go avec l’importateur de l’interface ; au-delà via un clone miroir)Mêmes OID ; la limite de taille est opérationnelle, pas protocolaire
Tickets✓ au mieuxL’importateur de Forgejo attribue des valeurs Issue.Index séquentielles aux tickets importés ; les trous dans la numérotation source ne sont pas préservés (par exemple, les #1, #2, #42 de GitHub deviennent #1, #2, #3 sur Forgejo). Les références entre tickets dans le corps des commentaires sont réécrites pour correspondre aux numéros attribués lorsque l’importateur parvient à les résoudre ; les références non résolues restent du texte brut. Si la fidélité exacte des numéros compte (gestionnaires de tickets anciens avec des favoris publics), la renumérotation par l’API consiste à créer sur la destination, avant l’importation, des tickets fictifs pour chaque trou, puis à les supprimer après l’importation.
Pull requests✓ au mieuxLes PR partagent l’espace de numérotation des tickets (compteur commun de Forgejo, comme Gitea) : l’ordre relatif est préservé, mais les numéros absolus suivent la réserve de la ligne Tickets ci-dessus, et les trous de la numérotation source disparaissent à l’importation. Si votre source contient le ticket #1, la PR #2, le ticket #5 et la PR #7, la destination aura le ticket #1, la PR #2, le ticket #3 et la PR #4. Utilisez le même contournement par tickets fictifs que pour les tickets si la fidélité exacte des numéros de PR compte (favoris publics, liens profonds). Les PR ouvertes au moment de la migration arrivent à l’état de brouillon.
Commentaires de revue de PR (en ligne, ancrés sur une ligne)⚠ partielLes commentaires ancrés sur une ligne deviennent de simples commentaires de PR (limite du modèle de données entre forges). Voir « Les commentaires de revue de PR sont importés comme de simples commentaires de PR » ci-dessous.
Règles de protection de branche✗, à recréerLa forme des règles branch_protections de GitHub ne correspond pas à la forme BranchProtection de Forgejo. Avant la migration : relevez chaque règle avec gh api /repos/<owner>/<repo>/branches/<name>/protection. Après la migration : recréez-les via l’onglet Règles des dépôts de l’interface d’administration fremforge, avec des dérogations par dépôt. Un modèle .gitea/branch-protection.yaml versionné dans l’organisation peut déclarer l’état souhaité ; aujourd’hui, l’application se fait côté opérateur via l’interface d’administration (la protection de branche sous forme de code via l’API est prévue en phase 2).
Webhooks✗, non préservésLe point de terminaison de migration de Forgejo n’énumère pas les webhooks de la forge source (les téléchargeurs GitHub/GitLab ne parcourent pas les hooks ; il n’existe pas d’option migrate webhooks dans MigrateRepoOptions). Vous arrivez avec zéro webhook côté destination. Recréez les webhooks sur fremforge après la migration à partir de l’inventaire produit par pre-migration-check.sh, qui liste l’URL et les événements de chaque webhook source. Les secrets HMAC ne sont pas récupérables depuis GitHub : chaque intégration réceptrice a donc aussi besoin d’un nouveau secret, renouvelé dans le tableau de bord du service une fois l’URL fremforge réenregistrée. fremforge ne relivre pas non plus les événements passés.
Sous-modules⚠ réécriture d’URL nécessaireLes URL de .gitmodules qui pointent vers github.com/<org>/<repo> restent des URL github.com littérales après la migration. Soit (a) mettez à jour chaque entrée de .gitmodules vers la nouvelle URL fremforge après la migration et commitez, soit (b) utilisez git config submodule.<name>.url <fremforge-url> dans chaque clone si le dépôt parent n’est pas sous votre contrôle. L’importateur fremforge ne réécrit pas .gitmodules automatiquement, car les URL de sous-modules sont du contenu qui appartient à l’auteur du projet.
Secrets Actions au niveau de l’organisation✗, à saisir à nouveauPar conception, les secrets ne sont pas récupérables depuis GitHub via l’API. Saisissez-les à nouveau dans Administration de l’organisation → Secrets (frem.sh/<org>/_admin/secrets). Avant la migration : listez-les avec gh secret list --org <org> pour disposer des noms à recréer.
Variables Actions au niveau de l’organisation (non secrètes)✓ par exportLes variables simples peuvent être exportées avec gh variable list --org <org> --json name,value > gh-vars.json et réimportées via l’interface d’administration fremforge. Pour une importation en masse par l’API, envoyez l’export vers le point de terminaison des variables : jq -c '.[]' < gh-vars.json | while read row; do n=$(jq -r .name <<<"$row"); v=$(jq -r .value <<<"$row"); curl -fsS -X POST "https://frem.sh/_app/api/v1/orgs/<org>/actions/variables" -H "Authorization: Bearer $T" -H "Content-Type: application/json" -d "{\"name\":\"$n\",\"value\":\"$v\"}"; done. La même forme fonctionne pour les variables au niveau du dépôt (remplacez /orgs/<org>/ par /repos/<owner>/<repo>/).
GitHub Discussions✗, pas d’équivalentForgejo ne propose pas d’équivalent à Discussions aujourd’hui. Exportez-les dans une archive séparée si les fils de discussion sont essentiels pour votre organisation.
GitHub Projects (tableaux)✗, pas d’équivalentLe suivi de projet se reconstruit dans fremforge avec tickets + étiquettes + jalons.

Reprise après échec

Le point de terminaison Forgejo /repos/migrate ne permet pas de reprise. Si l’appel échoue en cours de route (coupure réseau, limite de débit de l’API source, etc.), le dépôt partiellement importé reste dans un état incohérent. Procédure de récupération :

  1. Supprimez le dépôt partiel via Paramètres → Supprimer dans l’interface d’administration fremforge.
  2. Relancez immédiatement l’appel de migration. S’il renvoie 422 avec repository already exists, attendez 5 secondes et réessayez : il s’agit du décalage de réplication RDS sur le chemin du réplica en lecture, pas d’un cycle de pierre tombale (tombstone) de Forgejo.
  3. Si la deuxième tentative échoue de la même façon, utilisez un nouveau nom de dépôt.

Pour les dépôts dont la réimportation coûte cher (gros volume LFS, nombreux tickets), utilisez le repli par miroir local décrit dans « Dépôts volumineux » : git push --mirror reprend naturellement, car git gère lui-même proprement les coupures réseau.

Vérification après migration

Au-delà de la liste « vérifier et décommissionner » de l’étape 7 ci-dessous, voici la liste de vérification après migration que les clients oublient le plus souvent :

  • Comparer le nombre de commits. git rev-list --count HEAD sur le clone GitHub et sur le clone fremforge. Les nombres doivent être strictement identiques.
  • Comparer la liste des branches. git branch -r | sort de chaque côté, puis diff des sorties. Les refs refs/pull/* obsolètes de GitHub ne sont pas migrées (Forgejo numérote les PR dans son propre espace de refs) ; tout le reste doit correspondre.
  • Comparer la liste des tags. git tag --sort=v:refname de chaque côté ; les listes doivent être identiques.
  • Comparer le nombre de pointeurs LFS. git lfs ls-files | wc -l ; les nombres doivent être strictement identiques. Sinon, exécutez git lfs fetch --all && git lfs push --all origin vers le dépôt distant fremforge.
  • Nombre et numérotation des tickets et PR. gh issue list --limit 5000 --state all --json number | jq length sur GitHub, contre /api/v1/repos/<org>/<repo>/issues?state=all sur fremforge (avec pagination). Boucle de pagination pour fremforge : n=0; for p in $(seq 1 200); do c=$(curl -fsS "https://frem.sh/api/v1/repos/<org>/<repo>/issues?state=all&page=$p&limit=50" -H "Authorization: Bearer $T" | jq length); [ "$c" = 0 ] && break; n=$((n + c)); done; echo $n. Numérotation préservée.
  • CI au vert. Déclenchez un build sans changement sur main et vérifiez que l’exécution Forgejo Actions atteint success. Cela détecte les trous dans les miroirs uses: (la cause la plus fréquente de CI cassée après migration).

Si l’un de ces contrôles révèle un écart, ne décommissionnez pas la source GitHub tant que l’écart n’est pas résolu.

Étape 7 : vérifier et décommissionner

Après la migration :

  1. Clonez le dépôt migré depuis fremforge, lancez le build et vérifiez que les tests passent.
  2. Ouvrez une PR de test pour vérifier que l’analyseur de secrets en pre-receive, l’analyseur de dépendances et la vérification des commits signés sont actifs comme prévu.
  3. Consultez la vue Résultats de l’interface d’administration pour vérifier qu’aucun résultat d’analyse inattendu ne concerne l’historique migré.
  4. Vérifiez que les webhooks sont bien livrés via Paramètres → Webhooks → Livraisons récentes.
  5. Vérifiez que la connexion SSO fonctionne pour chaque utilisateur qui accédera au dépôt.
  6. Mettez à jour la documentation et les wikis internes pour qu’ils pointent vers les nouvelles URL des dépôts.
  7. Après 30 jours de fonctionnement sans problème sur fremforge, archivez les dépôts GitHub. Ne les supprimez pas ; conservez-les pour l’historique d’audit.

Retour arrière (partiel, à planifier)

La migration est partiellement réversible, pas entièrement. Soyez lucide sur ce qui fait ou non l’aller-retour avant d’y basculer votre trafic de production.

Ce qu’un retour arrière PEUT récupérer :

  1. L’historique Git : un git push --mirror depuis un clone fremforge local vers le dépôt GitHub restaure les branches, les tags et les commits.
  2. Les webhooks et intégrations : réactivez-les côté GitHub ; vous devrez remettre à la main les URL cibles des webhooks vers les points de terminaison hébergés par GitHub.

Ce qu’un retour arrière NE PEUT PAS récupérer fidèlement :

  1. Les tickets, PR et commentaires créés après la migration : Administration de l’organisation → Export de données de fremforge produit un dump JSON, mais l’API d’importation de GitHub utilise un autre schéma ; la réimportation demande donc un travail de correspondance manuel. Les numéros de tickets ne correspondront pas ; les références croisées dans les messages de commit pointeront dans le vide. L’attribution des auteurs exige que chaque contributeur ait de nouveau un compte GitHub. Les réactions, les fils de revue et l’ancrage des commentaires en ligne ne survivent généralement pas à l’aller-retour.
  2. L’historique CI et les journaux Actions créés sur fremforge : non exportables dans un format équivalent.
  3. Les résultats propres à fremforge : les refus de l’analyse des secrets, les résultats de l’analyse des dépendances et les attestations de commits signés créés sur fremforge n’ont pas d’équivalent GitHub dans lequel les importer.

Considérez la migration comme un aller simple pour la production. Faites d’abord un pilote sur un seul dépôt non critique ; vérifiez que la CI, les webhooks et le SSO fonctionnent ; puis migrez le reste par lots. L’idée d’une migration « réversible sous 30 jours » ne s’applique qu’au retour arrière de l’historique Git seul ; ne comptez pas dessus pour récupérer l’intégralité de l’état collaboratif.

Pièges courants

Objets LFS invisibles après la migration.

L’importateur de l’interface gère LFS automatiquement pour les petits volumes (< 5 Go). Pour des volumes plus importants, exécutez git lfs fetch --all sur un clone miroir local, puis git lfs push --all origin vers fremforge à la main.

Les workflows Actions échouent à la première exécution avec « action not found ».

Les miroirs sur https://frem.sh/<owner>/<repo> (voir la résolution des Actions ci-dessus) couvrent l’ensemble standard actions/* et dix autres organisations d’éditeurs. Une référence uses: en échec signifie que l’action n’est pas encore en miroir : ouvrez une demande auprès de support@frem.sh en indiquant la référence manquante, et le balayage des miroirs la prendra en compte au cycle suivant ; ou épinglez une version déjà résolue et en cache.

Les commentaires de revue de PR sont importés comme de simples commentaires de PR.

L’importateur de Forgejo transforme les commentaires de revue de PR en commentaires de PR, et non en commentaires de revue au niveau de la ligne. C’est une limite du modèle de données entre forges : les commentaires de revue en ligne perdent le contexte de leur ligne d’ancrage. Contournement : pour les dépôts où les commentaires en ligne sont essentiels, exportez-les avant la migration dans un fichier de données séparé via l’API GitHub et conservez-les comme pièce jointe d’archive sur la PR migrée.

Utilisateurs non associés automatiquement.

L’importateur associe les utilisateurs GitHub par adresse e-mail. Les utilisateurs dont l’e-mail GitHub ne correspond pas à leur e-mail fremforge (par exemple e-mail personnel sur GitHub, e-mail professionnel sur fremforge) apparaissent comme « Unknown user » sur les tickets importés. Soit vous les associez à l’avance en ajoutant l’e-mail utilisé côté GitHub comme e-mail secondaire du compte fremforge avant l’importation, soit vous acceptez l’affichage « Unknown user » et vous vous fiez à l’attribution d’origine visible dans l’historique des commits.

Obtenir de l’aide

Si quelque chose dans ce guide ne fonctionne pas avec votre configuration :

  • Écrivez à support@frem.sh avec un objet commençant par MIGRATION, GITHUB - et une description de l’endroit où vous êtes bloqué.
  • Si vous êtes sur le plan early adopter, vous avez une ligne directe avec l’équipe de développement de fremforge pour vous aider dans la migration, sans frais supplémentaires.

Voir aussi : Guide de migration depuis GitLab · Guide de migration depuis Azure DevOps · Matrice de compatibilité des 20 principales actions de la Marketplace · Liste de contrôle avant migration.