Zum Hauptinhalt springen

Von Azure DevOps zu fremforge migrieren

Diese Anleitung beschreibt die Migration von Azure DevOps Services (dev.azure.com) zu fremforge. Die Migration von Azure DevOps Server (on-premises) läuft ähnlich ab, aber Authentifizierung und API-Endpunkte unterscheiden sich. Passe die Abschnitte zu Token und Endpunkten unten an dein konkretes Deployment an.

Azure DevOps unterscheidet sich strukturell am stärksten von den drei großen Migrationsquellen. ADO hat getrennte Produkte für Repos, Pipelines, Boards, Test Plans und Artifacts; fremforge liefert Repos + CI/CD + Artifacts + einfache Issues als eine zusammenhängende Oberfläche und bietet keine Entsprechungen für Test Plans oder den vollen Funktionsumfang von Boards. Eine ADO-Migration ist daher teils eine Entscheidung über den Umfang und teils eine technische Migration: Für manche ADO-Funktionen, auf die du dich vielleicht verlässt, gibt es bei fremforge kein Ziel.

Lücken im Funktionsumfang

fremforge hat keine Entsprechungen für: Work Items von Azure Boards (keine Issue-Hierarchie und keine Sprint-Planung), Test Plans (keine Verwaltung von Testfällen), die automatische Migration von Azure-Artifacts-Feeds (Pakete müssen neu veröffentlicht werden) und klassische Pipelines (YAML-Pipelines lassen sich migrieren, im Designer erstellte Pipelines nicht). Sind das für dich K.-o.-Kriterien, bewerte den Umfang der Migration, bevor du beginnst.

Lies zuerst die Anleitung zur GitHub-Migration und die Anleitung zur GitLab-Migration, falls noch nicht geschehen. Einige grundlegende Schritte (SSH-Schlüssel, Integrationen von Drittanbietern) sind identisch, und wir wiederholen sie hier nicht vollständig.

Bevor du beginnst

Was du auf deiner Seite brauchst:

  • Die Rolle Project Administrator in den Azure-DevOps-Projekten, die du migrierst.
  • Einen persönlichen Zugriffstoken bei ADO mit mindestens den Scopes Code (Read), Code (Status), Work Items (Read), Build (Read), Release (Read) und Identity (Read).
  • Admin-Zugriff auf die fremforge-Organisation, in die du migrierst.
  • Für die Migration der Pipelines: eine Bestandsaufnahme der YAML-Pipeline-Dateien, der klassischen (nicht YAML-basierten) Pipelines, falls vorhanden, der Service Connections (sie werden zu OIDC-Föderation), der Variable Groups und der Agent Pools, auf die du angewiesen bist.

Was wir empfehlen:

  • Stelle klassische (nicht YAML-basierte) Pipelines in ADO vor der Migration auf YAML-Pipelines um. Die Migration von klassischen Pipelines zu Forgejo Actions ist praktisch eine Neuentwicklung; die Umstellung auf YAML gibt dir einen portablen Ausgangspunkt und verbessert nebenbei dein ADO-Setup.
  • Ermittle, welche Work-Item-Typen in Boards du tatsächlich nutzt. fremforge (Forgejo) hat Issues und Meilensteine, aber keine Epics, Features, User Stories oder Tasks als eigene Typen. Sie werden alle zu Issues mit Labels. Hängt dein Prozess von der Hierarchie der Work-Item-Typen ab, plane diese Zusammenführung vor der Migration.
  • Ermittle Abhängigkeiten von Test Plans. fremforge hat keine direkte Entsprechung; Teams, die stark auf ADO Test Plans angewiesen sind, betreiben ADO Test Plans meist als separates Tool weiter oder wechseln zu einem eigenen Werkzeug für Testmanagement.

Zeitaufwand:

  • Einzelnes Repository mit einfacher Pipeline und geringer Nutzung von Boards: 1 bis 2 Stunden.
  • Repository mit mäßig komplexer Pipeline und mehrstufigen Release-Pipelines: 3 bis 6 Stunden.
  • Migration einer ganzen Organisation mit vielen Pipelines, Variable Groups und Service Connections: 1 bis 2 Entwicklerwochen, überwiegend für die Umstellung der Pipelines und den Ersatz der Service Connections.

