Aller au contenu principal

Migrer d’Azure DevOps vers fremforge

Ce guide couvre la migration d’Azure DevOps Services (dev.azure.com) vers fremforge. La migration équivalente depuis Azure DevOps Server (sur site) est similaire, mais les détails d’authentification et de points de terminaison de l’API diffèrent. Adaptez les parties concernant le jeton et les points de terminaison ci-dessous à votre déploiement.

Azure DevOps est, des trois grandes sources de migration, la plus différente sur le plan structurel. ADO propose des produits distincts pour Repos, Pipelines, Boards, Test Plans et Artifacts ; fremforge fournit Repos + CI/CD + Artifacts + des tickets de base dans une seule surface intégrée et ne propose pas d’équivalent pour Test Plans ni pour l’ensemble des fonctionnalités de Boards. Une migration depuis ADO est donc en partie une décision de périmètre autant qu’une migration technique : certaines fonctionnalités d’ADO sur lesquelles vous comptez peut-être n’ont pas de destination dans fremforge.

Écarts de parité fonctionnelle

fremforge n’a pas d’équivalent pour : les éléments de travail Azure Boards (ni hiérarchie de tickets, ni planification de sprints), Test Plans (pas de gestion des cas de test), la migration automatique des flux Azure Artifacts (les paquets doivent être republiés) et les pipelines Classic (les pipelines YAML se migrent, ceux créés avec le concepteur non). Si ces points sont bloquants, évaluez le périmètre de la migration avant de commencer.

Si ce n’est pas déjà fait, lisez d’abord le guide de migration depuis GitHub et le guide de migration depuis GitLab. Certaines étapes de base (clés SSH, intégrations tierces) sont identiques et nous ne les répétons pas intégralement ici.

Avant de commencer

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

  • Le rôle Project Administrator sur le ou les projets Azure DevOps que vous migrez.
  • Un jeton d’accès personnel ADO avec au minimum les portées Code (Read), Code (Status), Work Items (Read), Build (Read), Release (Read) et Identity (Read).
  • Un accès administrateur à l’organisation fremforge vers laquelle vous migrez.
  • Pour la migration des pipelines : un inventaire des fichiers de pipelines YAML, des éventuels pipelines classiques (non YAML), des connexions de service (elles deviennent une fédération OIDC), des groupes de variables et des pools d’agents dont vous dépendez.

Nos recommandations :

  • Convertissez les pipelines classiques (non YAML) en pipelines YAML dans ADO avant la migration. Passer d’un pipeline classique à Forgejo Actions revient en pratique à tout réécrire ; convertir d’abord en YAML vous donne un point de départ portable et améliore au passage votre configuration ADO.
  • Identifiez les types d’éléments de travail Boards que vous utilisez réellement. fremforge (Forgejo) a des tickets et des jalons, mais pas d’Epics, Features, User Stories ou Tasks en tant que types distincts. Tous deviennent des tickets avec des étiquettes. Si votre processus repose sur la hiérarchie des types d’éléments de travail, planifiez cette fusion avant la migration.
  • Identifiez les dépendances à Test Plans. fremforge n’a pas d’équivalent direct ; les équipes qui s’appuient beaucoup sur ADO Test Plans le conservent généralement comme outil séparé ou passent à un outil dédié de gestion des tests.

Estimation de durée :

  • Un seul dépôt avec un pipeline simple et une utilisation limitée de Boards : 1 à 2 heures.
  • Un dépôt avec un pipeline de complexité modérée et des pipelines de release à plusieurs étapes : 3 à 6 heures.
  • Migration de toute une organisation avec de nombreux pipelines, groupes de variables et connexions de service : 1 à 2 semaines d’ingénierie, principalement consacrées à la conversion des pipelines et au remplacement des connexions de service.

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

L’importateur natif de Forgejo prend Azure DevOps en charge comme source. Il copie l’historique Git et, selon votre configuration ADO, les éléments de travail (importés comme tickets) et les pull requests.

Avec l’importateur natif (via l’interface)

