Zum Hauptinhalt springen

Von GitHub zu fremforge migrieren

Dieser Leitfaden führt ein typisches GitHub-Team durch die Migration zu fremforge. Er gilt für GitHub.com, GitHub Enterprise Cloud (GHEC) und GitHub Enterprise Server (GHES). Lies ihn vor dem Start vollständig durch. Überraschungen mitten in der Migration sind teuer.

Noch nicht bereit, alles auf einmal umzuziehen? fremforge parallel zu GitHub nutzen zeigt, wie du Repositorys spiegelst, damit fremforge sie scannt, und wie du SBOMs aus GitHub Actions hochlädst, während der Umzug läuft.

Wenn du die Checkliste vor der Migration noch nicht gegen deinen aktuellen GitHub-Mandanten ausgeführt hast, tu das zuerst. Sie zeigt große Repositorys, LFS-Nutzung, Abhängigkeiten von Marketplace-Actions und Integrationen von Drittanbietern, die besondere Aufmerksamkeit brauchen.

Bevor du anfängst

Was du auf deiner Seite brauchst:

  • Ein Konto mit der Owner-Rolle in der GitHub-Organisation, von der du migrierst.
  • Ein persönliches Zugriffstoken auf GitHub mit den Scopes repo, admin:org, workflow und admin:public_key (klassischer PAT) oder dem fein granulierten Gegenstück.
  • Admin-Zugriff auf die fremforge-Organisation, zu der du migrierst (die Organisation wird bei der Registrierung angelegt).
  • Für die Migration von Actions: eine Bestandsliste der GitHub-Marketplace-Actions, die du derzeit nutzt, mit ihren Versionen.

Was wir empfehlen:

  • Friere für das Migrationsfenster neue PRs und Merges auf die Haupt-Branches ein, die du migrierst. Gleichzeitige Schreibzugriffe während der Migration verursachen Abgleichsaufwand, den du nicht brauchst.
  • Führe die Migration zuerst gegen eine Testorganisation auf fremforge aus, die nicht produktiv ist, wenn du Zweifel hast, wie sich deine Workflows anpassen lassen. Die 30-tägige kostenlose Testphase ist genau dafür gedacht.
  • Migriere ein Repository von Anfang bis Ende und prüfe, dass es sauber baut, bevor du den Rest gesammelt migrierst.

Zeitschätzung (Planungsspannen, keine Zusagen):

  • Ein einzelnes kleines Repository (≤100 MB, kein LFS, einfache Actions): 15–30 Minuten Handarbeit plus CI-Prüfung.
  • Ein mittleres Repository (≤1 GB, etwas LFS, mittlere Komplexität der Actions): 1–2 Stunden einschließlich Anpassung der Workflows.
  • Eine Sammelmigration von 20–50 Repositorys: 1–2 Entwicklertage, verteilt über eine Woche, wobei die Anpassung der Actions mehr Zeit kostet als die Migration der Repositorys selbst.

Diese Spannen beruhen auf der Auswertung der Dokumentation gegen die Leistungsmerkmale von Forgejo upstream und auf 2 fremverk-internen Migrationen vor dem Launch; die tatsächlichen Zeiten werden durch unsere ersten 5 Kundenmigrationen genauer. Sie sind Planungshilfen, keine vertraglichen SLAs. Die reale Migrationsdauer hängt ab von: (a) Anzahl der Repositorys und gesamtem LFS-Volumen; (b) Komplexität der Actions und Anzahl der uses:-Referenzen, die gegen den Runner-Mirror von fremforge umgeschrieben werden müssen; (c) Größe des Teams, das die Prüflast tragen kann. Wenn du mehr als 50 Repositorys migrierst oder Actions nicht trivial nutzt, plane mindestens das Doppelte der Obergrenze als Puffer ein und führe zuerst einen Pilot mit einem einzigen Repository durch.

Matrix der Funktionsgleichheit

Was fremforge heute im Vergleich zu GitHub Enterprise Cloud bietet, mit Fokus auf die Sicherheits- und Authentifizierungsfunktionen, nach denen Kunden am häufigsten fragen:

fremforge stellt neue Organisationen standardmäßig auf Git-Zugriff nur über HTTPS ein (SSH ist seit dem 22.05.2026 standardmäßig deaktiviert), mit der vorregistrierten OAuth-App für den Git Credential Manager: Entwickler bekommen bei jeder Token-Erneuerung beim Push MFA über den IdP deiner Organisation. Die Tabelle unten zeigt, wo jede Fähigkeit steht.