Schritt 1: Repository und Historie migrieren

Der eingebaute Importer von Forgejo unterstützt Azure DevOps als Quelle. Er kopiert die Git-Historie und, je nach deiner ADO-Konfiguration, Work Items (als Issues importiert) und Pull Requests.

Mit dem eingebauten Importer (über die Oberfläche)

In der Verwaltungsoberfläche von fremforge:

  1. Klicke auf + → Neue Migration.
  2. Wähle Azure DevOps als Quelle.
  3. Füge die URL des Repositorys ein (z. B. https://dev.azure.com/acme/project/_git/backend).
  4. Füge deinen persönlichen Zugriffstoken von ADO ein.
  5. Hake die zu importierenden Inhalte an.
  6. Wähle die Zielorganisation und den Repository-Namen.
  7. Klicke auf Migrate repository.

Über die API (skriptbar)

# Build the JSON body via jq so the PAT is JSON-string-escaped safely
# (Azure DevOps PATs can contain `/`, `+`, `=` characters which are
# fine in JSON strings but a raw shell-interpolation can still break
# if the PAT happens to contain `"` from a copy-paste error).
jq -nc \
  --arg clone_addr    "https://dev.azure.com/acme/project/_git/backend" \
  --arg auth_username "fremforge" \
  --arg auth_token    "$ADO_TOKEN" \
  --arg repo_owner    "acme" \
  --arg repo_name     "backend" \
  '{clone_addr: $clone_addr, auth_username: $auth_username, auth_token: $auth_token,
    service: "git", repo_owner: $repo_owner, repo_name: $repo_name,
    issues: false, pull_requests: false, lfs: true}' \
| curl -X POST "https://frem.sh/api/v1/repos/migrate" \
    -H "Authorization: Bearer ${FREMFORGE_TOKEN}" \
    -H "Content-Type: application/json" \
    -d @-

Hinweis: ADO gehört nicht zu den service-Werten, die Forgejo für Migrationen kennt. Die Aufzählung im Protokoll des Upstream-Forgejo lautet git, github, gitea, gitlab, gogs, onedev, gitbucket, codebase; git ist der Fallback für reines Git (manche ältere Dokumentation nennt ihn „plain“, aber der Wert im Protokoll ist die wörtliche Zeichenkette git). "service": "git" explizit zu setzen (wie im Body oben) ist der maßgebliche Wert; der ADO-PAT in auth_token übernimmt die Authentifizierung, und die Clone-URL ist ein normales HTTPS-Git-Remote, das der Importer für reines Git korrekt verarbeitet. Mit "lfs": true holt der Importer LFS-Objekte über den LFS-Endpunkt der Quelle; das ist für ADO-Repos mit LFS-Inhalten erforderlich. Work Items und PR-Metadaten werden anschließend separat über einen Skript-Workflow mit der ADO-REST-API importiert (siehe unten); der Importer für reines Git bringt nur Refs mit.

auth_username ist für ADO erforderlich. PATs von Azure DevOps verwenden HTTP Basic Auth, bei der das Passwort der PAT ist und der Benutzername eine beliebige nicht leere Zeichenkette sein muss (Microsoft-Dokumentation: “When using a PAT, the username can be any non-empty string”). Der Importer von Forgejo für reines Git würde sonst URLs der Form https://{auth_token}@… bilden, die der Git-Server von AzDO als Benutzernamen behandelt und mit 401 ablehnt. Verwende "auth_username": "fremforge" (oder eine andere nicht leere Zeichenkette; der Wert ist AzDO egal, nur die Form der Basic Auth zählt).

ADO-Konzepte in fremforge

Azure-DevOps-KonzeptKonzept in fremforge (Forgejo)
Organisation(keine direkte Entsprechung, meist eine fremforge-Organisation pro ADO-Organisation)
ProjectOrganisation oder Präfixmuster in den Repository-Namen
RepositoryRepository
Pull RequestPull Request
Work Item: Epic, Feature, User Story, Task, BugIssue mit Label (epic, feature, story, task, bug)
Area PathLabel oder eigener Meilenstein
Iteration PathMeilenstein
Build PipelineWorkflow in Forgejo Actions
Release PipelineWorkflow in Forgejo Actions mit Jobs für Deployment-Umgebungen
Service ConnectionKonfiguration der OIDC-Föderation
Variable GroupUmgebungs-Secrets auf Organisations- oder Umgebungsebene
Agent PoolRunner-Label / Gruppe eigener Runner
Test Plan / Test SuiteKeine Funktion von fremforge, externes Tool
Artifact FeedPaket-Registry von fremforge
WikiWiki