Depuis l’interface d’administration fremforge :

  1. Cliquez sur + → Nouvelle migration.
  2. Sélectionnez Azure DevOps comme source.
  3. Collez l’URL du dépôt (par exemple https://dev.azure.com/acme/project/_git/backend).
  4. Collez votre jeton d’accès personnel ADO.
  5. Cochez les types de contenu à importer.
  6. Indiquez l’organisation de destination et le nom du dépôt.
  7. Cliquez sur Migrate repository.

Avec l’API (pour les scripts)

# 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 @-

Remarque : ADO ne fait pas partie des valeurs service de migration reconnues par Forgejo. L’énumération transmise par Forgejo en amont est git, github, gitea, gitlab, gogs, onedev, gitbucket, codebase ; git est le repli Git simple (une ancienne documentation l’appelle « plain », mais la valeur transmise est la chaîne littérale git). Indiquer explicitement "service": "git" (comme dans le corps ci-dessus) est la valeur canonique ; le PAT ADO dans auth_token porte l’authentification, et l’URL de clonage est un remote Git HTTPS standard que l’importateur Git simple gère correctement. "lfs": true demande à l’importateur de récupérer les objets LFS via le point de terminaison LFS de la source ; c’est indispensable pour les dépôts ADO qui contiennent du LFS. Les éléments de travail et les métadonnées des PR s’importent ensuite séparément, par un script utilisant l’API REST d’ADO (voir ci-dessous) ; l’importateur Git simple ne rapporte que les refs.

auth_username est obligatoire pour ADO. Les PAT Azure DevOps utilisent l’authentification HTTP Basic, où le mot de passe est le PAT et où le nom d’utilisateur doit être une chaîne non vide quelconque (documentation Microsoft : « When using a PAT, the username can be any non-empty string »). Sinon, l’importateur Git simple de Forgejo construit des URL de la forme https://{auth_token}@…, que le serveur Git d’AzDO interprète comme le nom d’utilisateur et rejette avec une erreur 401. Utilisez "auth_username": "fremforge" (ou n’importe quelle chaîne non vide : la valeur importe peu à AzDO, seule compte la forme de l’authentification Basic).

Correspondance des concepts ADO avec fremforge

Concept Azure DevOpsConcept fremforge (Forgejo)
Organisation(pas d’équivalent direct, généralement une organisation fremforge par organisation ADO)
ProjectOrganisation, ou préfixe dans les noms de dépôts
RepositoryDépôt
Pull RequestPull request
Work Item : Epic, Feature, User Story, Task, BugTicket avec étiquette (epic, feature, story, task, bug)
Area PathÉtiquette ou jalon personnalisé
Iteration PathJalon
Build PipelineWorkflow Forgejo Actions
Release PipelineWorkflow Forgejo Actions avec des jobs liés à des environnements de déploiement
Service ConnectionConfiguration de fédération OIDC
Variable GroupSecrets d’environnement au niveau de l’organisation ou de l’environnement
Agent PoolLabel de runner / groupe de runners auto-hébergés (BYO)
Test Plan / Test SuitePas une fonctionnalité de fremforge, outil externe
Artifact FeedRegistre de paquets fremforge
WikiWiki

Éléments de travail → tickets

Les éléments de travail ne sont pas importés par l’importateur natif de Forgejo. Script de migration :

#!/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

Adaptez-le à vos besoins. C’est un point de départ, pas une solution prête à l’emploi. Les migrations volumineuses doivent ajouter une temporisation en cas de limitation de débit et la conservation des commentaires.

Pagination WIQL. Azure DevOps plafonne une réponse WIQL à 20 000 éléments de travail. Le script ci-dessus envoie une seule requête et parcourt le résultat, ce qui suffit dans le cas courant. Avant de le lancer, comptez d’abord :

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}"

Si COUNT dépasse environ 19 000, partitionnez la requête (par exemple par trimestre de [System.CreatedDate] ou par [System.WorkItemType]) et lancez le script une fois par partition, ou contactez support@frem.sh pour les très gros volumes d’éléments de travail. La requête unique est tronquée silencieusement au plafond : il n’y a pas de réponse d’erreur, seulement un résultat incomplet, ce qui est précisément le mode d’échec que vous ne voulez pas pendant une migration.

Étape 2 : secrets et variables

Les emplacements de secrets d’Azure DevOps :

  • Variables de pipeline (en ligne dans le YAML) : à réécrire lors de la migration.
  • Groupes de variables (au niveau du projet, éventuellement liés à Azure Key Vault) : à recréer comme secrets fremforge au niveau de l’organisation ou de l’environnement.
  • Variables secrètes (marquées comme secrètes, non renvoyées par l’API ADO) : à récupérer dans votre référentiel de secrets et à ressaisir.
  • Références Key Vault : si le groupe de variables est lié à Azure Key Vault, la stratégie de migration consiste soit (a) à conserver Key Vault, les runners fremforge s’authentifiant auprès d’Azure par fédération OIDC et récupérant les valeurs au moment du job, soit (b) à copier directement les valeurs dans des secrets fremforge.

Recommandation forte : remplacez les secrets de principal de service Azure par une fédération OIDC vers Azure (voir l’étape 4).