FähigkeitGHECfremforgeHinweise
HTTPS + GCM (OAuth interaktiv, MFA über IdP)✅✅ Empfohlener StandardVorregistrierte OAuth-App: Entwickler führen zwei git config-Zeilen aus dem Leitfaden zur sicheren Anmeldung aus. MFA über den IdP deiner Organisation greift bei jeder Token-Erneuerung.
HTTPS + Push mit PAT (mit Scopes und Ablauf)✅✅Admins von fremforge können die Lebensdauer von PATs organisationsweit begrenzen. Für CI und Skripte gedacht, nicht für Pushes durch Menschen.
Push mit SSH-Schlüssel (beliebiger Algorithmus)✅⚠️ Standardmäßig deaktiviertSchalter pro Organisation unter <org>/_admin/auth-policy/: Schalte ihn wieder ein, wenn dein Workflow SSH braucht. Grund: Eine Durchsetzung nach Quell-IP ist bei SSH strukturell nicht möglich (siehe unten).
SSH-Zertifizierungsstelle✅✅Native Admin-Oberfläche unter <org>/_admin/auth-policy (Unterabschnitt unter „SSH-Protokoll erlauben“) für Organisationen, die SSH wieder eingeschaltet haben: öffentlichen CA-Schlüssel einfügen, Principal-Richtlinie, optional „Zertifikatsauthentifizierung verlangen“.
OIDC-Tokens für die Workload-Identität in CI✅✅Der Runner-OIDC-Issuer von fremforge, https://frem.sh/_app/runner/oidc (Discovery + JWKS), siehe Runner-OIDC. Föderation mit AWS, Azure, GCP und T Cloud Public funktioniert heute.
Pflicht zu hardwaregestützten SSH-Schlüsseln⚠️ Nur Richtlinie✅ Richtlinie + WatchdogSchalter unter <org>/_admin/auth-policy/; ein stündlicher Watchdog schreibt für jeden nicht hardwaregestützten Schlüssel ein Audit-Ereignis tenant.auth_policy.hw_key_violation.
Durchsetzung signierter Commits✅✅Organisationsweiter Schalter plus aktiver Propagator, der Branch-Schutzregeln pro Repository anlegt bzw. per PATCH aktualisiert.
Secret-Scan per Pre-Receive-Hook✅ Push Protection✅ Gitleaks Pre-ReceiveAnderer Anbieter, dieselbe Sicherheitsschranke.
IP-Allowlist pro Organisation: Weboberfläche + REST-API✅✅Eine IP-Allowlist unter <org>/_admin/security/access/ip-allowlist deckt die Weboberfläche für Admins, die fremforge-API, die Weboberfläche der Repositorys und die Forgejo-REST-API ab.
IP-Allowlist pro Organisation: Git über HTTPS, LFS, Pakete✅✅Dieselbe Liste deckt Git über HTTPS (Push, Pull, Clone), Git LFS und jede Paket-Registry ab.
IP-Allowlist pro Organisation: Push/Pull über SSH✅❌ Nicht abgedecktSSH erreicht fremforge über einen Load Balancer, der die Quelladresse auf einen Cluster-Knoten umschreibt, sodass die Adresse des Entwicklers nicht sichtbar ist; fremforge beurteilt eine Verbindung nicht anhand einer Adresse, von der es weiß, dass sie falsch ist. SSH ist standardmäßig aus (ssh_disabled=true); Organisationen, die IP-Filterung für jede Git-Operation brauchen, lassen es aus und nutzen HTTPS, das die Liste abdeckt.
SSH-Audit-Trail (Zeitpunkt + Auflösung des Fingerabdrucks)⚠️ Anbieterspezifisch✅Ein LTS-Scraper löst den Fingerabdruck über die Forgejo-Tabelle public_key zum Nutzer auf und schreibt die Audit-Ereignisse git.ssh_pull.ip_allowlist_observed_violation + git.ssh.tenant_disabled_observed. Nützlich für Alerts zu „Schlüsselnutzung nach dem Offboarding“.
Vorschaumodus „nur Audit“ für die IP-Allowlist❌✅Schalter „Nur-Audit“, der Ablehnungen protokolliert, die erfolgt wären, ohne zu blockieren: nützlich, um eine Allowlist gefahrlos einzuführen, bevor du sie durchsetzt.
BYOIDC pro Mandant❌ Eine SAML-/Entra-Organisation pro GHEC-Mandant✅ Nativ: Jede Kundenorganisation bindet ihren eigenen IdPWichtig für mandantenfähiges SaaS-Hosting auf fremforge.
OIDC-SSO mit mehreren Quellen⚠️ Einzelnes SAML/OIDC✅ Mehrere QuellenMehrere IdP-Schaltflächen auf der Anmeldeseite des Mandanten.
Datenebene nur in der EU❌ USA✅ Nativ (T Cloud Public EU-DE)Harte Anforderung für viele regulierte Kunden in der EU.
Preis pro Nutzer21 $/Nutzer/Monat (GHEC)30 €/Nutzer/Monat (306 €/Nutzer/Jahr bei jährlicher Laufzeit)Ein fester Preis für jeden Nutzer, ohne Preisstufen pro Nutzer. Siehe Abrechnung.
Review-Vorschläge im PR übernehmen✅✅Commit per Klick aus einem ```suggestion-Codeblock in einem PR-Review; Head-SHA und Branch werden serverseitig geprüft. Kundendokumentation unter Entwickeln → Issues und PRs → Review-Vorschläge übernehmen. Ausgeliefert am 24.05.2026.
Öffentliches Doku-Wiki bei privaten Repositorys❌ GitHub Pages verlangt ein öffentliches Repository oder das GHEC-Pages-Add-on✅ Nativ, pro Repository zuschaltbarAnonymer öffentlicher Lesezugriff auf das Wiki des Repositorys unter frem.sh/<org>/<repo>/wiki[/...], unabhängig davon, ob das zugrunde liegende Repository öffentlich oder privat ist. Kundendokumentation unter Entwickeln → Wiki und öffentliche Dokumentation. Ausgeliefert am 24.05.2026.
Vom Kunden einstellbare Aufbewahrung des Audit-Logs❌ fest 7 Jahre (keine Steuerung durch den Kunden)✅ Pro Mandant {90 / 180 / 365 / 730} Tage Hot-Tier + 3 Jahre WORMDer Admin des Mandanten legt das abfragbare Hot-Tier-Fenster unter Authentifizierungsrichtlinie → Aufbewahrung des Audit-Logs fest; das 3-jährige WORM-Archiv mit Hash-Kette bleibt unverändert. Standards: 90 Tage im Standardplan, 365 Tage bei Enterprise. Ausgeliefert am 24.05.2026.

Der strategische Unterschied zu GHEC: fremforge behandelt HTTPS+GCM als Hauptweg, weil MFA bei jeder Token-Erneuerung ganz natürlich über den IdP greift; SSH ist pro Organisation zuschaltbar, weil seine IP-Durchsetzung auf diesem Stack strukturell schwächer ist. Für die meisten Sicherheitsanforderungen von Unternehmen („MFA bei jedem Push“, „per IP einschränken, von wo Entwickler pushen dürfen“) ist der Standard HTTPS+GCM klar stärker als der SSH-Schlüssel-Standard, den GHEC aus der Geschichte von GitHub übernommen hat.

Schritt 1: Migration von Repository und Historie

fremforge betreibt Forgejo upstream, das einen nativen Importer für GitHub-Repositorys mitbringt. Der Importer kopiert die vollständige Git-Historie, Issues, Pull Requests, Kommentare, Labels, Meilensteine, Wiki-Inhalte und Releases, nicht nur den Standard-Branch.

Mit dem nativen Importer (Weg über die Oberfläche)

In der Admin-Oberfläche von fremforge für deine Organisation:

  1. Klicke auf + → Neue Migration.
  2. Wähle GitHub als Quelle.
  3. Füge die URL des GitHub-Repositorys ein (z. B. https://github.com/acme/backend).
  4. Füge dein persönliches GitHub-Zugriffstoken ein. Das Token wird nur für diesen Import verwendet und nach Abschluss des Imports nicht gespeichert.
  5. Hake die Inhaltstypen an, die importiert werden sollen: Wiki, Issues, Pull requests, Releases, Labels, Milestones.
  6. Wähle die Zielorganisation und den Namen des Repositorys auf fremforge. Die Standardwerte übernehmen die GitHub-Quelle.
  7. Klicke auf Migrate repository.

Der Importer läuft im Hintergrund. Bei einem typischen Repository mit 100–500 MB und mittlerer Issue-/PR-Historie rechne mit 2–10 Minuten. Eine Fortschrittsanzeige in der Admin-Oberfläche zeigt die aktuelle Phase (Klonen der Git-Historie, Import der Issues, Import der PRs, Import der Releases).

Mit der API (skriptbarer Weg)

Für Sammelmigrationen skriptest du den Import gegen die fremforge-API. Die Endpunkte für Migration, Repositorys, Issues und PRs sind die Forgejo-native API, die fremforge unverändert unter frem.sh/_app/api/v1/... bereitstellt; sie sind nicht gesondert in der OpenAPI-Spezifikation von fremforge dokumentiert (die nur die Ergänzungen der fremforge-Steuerungsebene abdeckt: Nutzer, Richtlinien, Befunde, Exporte, Mandate). Die aktuelle Referenz der Forgejo-nativen Endpunkte findest du unter docs.frem.sh/api/openapi.yaml oder in der OpenAPI-Dokumentation von Forgejo upstream unter docs.codeberg.org/api/. fremforge hostet die Forgejo-Swagger-UI in Produktion nicht (bewusst deaktiviert, da ein bekanntes Ziel für Aufklärung). Alle Endpunkte unten sind Standard-API von 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 @-

Parallelisiere über Repositorys hinweg mit GNU parallel oder einem kleinen Steuerskript. Begrenze auf 3–5 gleichzeitige Importe, damit weder das PAT-Rate-Limit von GitHub noch deine lokale Bandbreite ausgereizt wird.

Was der Importer übernimmt und was nicht

Wird korrekt importiert:

  • Alle Branches und Tags mit vollständiger Commit-Historie.
  • Issues mit Titeln, Texten, Kommentaren, Labels, Meilensteinen und Zuständigen (über die E-Mail-Adresse zugeordnet, sofern der Nutzer auf fremforge existiert).
  • Pull Requests einschließlich Review-Kommentaren, Merge-Status und Schließgrund. Offene PRs werden zu offenen PRs, geschlossene PRs sind geschlossen.
  • Releases einschließlich binärer Anhänge (verschoben in den LFS-Speicher von fremforge in der EU).
  • Wiki-Seiten.

Wird nicht importiert:

  • Die Historie der GitHub-Actions-Workflow-Läufe. Frühere Läufe bleiben auf GitHub, neue Läufe beginnen frisch auf fremforge.
  • Werte von Secrets und Umgebungsvariablen: Diese gibst du neu ein (siehe Schritt 2).
  • Auf GitHub konfigurierte Integrationen von Drittanbietern. Diese müssen neu verbunden werden (siehe Schritt 5).
  • GitHub Projects (klassisch oder Projects v2). Forgejo hat kein 1:1-Gegenstück; einfache Inhalte von Projekt-Boards lassen sich von Hand oder über die Projects-Funktion von fremforge (Phase 1.5) neu anlegen.
  • Dependabot-Alerts. Der Abhängigkeits-Scan von fremforge läuft unabhängig auf Trivy/osv-scanner und erzeugt eigene Befunde.
  • Sicherheitshinweise des Repositorys. Lege die gewünschten unter Sicherheit › Berichte › Sicherheitshinweise neu an (Sicherheitshinweise) oder über deren API aus GitHubs GET /repos/{owner}/{repo}/security-advisories; veröffentlichte erhalten eine neue FFSA--ID, also behalte die GHSA-ID in den Referenzen.
  • GitHub Discussions. Dafür gibt es in Forgejo heute kein Gegenstück.
  • Benachrichtigungseinstellungen pro Nutzer. Mitglieder abonnieren auf fremforge neu.

Große Repositorys

Ist dein Repository größer als 2 GB oder übersteigt dein LFS-Bestand 5 GB, kann der Importer über die Oberfläche in eine Zeitüberschreitung laufen. Der Forgejo-Endpunkt /repos/migrate bietet keine Einstellung für die Zeitüberschreitung pro Aufruf, daher ist der empfohlene Ausweg, lokal einen direkten Git-Mirror-Clone zu erstellen und per git push --mirror in ein vorab angelegtes, leeres fremforge-Repository zu pushen:

# 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

Bei diesem Weg sind Issues und PR-Historie nicht enthalten. Importiere sie separat über die Forgejo-Migrate-API (POST /api/v1/repos/migrate, siehe das maßgebliche curl-Beispiel oben auf dieser Seite) mit "wiki": false, "issues": true, "pull_requests": true und richte die Anfrage auf die URL des bereits gepushten fremforge-Repositorys, sodass nur die Metadaten von GitHub geholt werden.

Der Secret-Scan beim Pre-Receive prüft diesen Push. fremforge führt gitleaks bei jedem Push als Forgejo-Pre-Receive-Hook aus, auch bei der --mirror-Variante oben. Enthalten deine historischen Commits echte Secrets (geleakte AWS-Schlüssel, abgelaufene Stripe-Tokens, eingebettete private Schlüssel), wird der Push abgewiesen, und die betroffenen Commit-SHAs werden ausgegeben; die gesamte Mirror-Operation schlägt atomar fehl. Das ist Absicht: Ein Secret aus einer öffentlichen Historie in fremforge zu importieren, rotiert es beim Upstream-Anbieter NICHT stillschweigend, daher ist der sichere Weg: erst bereinigen, dann importieren. Zwei Möglichkeiten zur Behebung:

  1. Zuerst die Historie bereinigen mit git-filter-repo (empfohlen) oder BFG Repo-Cleaner, dann erneut pushen. Informiere den Eigentümer des Secrets, dass die Historie beim Upstream-Anbieter ebenfalls undicht ist, egal was du am Ziel tust: Rotiere die geleakten Zugangsdaten an der Quelle.
  2. Eine einmalige Ausnahme anfordern bei support@frem.sh für bekanntermaßen widerrufene Secrets in archivierter Historie. Die Ausnahme wird protokolliert, auditiert und an eine schriftliche Bestätigung geknüpft, dass die Secrets bereits rotiert sind.

Lande zuerst main, damit der LFS-Push sinnvoll bleibt. Da git push --mirror gegenüber gitleaks atomar ist (alle Refs in einer Transaktion; eine Abweisung = leerer Mirror = der LFS-Push hat kein Ziel), lohnt es sich, zuerst einen einzelnen Branch zu pushen, um die Regeln zu bestätigen, bevor du jeden Ref auf einmal pushst. Zwischen git remote set-url und git push --mirror:

git push origin main --force-with-lease

Kommt main durch, kommen die übrigen Refs fast immer durch (die gitleaks-Regeln richten sich nach Inhalt, nicht nach Branch). Wird main abgewiesen, bereinige oder fordere eine Ausnahme an, bevor du den Mirror erneut versuchst. Es bringt nichts, andere Refs zu pushen, solange der Commit mit dem Secret auf main noch da ist.

Der Hook nutzt dieselben gitleaks-Regeln, die jedes fremforge-Repository schützen; es ist keine migrationsspezifische Prüfung. Führe vor dem Start pre-migration-check.sh aus; es zeigt dieselben Befunde, die der Hook finden würde, sodass du bereinigen kannst, bevor das Migrationsfenster beginnt.

LFS-Speicherkontingent und Kapazität für große Repositorys

git lfs push --all origin schreibt Objekte in das LFS-Kontingent deines fremforge-Mandanten. Kontingente nach Plan:

NutzerplanEnthaltener LFS-SpeicherWeiche Grenze vor der Drosselung
Standard (30 € pro Nutzer/Monat)5 GB pro Nutzer, auf Organisationsebene zusammengefasst90 % des Pools, Uploads liefern dann 429 quota_warning
Enterprise-on-DemandVerhandeltLaut Vertrag

Unter dem Kontingent des Plans liegen zwei praktische Grenzen:

  • Größe des Bare-Git-Repositorys. Übersteigt das Bare-.git des Repositorys (nach git gc --aggressive) etwa 5 GiB, wende dich vor der Migration an support@frem.sh, damit wir den Spielraum für dein Repository bestätigen können.
  • Sehr große LFS-Pushes. Ein git lfs push von mehr als etwa 100 GiB in einer Sitzung muss eventuell in Portionen von ≤50 GiB aufgeteilt werden, um eine Drosselung durch das Rate-Limit zu vermeiden. Der Fehler sieht aus wie HTTP 503 mit X-Reserved: ratelimit in der Antwort: Warte 60 s und setze fort; LFS lässt sich fortsetzen.

Wenn du nicht sicher bist, wie groß der LFS-Bestand wird, führe git lfs ls-files --size --all | awk '{s+=$2} END {print s/1024/1024/1024 " GiB"}' gegen das Quell-Repository aus, bevor du den Mirror-Push startest.

Schritt 2: Secrets und Umgebungsvariablen

GitHub speichert Secrets auf Ebene der Organisation, der Umgebung und des Repositorys. fremforge nutzt dieselben drei Ebenen.

Wichtig: Werte von Secrets lassen sich nicht aus GitHub exportieren. Die API von GitHub gibt die Namen von Secrets zurück, aber nie ihre Werte. Entweder kennst du den Wert (bei der Migration rotieren, empfohlen), oder du holst ihn aus deiner maßgeblichen Secret-Verwaltung (Passwortmanager, Vault, CI-Orchestrierungswerkzeuge).

Secrets neu eingeben

Entscheide für jedes Secret:

  • Ist es ein langlebiger Zugang, der ohnehin durch OIDC-Föderation ersetzt werden sollte? Wenn ja, richte die OIDC-Föderation mit T Cloud Public ein (siehe Schritt 3) und lösche das Secret, statt es zu migrieren.
  • Ist es ein API-Schlüssel eines Drittanbieters oder ein Dienstzugang ohne OIDC-Alternative? Rotiere den Zugang an der Quelle und setze dann den neuen Wert in fremforge.
  • Ist es ein kryptografischer Schlüssel, der in Builds verwendet wird? Rotiere ihn und setze ihn dann in fremforge.

Setze Secrets in der Admin-Oberfläche von fremforge auf der passenden Ebene:

  • Secrets der Organisation, verfügbar für jedes Repository der Organisation. Gesetzt unter Organisationsverwaltung → Secrets (frem.sh/<org>/_admin/secrets).
  • Secrets der Umgebung, nur in der genannten Umgebung verfügbar (z. B. production, staging). Gesetzt unter Organisationsverwaltung → Umgebungen → <env> → Umgebungs-Secrets.
  • Secrets des Repositorys, auf ein Repository beschränkt. Gesetzt unter Repository → Einstellungen → Actions → Geheimnisse.

Umgebungsvariablen (Konfiguration ohne Secrets)

GitHub Actions unterstützt env: und vars: auf Ebene von Workflow, Job und Step. fremforge Actions unterstützt dieselbe Syntax; für Inline-Variablen ist keine Migration nötig.

Für Variablen auf Ebene der Organisation und des Repositorys (der vars:-Kontext bei GitHub) hat fremforge dieselben Ebenen. Gesetzt unter Einstellungen → Actions → Variablen in den Forgejo-Einstellungen der Organisation oder des Repositorys.

Schritt 3: Anpassung der Actions-Workflows

Forgejo Actions ist weitgehend kompatibel mit GitHub Actions, aber nicht bitgenau identisch. Ein Workflow, der auf GitHub läuft, läuft auf fremforge meist mit zwei oder drei gezielten Anpassungen. Die Kompatibilitätsmatrix der Top-20-Marketplace-Actions unter docs.frem.sh/marketplace-compat dokumentiert, welche Actions unverändert funktionieren, welche einen Wrapper brauchen und welche kein Gegenstück in fremforge haben.

Änderungen, die fast jeden Workflow betreffen

1. uses:-Referenzen können für die wichtigen GitHub-Actions als actions/*@version bleiben.

Der Runner von fremforge löst uses:-Anweisungen über die EU-internen Mirrors von fremverk unter https://frem.sh/<owner>/<repo> auf (eine Mirror-Organisation pro Upstream-Herausgeber, sodass actions/checkout zu frem.sh/actions/checkout aufgelöst wird); Runner-VMs greifen beim Jobstart nicht direkt auf github.com zu (DPA Anhang A.6). Das funktioniert für actions/checkout, actions/setup-node, actions/setup-go, actions/setup-python, actions/setup-java, actions/cache, actions/upload-artifact, actions/download-artifact und den Rest der offiziellen actions/*, die bereits gespiegelt sind. Für gespiegelte Actions musst du deine uses:-Zeilen nicht ändern; fehlt eine Referenz, siehe Häufige Stolperfallen unten.

2. Die Semantik von ${{ secrets.GITHUB_TOKEN }} weicht leicht ab.

GitHub liefert mit jedem Workflow automatisch ein Token mit Berechtigungen, die auf das aufrufende Repository beschränkt sind. Forgejo liefert ein Gegenstück als ${{ secrets.FORGEJO_TOKEN }}, und ${{ secrets.GITHUB_TOKEN }} ist ein Alias für denselben Token, sodass die meisten Workflows einfach funktionieren. Verwende einen dieser beiden Namen statt des älteren ${{ secrets.GITEA_TOKEN }}. Seit dem 21. Oktober 2026 setzen die gehosteten Runner (forgejo-runner 13) keine GITEA_*-Umgebungsvariablen mehr; ersetze also GITEA_ACTIONS durch FORGEJO_ACTIONS oder GITHUB_ACTIONS und GITEA_ACTIONS_RUNNER_VERSION durch FORGEJO_ACTIONS_RUNNER_VERSION. Erwartet ein Workflow bestimmtes Verhalten der GitHub-API hinter diesem Token (z. B. das Auslösen der GitHub Checks API), muss er angepasst werden. Für Forgejo-native Check-Runs liegt die entsprechende API unter frem.sh/api/v1/repos/{owner}/{repo}/check-runs.

3. Actions, die die GitHub-REST-API direkt aufrufen, müssen angepasst werden.

Nutzt ein Workflow curl https://api.github.com/... oder octokit, um die REST-API von GitHub direkt aufzurufen, müssen diese Aufrufe über die fremforge-API auf https://frem.sh/_app/api/v1/... zielen (auf REST-Ebene weitgehend GitHub-kompatibel). Siehe die OpenAPI-Spezifikation.

4. Die Standard-Shell der Steps weicht ab.

Die Standard-Shell des Forgejo-Runners ist bash mit POSIX-Flags. Die Standards des GitHub-Runners unterscheiden sich subtil zwischen Linux und Windows/macOS. Hängt dein Workflow von bestimmtem Quoting-Verhalten der Shell ab, setze ausdrücklich shell: bash (Linux), shell: pwsh (Windows) oder shell: sh (nur POSIX).

Änderungen, die manche Workflows betreffen

if: github.*-Kontext.

Forgejo Actions stellt github.*-Kontextvariablen mit denselben Namen wie GitHub Actions bereit. Fast alle if-Ausdrücke lassen sich unverändert übernehmen. Sonderfälle betreffen GitHub-spezifische Metadaten (z. B. github.event.pull_request.auto_merge), bei denen Forgejo möglicherweise nicht genau dieselbe Eigenschaft bereitstellt.

Marketplace-Actions, die GitHub-API-spezifisch sind.

Beispiele: peter-evans/create-pull-request, marocchino/sticky-pull-request-comment, nwtgck/actions-netlify. Die meisten funktionieren ohne Weiteres, weil die REST-Schnittstelle von fremforge ihre API-Aufrufe akzeptiert. Einige wenige brauchen kleine Patches. Die Top-20-Matrix dokumentiert konkrete Workarounds.

Workflows, die umgeschrieben werden müssen

Nutzt dein Workflow Funktionen, die spezifisch für GitHub Enterprise sind (API für Organisations-Rulesets, GHES-spezifische Metrik-Endpunkte, API für Copilot Extensions, GitHub Packages über npm/Docker/Maven hinaus), müssen diese ersetzt werden. Meist ist der Ersatz fremforge-nativ:

  • Organisations-Rulesets → Richtlinie auf Organisationsebene in fremforge (Organisationsverwaltung → Sicherheit → Richtlinien → Repository-Regeln).
  • GitHub Packages → Paket-Registry von fremforge (unterstützt npm, Maven, Docker, NuGet, PyPI, RubyGems, Composer, Go).
  • Copilot Extensions → bewusst außerhalb des Umfangs von fremforge (siehe den Beitrag zur KI-Haltung auf www.frem.sh).

Schritt 4: SSH-Schlüssel neu registrieren

Öffentliche SSH-Schlüssel gehören zum einzelnen Nutzer und werden nicht migriert. Jeder Entwickler fügt seinen öffentlichen SSH-Schlüssel seinem fremforge-Konto hinzu:

  1. Melde dich bei fremforge an.
  2. Einstellungen → SSH- / GPG-Schlüssel → Schlüssel hinzufügen.
  3. Füge den öffentlichen Schlüssel ein (~/.ssh/id_ed25519.pub oder Entsprechendes).

Die Fingerabdrücke der Host-Schlüssel für frem.sh sind unter www.frem.sh/ssh-fingerprints veröffentlicht. Entwickler sollten sie bei der ersten SSH-Verbindung prüfen, um einen unbemerkten MITM-Angriff auszuschließen. Der Fingerabdruck erscheint bei der ersten Verbindung; Entwickler vergleichen ihn mit der Vertrauensseite, bestätigen, und der Schlüssel wird für spätere Verbindungen gepinnt.

Für Teams, die SSH-Zertifizierungsstellen nutzen, unterstützt fremforge die Konfiguration vertrauenswürdiger CAs direkt in der Admin-Oberfläche der Organisation unter <your-org>/_admin/auth-policy: Der Abschnitt zur SSH-CA liegt unter dem Schalter „SSH-Protokoll erlauben“ (am 26.05.2026 in die Authentifizierungsrichtlinie übernommen; das eigenständige /admin/ssh-ca/ leitet hierher weiter). Füge den öffentlichen OpenSSH-Schlüssel deiner CA ein, wähle eine Principal-Richtlinie (Benutzername / E-Mail / opak) und erzwinge optional „Zertifikatsauthentifizierung verlangen“, damit eine Anmeldung mit einfachem öffentlichem Schlüssel abgewiesen wird. Die vollständige Einrichtung mit Beispielen für die Integration von Smallstep und Vault findest du im Abschnitt zur SSH-Zertifizierungsstelle im Leitfaden zur Authentifizierungsrichtlinie. Jeder Nutzer, der sich mit einem von der CA ausgestellten Zertifikat authentifiziert, wird mit den Berechtigungen des passenden fremforge-Kontos zugelassen.

Für Teams, bei denen SSO erzwungen wird (sso_required = true auf Organisationsebene), prüft die SSH-Authentifizierung zusätzlich bei jeder Verbindung einen OIDC-Refresh-Token gegen den IdP des Mandanten (15 Minuten zwischengespeichert). Wird ein Nutzer auf der IdP-Seite deprovisioniert, ist sein SSH-Zugriff also innerhalb von 15 Minuten gesperrt, auch wenn sein SSH-Schlüssel noch auf fremforge registriert ist. Ein gesondertes Aufräumen der Schlüssel ist nicht nötig.

Schritt 5: Integrationen von Drittanbietern neu verbinden

Auf GitHub konfigurierte Integrationen (Webhooks, CI-Benachrichtigungen an Slack/Teams, Deploy-Hooks zu Vercel/Netlify, Issue-Tracker-Synchronisierung mit Jira/Linear, Code-Review-Werkzeuge wie Sourcegraph oder Graphite) werden nicht automatisch migriert. Jede muss neu verbunden werden.

Webhooks

GitHub-Webhooks liegen unter Repository → Settings → Webhooks. Webhooks in fremforge liegen an derselben Stelle der Admin-Oberfläche. Das Format der Webhook-Payload ist weitgehend kompatibel; die wichtigsten Unterschiede:

  • Der Header X-GitHub-Event bei GitHub heißt auf fremforge X-Forgejo-Event (oder X-Gitea-Event für Gitea-kompatible Empfänger). Die meisten generischen Webhook-Empfänger akzeptieren beide.
  • Die Zustellungskennung ist X-Gitea-Delivery + X-Hook-UUID (das Gegenstück zu GitHubs X-GitHub-Delivery). Beide sind bei jedem Webhook von fremforge vorhanden; die meisten Empfänger richten sich nach einem von beiden.
  • Die Ereignistypen sind eine nahe Obermenge der Kernereignisse von GitHub. push, pull_request, pull_request_review, issues, issue_comment, release, create, delete, fork und star sind alle vorhanden.
  • Der Signatur-Header ist X-Forgejo-Signature (HMAC-SHA256 mit deinem Webhook-Secret).

Für Empfänger, die gegen die API von GitHub geschrieben sind (Integrationen für Slack, Discord, PagerDuty), gibt es zwei Möglichkeiten:

  1. Den Empfänger auf seine Forgejo-native Integration umstellen. Die Forgejo-Integration von Slack, das Forgejo-Webhook-Ziel von Discord usw. gibt es meist, und sie sind der sauberere Weg.
  2. Den Webhook auf der Empfängerseite anpassen. Ist der Empfänger ein eigener interner Dienst, ergänze die Verarbeitung von Forgejo-Ereignissen neben der von GitHub-Ereignissen. Meist eine kleine Änderung.

CI-Integrationen (CircleCI, TravisCI, Jenkins)

Wenn du CI außerhalb der Forge betreibst (CircleCI, externes Jenkins, Buildkite), ist die Migration einfach: Richte diese CI-Systeme auf die fremforge-Repositorys statt auf die GitHub-Repositorys aus. Die meisten externen CI-Systeme unterstützen Forgejo/Gitea als Quelle; die Konfigurationsänderung erfolgt im CI-System, nicht in fremforge.

Die meisten Teams, die zu fremforge migrieren, nutzen die Gelegenheit, um auf die gehosteten Runner von fremforge zu konsolidieren und die externe CI abzulösen. Runner-Minuten sind im Pauschalpreis pro Nutzer enthalten. Die Rechnung findest du im TCO-Beitrag im fremverk-Blog.

Deploy-Ziele (Vercel, Netlify, Cloudflare Pages)

Jeder Dienst verbindet sich mit fremforge entweder über native Unterstützung (Vercel und Netlify bieten Git-Quell-Integrationen für Forgejo/Gitea) oder über einen generischen Deploy-Hook per Git-Push. Dokumentiere deine neuen Webhook-URLs und aktualisiere sie im Dashboard jedes Dienstes.

Issue-Tracker-Synchronisierung (Jira, Linear, Zendesk)

Beruht deine Issue-Tracker-Synchronisierung auf Git-Commits (Verknüpfung von Commits mit Tickets über die ID), funktioniert sie weiter. Die Commit-SHAs bleiben bei der Migration erhalten. Beruht die Synchronisierung auf der GitHub-API (lauscht auf PR-Ereignisse, fragt GitHub-Issues ab), stelle sie auf fremforge-Webhooks um oder schalte sie ab.

Schritt 6: DNS und eigene Domains (falls zutreffend)

fremforge stellt Repository-Inhalte nur unter frem.sh/<org>/<repo> bereit. Eigene Git-Domains von Kunden werden nicht unterstützt: Es gibt kein Gegenstück zur Funktion „custom hostname“ von GitHub Enterprise Server, bei der TLS mit deinem Zertifikat auf git.company.com terminiert. Zwei Folgen, die wir ausdrücklich nennen:

Vanity-CNAME ohne TLS

Ein Vanity-CNAME im DNS des Kunden (z. B. internes git.company.com als CNAME → frem.sh) ist technisch möglich, aber das ausgelieferte TLS-Zertifikat ist immer das *.frem.sh-Zertifikat von fremforge, NICHT ein *.company.com-Zertifikat. Ein Browser, der https://git.company.com/... aufruft, zeigt eine Warnung wegen nicht übereinstimmender Namen, es sei denn, der Kunde stellt zusätzlich sein eigenes Zertifikat über einen eigenen vorgeschalteten Reverse Proxy bereit. Das ist Sache des Kunden: fremforge terminiert TLS nicht für Vanity-Hostnamen, akzeptiert keine vom Kunden gelieferten Zertifikate und betreibt keine SNI-Schicht mit mehreren Zertifikaten.

Empfohlener Weg für Kunden, die von GitHub Enterprise Server wegmigrieren: Übernimm direkt das URL-Muster frem.sh/<org>/*. Aktualisiere interne Links, CI-Konfigurationen und Dokumentation auf die neuen URLs. Der Weg über Vanity-CNAME mit eigenem Zertifikat erzeugt Betriebsaufwand (Zertifikatserneuerung, Proxy-Betrieb) und ist keine von fremforge unterstützte Konfiguration.

Bring einen Enterprise-on-Demand-Vertrag mit, wenn deine Beschaffung ein SLA für Vanity-Domains verlangt. Das eröffnet ein Gespräch über eine dedizierte Edge-Schicht mit Terminierung von Kundenzertifikaten, liegt aber außerhalb des Umfangs der Self-Service-Stufe.

Was migriert wird und was nicht

Dieser Abschnitt führt auf, mit welcher Genauigkeit die Artefakte von GitHub durch die Migration kommen. Nutze ihn als Checkliste zur Abstimmung vor der Migration.

ArtefaktMigriert?Hinweise zur Genauigkeit
Repository-Inhalt (Commits, Branches, Tags)✓SHA-stabil; vollständige Historie erhalten
LFS-Objekte✓ (≤ 5 GB Pool mit dem Importer über die Oberfläche; größer per Mirror-Clone)Dieselben OIDs; die Größengrenze ist betrieblich, nicht durch das Protokoll bedingt
Issues✓ nach bestem BemühenDer Importer von Forgejo vergibt importierten Issues fortlaufende Issue.Index-Werte; Lücken in der Nummerierung der Quelle bleiben nicht erhalten (z. B. wird GitHub #1, #2, #42 auf Forgejo zu #1, #2, #3). Querverweise zwischen Issues in Kommentartexten werden auf die vergebenen Indizes umgeschrieben, wenn der Importer sie auflösen kann; nicht auflösbare Verweise bleiben als wörtlicher Text stehen. Kommt es auf exakt gleiche Nummern an (langjährige Issue-Tracker mit öffentlichen Lesezeichen), ist der Weg über die API, am Ziel vor dem Import für jede Lücke einen Platzhalter-Issue anzulegen und diese nach dem Import zu löschen.
Pull Requests✓ nach bestem BemühenPRs teilen sich den Nummernraum mit den Issues (der gemeinsame Zähler von Forgejo, wie bei Gitea), sodass die relative Reihenfolge erhalten bleibt, die absoluten Nummern aber dem Vorbehalt in der Issue-Zeile oben folgen: Lücken in der Nummerierung der Quelle fallen beim Import weg. Hat deine Quelle Issue #1, PR #2, Issue #5, PR #7, erhält das Ziel Issue #1, PR #2, Issue #3, PR #4. Nutze denselben Workaround mit vorab angelegten Platzhaltern wie bei Issues, wenn es auf exakte PR-Nummern ankommt (öffentliche Lesezeichen, Deep Links). Ausstehende PRs werden als Entwurf migriert, wenn sie zum Zeitpunkt der Migration offen sind.
PR-Review-Kommentare (inline, an Zeilen verankert)⚠ teilweiseAn Zeilen verankerte Kommentare werden zu einfachen PR-Kommentaren (Grenze des Datenmodells zwischen Forges). Siehe „PR-Review-Kommentare werden als einfache PR-Kommentare importiert“ unten.
Branch-Schutzregeln✗, neu anlegenDie Regelform branch_protections von GitHub lässt sich nicht auf die BranchProtection-Form von Forgejo abbilden. Vor der Migration: Erfasse jede Regel mit gh api /repos/<owner>/<repo>/branches/<name>/protection. Nach der Migration: Lege sie in der Admin-Oberfläche von fremforge im Tab Repository-Regeln plus Übersteuerung pro Repository neu an. Eine in die Organisation eingecheckte Vorlage .gitea/branch-protection.yaml kann den gewünschten Zustand festhalten; heute erfolgt das Anwenden durch den Operator über die Admin-Oberfläche (Branch-Schutz als Code über die API ist eine Funktion für Phase 2).
Webhooks✗, nicht erhaltenDer Migrate-Endpunkt von Forgejo liest keine Webhooks aus der Quell-Forge aus (die Downloader für GitHub/GitLab durchlaufen keine Hooks; es gibt kein Flag migrate webhooks in MigrateRepoOptions). Kunden haben am Ziel null Webhooks. Lege die Webhooks nach der Migration auf fremforge anhand der Bestandsliste neu an, die pre-migration-check.sh erzeugt: Sie nennt URL und Ereignisse jedes Quell-Webhooks. HMAC-Secrets lassen sich aus GitHub nicht auslesen, daher braucht jede empfangende Integration außerdem ein neues Secret, das im Dashboard des Quelldienstes rotiert wird, sobald die fremforge-URL neu registriert ist. fremforge stellt historische Ereignisse auch nicht erneut zu.
Submodule⚠ URL-Umschreibung nötig.gitmodules-URLs, die auf github.com/<org>/<repo> zeigen, bleiben nach der Migration wörtliche github.com-URLs. Entweder (a) aktualisierst du nach der Migration jeden .gitmodules-Eintrag auf die neue fremforge-URL und committest, ODER (b) du nutzt git config submodule.<name>.url <fremforge-url> pro Clone, wenn das übergeordnete Repository nicht unter deiner Kontrolle steht. Der Importer von fremforge schreibt .gitmodules nicht automatisch um, weil die URLs der Submodule Inhalt sind, der dem Autor des Projekts gehört.
Actions-Secrets der Organisation✗, neu eingebenSecrets lassen sich aus GitHub per API bewusst nicht zurückholen. Gib sie unter Organisationsverwaltung → Secrets (frem.sh/<org>/_admin/secrets) neu ein. Vor der Migration: Liste sie mit gh secret list --org <org> auf, damit du die Namen zum Neueingeben hast.
Actions-Variablen der Organisation (keine Secrets)✓ per ExportEinfache Variablen lassen sich mit gh variable list --org <org> --json name,value > gh-vars.json exportieren und über die Admin-Oberfläche von fremforge wieder importieren. Für einen Sammelimport per API leitest du den Export durch den Variablen-Endpunkt: 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. Dieselbe Form funktioniert für Variablen auf Repository-Ebene (ersetze /orgs/<org>/ durch /repos/<owner>/<repo>/).
GitHub Discussions✗, kein GegenstückForgejo bietet heute kein Gegenstück zu Discussions. Exportiere sie in ein separates Archiv, wenn Diskussionsverläufe für deine Organisation tragend sind.
GitHub Projects (Boards)✗, kein GegenstückDie Projektverfolgung wird in fremforge mit Issues, Labels und Meilensteinen neu aufgebaut.

Fortsetzbarkeit

Der Forgejo-Endpunkt /repos/migrate ist nicht fortsetzbar. Bricht der Aufruf mittendrin ab (Netzwerkabbruch, Rate-Limit der Quell-API usw.), bleibt das teilweise importierte Repository in einem inkonsistenten Zustand. Vorgehen zur Behebung:

  1. Lösche das unvollständige Repository in der Admin-Oberfläche von fremforge unter Einstellungen → Löschen.
  2. Setze den Migrate-Aufruf sofort erneut ab. Liefert er 422 mit repository already exists, warte 5 Sekunden und versuche es erneut: Das ist Replikationsverzug von RDS auf dem Pfad über das Lese-Replikat, kein Tombstone-Zyklus von Forgejo.
  3. Schlägt der zweite Versuch genauso fehl, verwende einen neuen Repository-Namen.

Für Repositorys, bei denen ein erneuter Import teuer ist (großes LFS, viele Issues), nutze den lokalen Mirror-Ausweg unter „Große Repositorys“: git push --mirror ist von Natur aus fortsetzbar, weil Git selbst Netzwerkabbrüche sauber behandelt.

Prüfung nach der Migration

Über die Liste „Prüfen und stilllegen“ in Schritt 7 unten hinaus die Prüfpunkte nach der Migration, die Kunden am häufigsten vergessen:

  • Anzahl der Commits vergleichen. git rev-list --count HEAD im GitHub-Clone und im fremforge-Clone. Die Zahlen müssen genau übereinstimmen.
  • Liste der Branches vergleichen. git branch -r | sort auf beiden Seiten und die Ausgaben mit diff vergleichen. Veraltete refs/pull/*-Refs von GitHub werden nicht migriert (Forgejo nummeriert PRs in seinem eigenen Ref-Raum); alles andere sollte übereinstimmen.
  • Liste der Tags vergleichen. git tag --sort=v:refname auf beiden Seiten; erwarte identische Listen.
  • Anzahl der LFS-Pointer vergleichen. git lfs ls-files | wc -l; die Zahlen sollten genau übereinstimmen. Wenn nicht, führe git lfs fetch --all && git lfs push --all origin gegen das fremforge-Remote aus.
  • Anzahl und Nummerierung von Issues / PRs. gh issue list --limit 5000 --state all --json number | jq length auf GitHub gegen fremforge /api/v1/repos/<org>/<repo>/issues?state=all (mit Paginierung). Paginierungsschleife für 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. Nummerierung erhalten.
  • CI grün. Löse einen No-op-Build auf main aus und prüfe, dass der Forgejo-Actions-Lauf success erreicht. Das deckt Lücken im uses:-Mirror auf (die häufigste CI-Störung nach der Migration).

Zeigt einer dieser Punkte Abweichungen, lege die GitHub-Quelle erst still, wenn die Abweichung behoben ist.

Schritt 7: Prüfen und stilllegen

Nach der Migration:

  1. Klone das migrierte Repository von fremforge, führe den Build aus und prüfe, dass die Tests bestehen.
  2. Öffne einen Test-PR, um zu prüfen, dass der Secret-Scanner beim Pre-Receive, der Abhängigkeits-Scanner und die Prüfung signierter Commits wie erwartet aktiv sind.
  3. Sieh in der Admin-Oberfläche in der Ansicht Befunde nach, ob die migrierte Historie keine überraschenden Scan-Ergebnisse hat.
  4. Prüfe unter Einstellungen → Webhooks → Letzte Zustellungen, dass Webhooks korrekt zugestellt werden.
  5. Prüfe, dass die SSO-Anmeldung für jeden Nutzer funktioniert, der auf das Repository zugreifen wird.
  6. Aktualisiere Dokumentation und interne Wikis, sodass sie auf die neuen Repository-URLs zeigen.
  7. Setze die GitHub-Repositorys nach 30 Tagen erfolgreichem Betrieb auf fremforge auf archiviert. Lösche sie nicht; behalte sie für die Audit-Historie.

Rollback (teilweise, plane entsprechend)

Die Migration ist teilweise umkehrbar, nicht vollständig. Sei dir ehrlich darüber im Klaren, was in beide Richtungen funktioniert und was nicht, bevor du Produktionsverkehr umstellst.

Was ein Rollback zurückholen KANN:

  1. Git-Historie: git push --mirror aus einem lokalen fremforge-Clone zurück in das GitHub-Repository stellt Branches, Tags und Commits wieder her.
  2. Webhooks + Integrationen: Schalte sie auf der GitHub-Seite wieder ein; die Ziel-URLs der Webhooks musst du von Hand wieder auf die bei GitHub gehosteten Endpunkte setzen.

Was ein Rollback NICHT mit voller Genauigkeit zurückholen kann:

  1. Nach der Migration angelegte Issues, PRs und Kommentare: Organisationsverwaltung → Datenexport in fremforge erzeugt einen JSON-Dump, aber die Import-API von GitHub nutzt ein anderes Schema, sodass der erneute Import eine manuelle Zuordnungsarbeit ist. Issue-Nummern stimmen nicht überein; Querverweise in Commit-Nachrichten laufen ins Leere. Für die Zuordnung der Autoren braucht jeder Mitwirkende wieder ein GitHub-Konto. Reaktionen, Review-Verläufe und die Zeilenverankerung von Inline-Kommentaren überstehen den Rückweg meist nicht.
  2. Auf fremforge entstandene CI-Historie + Actions-Logs: in keinem gleichwertigen Format exportierbar.
  3. fremforge-spezifische Befunde: Abweisungen durch den Secret-Scan, Ergebnisse des Abhängigkeits-Scans und auf fremforge erstellte Attestierungen signierter Commits haben kein GitHub-Gegenstück, in das sie sich importieren ließen.

Betrachte die Migration für den Produktionseinsatz als Einbahnstraße. Führe zuerst einen Pilot mit einem einzigen, unkritischen Repository durch; prüfe, dass CI, Webhooks und SSO funktionieren; migriere dann den Rest in Portionen. Die Aussage „innerhalb von 30 Tagen umkehrbar“ gilt nur für ein Rollback der reinen Git-Historie; verlass dich nicht darauf, um den vollständigen Stand der Zusammenarbeit zurückzuholen.

Häufige Stolperfallen

LFS-Objekte nach der Migration nicht sichtbar.

Der Importer über die Oberfläche übernimmt LFS bei kleinen Beständen (<5 GB) automatisch. Bei größeren Beständen führe git lfs fetch --all in einem lokalen Mirror-Clone und git lfs push --all origin zu fremforge von Hand aus.

Actions-Workflows schlagen beim ersten Lauf mit „action not found“ fehl.

Die Mirrors unter https://frem.sh/<owner>/<repo> (siehe Auflösung von Actions oben) decken die Standardmenge actions/* und zehn weitere Herausgeber-Organisationen ab. Eine fehlgeschlagene uses:-Referenz bedeutet, dass die Action noch nicht gespiegelt ist: Öffne ein Ticket bei support@frem.sh mit der fehlenden Referenz, dann nimmt der nächste Mirror-Durchlauf sie auf; oder pinne auf eine früher aufgelöste Version, die bereits zwischengespeichert ist.

PR-Review-Kommentare werden als einfache PR-Kommentare importiert.

Der Importer von Forgejo bildet PR-Review-Kommentare auf PR-Kommentare ab, nicht auf Review-Kommentare auf Zeilenebene. Das ist eine Grenze des Datenmodells zwischen Forges; Inline-Review-Kommentare verlieren den Bezug zu ihrer Ankerzeile. Workaround: Exportiere sie für Repositorys, bei denen Inline-Kommentare tragend sind, vor der Migration über die API von GitHub in eine separate Datendatei und bewahre sie als Archivanhang am migrierten PR auf.

Nutzer werden nicht automatisch zugeordnet.

Der Importer ordnet GitHub-Nutzer über die E-Mail-Adresse zu. Nutzer, deren GitHub-E-Mail nicht mit ihrer fremforge-E-Mail übereinstimmt (z. B. private E-Mail bei GitHub, Firmen-E-Mail bei fremforge), erscheinen in importierten Issues als „Unknown user“. Ordne sie entweder vorab zu, indem du die GitHub-seitige E-Mail vor dem Import als zweite E-Mail-Adresse zum fremforge-Konto hinzufügst, oder akzeptiere die Anzeige „Unknown user“ und verlass dich auf die ursprüngliche Zuordnung, die in der Commit-Historie sichtbar ist.

Hilfe bekommen

Wenn etwas in diesem Leitfaden für dein Setup nicht funktioniert:

  • Schreib an support@frem.sh mit einer Betreffzeile, die mit MIGRATION, GITHUB - beginnt, und einer Beschreibung, wo du festhängst.
  • Bist du im Early-Adopter-Plan, hast du ohne Aufpreis einen direkten Draht zum Entwicklungsteam von fremforge, wenn du Hilfe bei der Migration brauchst.

Siehe auch: Leitfaden zur Migration von GitLab · Leitfaden zur Migration von Azure DevOps · Kompatibilitätsmatrix der Top-20-Marketplace-Actions · Checkliste vor der Migration.