Work Items → Issues

Work Items werden vom eingebauten Importer von Forgejo nicht importiert. Migrationsskript:

#!/bin/bash
# Requires: curl, jq, ADO_TOKEN, FREMFORGE_TOKEN
ADO_ORG="acme"
ADO_PROJECT="project"
FREMFORGE_ORG="acme"
FREMFORGE_REPO="backend"

# Query all work items in the project
curl -s -u ":${ADO_TOKEN}" \
  "https://dev.azure.com/${ADO_ORG}/${ADO_PROJECT}/_apis/wit/wiql?api-version=7.1" \
  -H "Content-Type: application/json" \
  -d '{"query":"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject]=@project"}' \
  | jq -r '.workItems[].id' \
  | while read wi_id; do
    # Fetch full work item
    ado_wi=$(curl -s -u ":${ADO_TOKEN}" \
      "https://dev.azure.com/${ADO_ORG}/_apis/wit/workitems/${wi_id}?api-version=7.1")

    title=$(echo "${ado_wi}" | jq -r '.fields."System.Title"')
    body=$(echo "${ado_wi}" | jq -r '.fields."System.Description" // ""')
    wi_type=$(echo "${ado_wi}" | jq -r '.fields."System.WorkItemType"' | tr '[:upper:]' '[:lower:]')
    state=$(echo "${ado_wi}" | jq -r '.fields."System.State"')

    # Create fremforge issue
    curl -s -X POST "https://frem.sh/api/v1/repos/${FREMFORGE_ORG}/${FREMFORGE_REPO}/issues" \
      -H "Authorization: Bearer ${FREMFORGE_TOKEN}" \
      -H "Content-Type: application/json" \
      -d "{
        \"title\": \"${title}\",
        \"body\": \"**Migrated from Azure DevOps work item #${wi_id}**\n\n${body}\",
        \"labels\": [\"${wi_type}\"],
        \"closed\": $([[ "${state}" == "Closed" || "${state}" == "Done" || "${state}" == "Resolved" ]] && echo true || echo false)
      }"
  done

Passe es nach Bedarf an. Es ist ein Ausgangspunkt, keine fertige Lösung. Große Migrationen sollten ein Backoff bei Ratenbegrenzung ergänzen und Kommentare übernehmen.

Paginierung bei WIQL. Azure DevOps begrenzt eine einzelne WIQL-Antwort auf 20.000 Work Items. Das Skript oben stellt eine Abfrage und geht deren Ergebnismenge durch; für den üblichen Fall reicht das. Zähle vor dem Start zuerst:

COUNT=$(curl -s -u ":${ADO_TOKEN}" \
  "https://dev.azure.com/${ADO_ORG}/${ADO_PROJECT}/_apis/wit/wiql?api-version=7.1" \
  -H "Content-Type: application/json" \
  -d '{"query":"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject]=@project"}' \
  | jq '.workItems | length')
echo "Work items in scope: ${COUNT}"

Liegt COUNT über etwa 19.000, teile die Abfrage auf (zum Beispiel nach Quartal von [System.CreatedDate] oder nach [System.WorkItemType]) und führe das Skript einmal pro Teil aus, oder wende dich bei sehr großen Mengen an Work Items an support@frem.sh. Der Weg mit einer einzigen Abfrage schneidet an der Grenze stillschweigend ab: Es gibt keine Fehlerantwort, nur eine zu kurze Ergebnismenge, und genau dieses Fehlerbild willst du bei einer Migration nicht haben.

Schritt 2: Secrets und Variablen