Étape 3 : conversion des pipelines vers Forgejo Actions

Le YAML d’Azure Pipelines et celui de Forgejo Actions ont une forme semblable mais un vocabulaire sensiblement différent. La conversion est manuelle. La conversion automatique est reportée à la phase 2, en fonction de la demande des clients.

Modèles de conversion

Stages et jobs

YAML 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'

Équivalent 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

Principales conversions :

  • trigger: → on: push: avec des filtres de branches.
  • pr: → on: pull_request:.
  • schedules: → on: schedule: avec des expressions cron.
  • stages / jobs / steps → jobs / steps (un niveau de moins ; stages n’a pas d’équivalent direct, l’enchaînement s’obtient avec needs: entre les jobs).
  • pool: vmImage: ubuntu-latest → runs-on: fremforge (voir Images de runner pour le système du runner, la liste des outils préinstallés et l’installation des chaînes d’outils de langage via les actions setup-*).
  • script: → run: avec la même commande shell.
  • task: <name>@<version> → uses: <action-path>@<version>, où l’action est une action équivalente de la Marketplace. La plupart des tâches ADO n’ont pas d’équivalent direct dans Forgejo Actions et se réécrivent en étapes run: ou en petites actions composites.

Tâches ADO qui nécessitent souvent une conversion

Tâche ADORemplacement 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 ou la CLI docker directement dans run:
AzureCLI@2azure/cli@v2 avec des identifiants issus de la fédération OIDC (voir l’étape 4)
AzureKeyVault@2Secrets natifs fremforge (de préférence) ou azure/cli@v2 + az keyvault secret show
SonarCloudPrepare@1 / SonarCloudAnalyze@1sonarsource/sonarcloud-github-action@master
PublishTestResults@2dorny/test-reporter@v1 ou envoi d’artefact au niveau du job + rendu manuel du rapport
HelmDeploy@0helm/helm-action@v1 ou la CLI helm directement
KubernetesManifest@0azure/k8s-deploy@v5 (authentifié par OIDC)

Conditions

condition: d’ADO → if: de 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

Modèles et Library

Les modèles ADO (extends:, template:) correspondent aux workflows réutilisables de Forgejo Actions (uses: <repo>/.forgejo/workflows/template.yaml@ref) ou aux actions composites (uses: ./.forgejo/actions/<name>). La conversion est manuelle mais mécanique.

Pipelines de release à plusieurs étapes → jobs de déploiement conditionnés par un environnement

Les pipelines de release ADO avec des points d’approbation correspondent à des workflows Forgejo Actions qui utilisent environment: <name> pour déclencher le processus de relecteurs obligatoires / d’approbation au niveau de l’environnement. Configurez les règles de protection d’environnement dans l’interface d’administration fremforge sous Administration de l’organisation → Environnements → <name>.

Pools d’agents → labels de runner

pool: vmImage: windows-latest d’ADO → runs-on: windows-latest de Forgejo Actions. Les runners hébergés fournis par fremforge sont uniquement Linux amd64. Windows et macOS ne sont pas disponibles dans l’offre standard.

Si vos pipelines exigent des runners Windows ou macOS, deux voies s’offrent à vous :

  1. Runners auto-hébergés (BYO) : enregistrez un runner Windows ou macOS sur votre propre infrastructure avec le label windows-latest ou macos-latest. Vos pipelines le ciblent via runs-on:.
  2. Conserver ces pipelines sur ADO : pour les équipes qui migrent l’essentiel de leur CI mais gardent les builds Windows/Mac sur l’infrastructure existante. Ce n’est pas idéal, mais c’est pris en charge comme état transitoire.

Étape 4 : connexions de service → fédération OIDC

Azure DevOps utilise les connexions de service pour stocker les identifiants cloud. fremforge les remplace par la fédération OIDC, l’approche recommandée pour toutes les cibles cloud, pas seulement Azure.

Pour Azure

  1. Dans Azure AD, créez un App Registration et configurez un identifiant fédéré avec :
    • Issuer : https://frem.sh/_app/runner/oidc (un seul émetteur global pour tous les tenants ; voir build/runners/oidc/ pour le point de terminaison JWKS et l’ensemble complet des revendications compatibles avec GitHub Actions)
    • Subject : repo:<fremforge-org>/<repo>:ref:refs/heads/main (ou le modèle de portée de votre choix ; la revendication subject contient l’organisation, c’est donc ici que l’isolation par tenant est assurée)
    • Audience : api://AzureADTokenExchange
  2. Accordez à l’App Registration les attributions de rôle nécessaires sur le ou les abonnements Azure cibles.
  3. Dans votre workflow 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