Wo Azure DevOps Secrets speichert:

  • Pipeline-Variablen (inline im YAML): bei der Migration umschreiben.
  • Variable Groups (auf Projektebene, optional mit Azure Key Vault verknüpft): als Secrets von fremforge auf Organisations- oder Umgebungsebene neu anlegen.
  • Geheime Variablen (als geheim markiert, von der ADO-API nicht zurückgegeben): aus deinem führenden Secret-Speicher holen und neu eingeben.
  • Key-Vault-Verweise: Ist die Variable Group mit Azure Key Vault verknüpft, gibt es zwei Strategien: (a) Key Vault behalten, die Runner von fremforge per OIDC-Föderation bei Azure authentifizieren lassen und die Werte zur Laufzeit des Jobs abrufen, oder (b) die Werte direkt in Secrets von fremforge kopieren.

Dringende Empfehlung: Ersetze Secrets von Azure-Service-Principals durch OIDC-Föderation zu Azure (siehe Schritt 4).

Schritt 3: Pipelines → Forgejo Actions umstellen

YAML von Azure Pipelines und YAML von Forgejo Actions sind ähnlich aufgebaut, verwenden aber ein deutlich anderes Vokabular. Die Umstellung ist Handarbeit. Eine automatische Umstellung ist auf Phase 2 verschoben, abhängig von der Nachfrage der Kunden.

Umstellungsmuster

Stages und Jobs

YAML von Azure Pipelines:

trigger: [main]

stages:
  - stage: Build
    jobs:
      - job: BuildApp
        pool:
          vmImage: ubuntu-latest
        steps:
          - script: make build
            displayName: 'Build'

  - stage: Test
    dependsOn: Build
    jobs:
      - job: TestApp
        pool:
          vmImage: ubuntu-latest
        steps:
          - script: make test
            displayName: 'Test'

Entsprechung in Forgejo Actions:

name: CI

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: make build

  test:
    needs: build
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4
      - name: Test
        run: make test

Die wichtigsten Umstellungen:

  • trigger: → on: push: mit Branch-Filtern.
  • pr: → on: pull_request:.
  • schedules: → on: schedule: mit Cron-Ausdrücken.
  • stages / jobs / steps → jobs / steps (eine Ebene flacher; stages hat keine direkte Entsprechung, die Reihenfolge entsteht durch needs: zwischen Jobs).
  • pool: vmImage: ubuntu-latest → runs-on: fremforge (unter Runner-Images findest du das Betriebssystem des Runners, die Liste der vorinstallierten Tools und wie du Sprach-Toolchains über setup-*-Actions installierst).
  • script: → run: mit demselben Shell-Befehl.
  • task: <name>@<version> → uses: <action-path>@<version>, wobei die Action eine gleichwertige Marketplace-Action ist. Die meisten ADO-Tasks haben keine direkte Entsprechung in Forgejo Actions und werden als run:-Steps oder kleine Composite Actions neu geschrieben.

ADO-Tasks, die häufig umgestellt werden müssen

ADO-TaskErsatz in Forgejo Actions
UseNode@1actions/setup-node@v4
UsePythonVersion@0actions/setup-python@v5
UseDotNet@2actions/setup-dotnet@v4
UseJavaVersion@1actions/setup-java@v4
PublishBuildArtifacts@1actions/upload-artifact@v4
DownloadBuildArtifacts@0actions/download-artifact@v4
Cache@2actions/cache@v4
Docker@2 / DockerCompose@0docker/build-push-action@v6 oder direkt die docker-CLI in run:
AzureCLI@2azure/cli@v2 mit Zugangsdaten aus der OIDC-Föderation (siehe Schritt 4)
AzureKeyVault@2Eingebaute Secrets von fremforge (bevorzugt) oder azure/cli@v2 + az keyvault secret show
SonarCloudPrepare@1 / SonarCloudAnalyze@1sonarsource/sonarcloud-github-action@master
PublishTestResults@2dorny/test-reporter@v1 oder Artefakt-Upload auf Job-Ebene + manuelle Aufbereitung des Berichts
HelmDeploy@0helm/helm-action@v1 oder direkt die helm-CLI
KubernetesManifest@0azure/k8s-deploy@v5 (per OIDC authentifiziert)

Bedingungen

condition: in ADO → if: in Forgejo Actions.

ADO:

- task: Deploy
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Forgejo Actions:

- name: Deploy
  if: success() && github.ref == 'refs/heads/main'
  run: make deploy

Templates und Library

ADO-Templates (extends:, template:) entsprechen wiederverwendbaren Workflows in Forgejo Actions (uses: <repo>/.forgejo/workflows/template.yaml@ref) oder Composite Actions (uses: ./.forgejo/actions/<name>). Die Umstellung ist Handarbeit, aber mechanisch.

Mehrstufige Release-Pipelines → Deploy-Jobs mit Umgebungsschutz

Release-Pipelines in ADO mit Genehmigungsschritten entsprechen Workflows in Forgejo Actions, die mit environment: <name> den Ablauf mit erforderlichen Reviewern bzw. Genehmigungen auf Umgebungsebene auslösen. Konfiguriere die Schutzregeln der Umgebung in der Verwaltungsoberfläche von fremforge unter Organisationsverwaltung → Umgebungen → <name>.

Agent Pools → Runner-Labels

pool: vmImage: windows-latest in ADO → runs-on: windows-latest in Forgejo Actions. Die von fremforge gehosteten Runner sind ausschließlich Linux amd64. Windows und macOS gibt es im Standardtarif nicht.

Brauchen deine Pipelines Runner mit Windows oder macOS, gibt es zwei Wege:

  1. Eigene Runner: Registriere einen Runner mit Windows oder macOS auf deiner eigenen Infrastruktur mit dem Label windows-latest oder macos-latest. Deine Pipelines sprechen ihn über runs-on: an.
  2. Diese Pipelines in ADO belassen: für Teams, die den Großteil ihrer CI migrieren, Windows- und Mac-Builds aber auf der bestehenden Infrastruktur behalten. Nicht ideal, aber als Übergangszustand unterstützt.

Schritt 4: Service Connections → OIDC-Föderation

Azure DevOps speichert Cloud-Zugangsdaten in Service Connections. fremforge ersetzt diese durch OIDC-Föderation, den bevorzugten Weg für jedes Cloud-Ziel, nicht nur für Azure.

Für Azure

  1. Lege in Azure AD eine App Registration an und konfiguriere einen föderierten Zugang mit:
    • Issuer: https://frem.sh/_app/runner/oidc (ein einziger globaler Aussteller für alle Mandanten; unter build/runners/oidc/ findest du den JWKS-Endpunkt und den vollständigen, mit GitHub Actions kompatiblen Satz an Claims)
    • Subject: repo:<fremforge-org>/<repo>:ref:refs/heads/main (oder dein bevorzugtes Muster für den Geltungsbereich; der Subject-Claim enthält die Organisation, sodass die Trennung pro Mandant hier erzwungen wird)
    • Audience: api://AzureADTokenExchange
  2. Gib der App Registration die nötigen Rollenzuweisungen für die Ziel-Subscriptions in Azure.
  3. In deinem Workflow in Forgejo Actions:
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - uses: azure/login@v2
        with:
          client-id: ${{ vars.AZURE_CLIENT_ID }}
          tenant-id: ${{ vars.AZURE_TENANT_ID }}
          subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
      - run: az account show

Kein Client-Secret. Keine langlebigen Zugangsdaten. Das Token wird zur Laufzeit des Jobs ausgestellt, ist auf diesen Workflow beschränkt und läuft innerhalb einer Stunde ab.

Für T Cloud Public

Wie bei GitLab-Migrationen (GitLab, Schritt 4) unterstützt fremforge native OIDC-Föderation zu Agencies in T Cloud Public. Konfiguriere sie in der Verwaltungsoberfläche von fremforge unter Einstellungen → Runner-OIDC-Föderation.

Für AWS / GCP

Die üblichen Muster für OIDC zu AWS bzw. OIDC zu GCP funktionieren genauso wie aus GitHub Actions. Konfiguriere die Vertrauensbeziehung mit https://frem.sh/_app/runner/oidc als Aussteller (ein einziger globaler Aussteller für alle Mandanten; binde die Bedingung der Vertrauensrichtlinie an den Claim repository_owner, um Mandanten zu trennen, nach demselben Muster wie der Filter auf repository_owner bei token.actions.githubusercontent.com in GitHub Actions).

Schritt 5: SSH-Schlüssel neu registrieren