Pas de secret client. Pas d’identifiant de longue durée. Le jeton est émis au moment du job, limité à ce workflow, et expire dans l’heure.

Pour T Cloud Public

Comme pour les migrations depuis GitLab (étape 4 de GitLab), fremforge prend en charge nativement la fédération OIDC vers les agences T Cloud Public. Configurez-la dans l’interface d’administration fremforge sous Paramètres → Fédération OIDC des runners.

Pour AWS / GCP

Les modèles standard OIDC vers AWS / OIDC vers GCP fonctionnent comme depuis GitHub Actions. Configurez la relation de confiance avec https://frem.sh/_app/runner/oidc comme émetteur (un seul émetteur global pour tous les tenants ; fixez la condition de la politique de confiance sur la revendication repository_owner pour l’isolation par tenant, sur le même modèle que le filtre repository_owner de GitHub Actions sur token.actions.githubusercontent.com).

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

Voir l’étape 4 de la migration depuis GitHub.

Étape 6 : migration de Boards (partielle)

Comme indiqué plus haut, fremforge ne propose pas de hiérarchie de types d’éléments de travail. Options de migration :

  1. Aplatir : tous les éléments de travail deviennent des tickets avec des étiquettes de type. Les requêtes et rapports se reconstruisent autour de la recherche de fremforge.
  2. Garder Boards à part : exportez les éléments de travail ADO dans un fichier de données à plat, archivez-le et continuez à utiliser ADO Boards pour la gestion du backlog en ne migrant que le code et la CI. C’est un état intermédiaire courant pour les équipes dont l’usage de Boards est poussé.
  3. Remplacer par un outil de gestion de projet dédié : Linear, Jira, Shortcut, GitHub Projects (si vous restez dans l’écosystème GitHub tout en quittant ADO). Les webhooks et l’API REST de fremforge s’intègrent avec tous ces outils.

Le script d’import de l’étape 1 couvre l’option 1 avec un aplatissement par étiquettes.

Étape 7 : flux Artifacts → registre de paquets fremforge

Les flux Artifacts d’ADO correspondent au registre de paquets fremforge. Formats pris en charge sur fremforge :

  • npm
  • Maven
  • Conteneurs Docker/OCI
  • NuGet
  • PyPI
  • RubyGems
  • Composer
  • Modules Go
  • Générique

La migration repose sur la publication : chaque pipeline de publication republie ses artefacts dans le registre fremforge après la migration. Les versions historiques des artefacts restent disponibles sur ADO. Mettez-les hors service à votre rythme.

Étape 8 : reconnexion des intégrations tierces

Voir l’étape 5 de la migration depuis GitHub. Les intégrations propres à ADO (Service Hooks Teams, ServiceNow, webhooks spécifiques à ADO) se reconnectent sous forme de webhooks fremforge.

Étape 9 : vérifier et mettre hors service

Comme dans le guide GitHub.

Pièges courants propres aux migrations depuis ADO

Les pipelines classiques ne peuvent pas être migrés automatiquement.

Si vous avez des pipelines classiques (non YAML), convertissez-les d’abord en YAML dans ADO. Appliquez ensuite les modèles de conversion de l’étape 3. Sauter l’étape intermédiaire YAML oblige à recréer les pipelines à partir de leur forme logique dans l’interface ADO, ce qui est source d’erreurs.

Connexions de service avec des références Azure Key Vault.

Une connexion de service qui lit Azure Key Vault au moment de l’exécution du pipeline nécessite une migration en deux temps : (1) mettre en place la fédération OIDC pour que le runner fremforge puisse exécuter az login ; (2) le workflow récupère ensuite le secret avec az keyvault secret show au moment du job, au lieu de l’intégrer dans les secrets fremforge. Cela reproduit exactement le fonctionnement d’ADO.

Pipelines de release avec points d’approbation.

Les pipelines de release ADO avec approbation manuelle avant le déploiement en production correspondent à Forgejo Actions avec des règles de protection environment:. L’interface d’administration fremforge permet de configurer des relecteurs obligatoires par environnement. Les fonctionnalités sont équivalentes ; seule l’ergonomie diffère.

Dépendance à Test Plans.

L’exécution de tests manuels suivie dans ADO Test Plans n’a pas de destination dans fremforge. Les équipes qui en dépendent doivent choisir un outil de remplacement (Xray sur Jira, Zephyr, qTest) ou accepter la réduction de périmètre.

Obtenir de l’aide

Écrivez à support@frem.sh avec l’objet MIGRATION, AZURE DEVOPS, <your-specific-issue>.


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