Siehe Schritt 4 der GitHub-Migration.

Schritt 6: Boards migrieren (teilweise)

Wie erwähnt bietet fremforge keine Hierarchie von Work-Item-Typen. Möglichkeiten für die Migration:

  1. Abflachen: Alle Work Items werden zu Issues mit Typ-Labels. Abfragen und Berichte werden rund um die Suche von fremforge neu aufgebaut.
  2. Boards getrennt behalten: Exportiere die Work Items aus ADO in eine flache Datendatei, archiviere sie und nutze ADO Boards weiter für das Backlog, während du nur Code und CI migrierst. Das ist ein häufiger Zwischenzustand für Teams, die Boards intensiv nutzen.
  3. Durch ein eigenes PM-Tool ersetzen: Linear, Jira, Shortcut, GitHub Projects (wenn du im GitHub-Ökosystem bleibst, aber ADO verlässt). Webhooks und REST-API von fremforge lassen sich mit allen genannten integrieren.

Das Importskript in Schritt 1 deckt Option 1 mit Abflachung über Labels ab.

Schritt 7: Artifact Feeds → Paket-Registry von fremforge

Artifact Feeds aus ADO entsprechen der Paket-Registry von fremforge. Bei fremforge unterstützte Formate:

  • npm
  • Maven
  • Docker/OCI-Container
  • NuGet
  • PyPI
  • RubyGems
  • Composer
  • Go-Module
  • Generic

Die Migration erfolgt durch erneutes Veröffentlichen: Jede veröffentlichende Pipeline veröffentlicht ihre Artefakte nach der Migration erneut in der Registry von fremforge. Historische Artefaktversionen bleiben in ADO verfügbar. Lege sie in deinem eigenen Tempo still.

Schritt 8: Integrationen von Drittanbietern neu verbinden

Siehe Schritt 5 der GitHub-Migration. ADO-spezifische Integrationen (Teams Service Hooks, ServiceNow, ADO-spezifische Webhooks) werden als Webhooks von fremforge neu verbunden.

Schritt 9: Prüfen und stilllegen

Wie in der Anleitung für GitHub.

Typische Stolperfallen bei ADO-Migrationen

Klassische Pipelines lassen sich nicht automatisch migrieren.

Hast du klassische (nicht YAML-basierte) Pipelines, stelle sie zuerst in ADO auf YAML um. Wende danach die Umstellungsmuster aus Schritt 3 an. Lässt du den Zwischenschritt über YAML weg, musst du die Pipelines anhand ihrer logischen Struktur in der ADO-Oberfläche neu aufbauen, und das ist fehleranfällig.

Service Connections mit Verweisen auf Azure Key Vault.

Eine Service Connection, die zur Laufzeit der Pipeline aus Azure Key Vault liest, braucht eine Migration in zwei Stufen: (1) OIDC-Föderation einrichten, damit der Runner von fremforge az login ausführen kann; (2) der Workflow holt das Secret dann zur Laufzeit des Jobs mit az keyvault secret show, statt es in den Secrets von fremforge abzulegen. Das bildet das ADO-Muster genau nach.

Release-Pipelines mit Genehmigungsschritten.

Release-Pipelines in ADO mit manuellen Genehmigungsschritten vor dem Produktions-Deployment entsprechen Forgejo Actions mit Schutzregeln über environment:. In der Verwaltungsoberfläche von fremforge legst du die erforderlichen Reviewer pro Umgebung fest. Der Funktionsumfang ist gleichwertig; nur die Bedienung unterscheidet sich.

Abhängigkeit von Test Plans.

Manuelle Testdurchführung, die in ADO Test Plans verfolgt wird, hat bei fremforge kein Ziel. Teams, die darauf angewiesen sind, müssen ein Ersatztool wählen (Xray für Jira, Zephyr, qTest) oder den geringeren Umfang in Kauf nehmen.

Hilfe bekommen

Schreib an support@frem.sh mit dem Betreff MIGRATION, AZURE DEVOPS, <your-specific-issue>.


Siehe auch: Anleitung zur GitHub-Migration · Anleitung zur GitLab-Migration · Kompatibilitätsmatrix der Top-20-Marketplace-Actions · Checkliste vor der Migration.