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)etIdentity (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 :
- Cliquez sur + → Nouvelle migration.
- Sélectionnez Azure DevOps comme source.
- Collez l’URL du dépôt (par exemple
https://dev.azure.com/acme/project/_git/backend). - Collez votre jeton d’accès personnel ADO.
- Cochez les types de contenu à importer.
- Indiquez l’organisation de destination et le nom du dépôt.
- 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 DevOps | Concept fremforge (Forgejo) |
|---|---|
| Organisation | (pas d’équivalent direct, généralement une organisation fremforge par organisation ADO) |
| Project | Organisation, ou préfixe dans les noms de dépôts |
| Repository | Dépôt |
| Pull Request | Pull request |
| Work Item : Epic, Feature, User Story, Task, Bug | Ticket avec étiquette (epic, feature, story, task, bug) |
| Area Path | Étiquette ou jalon personnalisé |
| Iteration Path | Jalon |
| Build Pipeline | Workflow Forgejo Actions |
| Release Pipeline | Workflow Forgejo Actions avec des jobs liés à des environnements de déploiement |
| Service Connection | Configuration de fédération OIDC |
| Variable Group | Secrets d’environnement au niveau de l’organisation ou de l’environnement |
| Agent Pool | Label de runner / groupe de runners auto-hébergés (BYO) |
| Test Plan / Test Suite | Pas une fonctionnalité de fremforge, outil externe |
| Artifact Feed | Registre de paquets fremforge |
| Wiki | Wiki |
É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)
}"
doneAdaptez-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 testPrincipales 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 ;stagesn’a pas d’équivalent direct, l’enchaînement s’obtient avecneeds: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 actionssetup-*).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 étapesrun:ou en petites actions composites.
Tâches ADO qui nécessitent souvent une conversion
| Tâche ADO | Remplacement Forgejo Actions |
|---|---|
UseNode@1 | actions/setup-node@v4 |
UsePythonVersion@0 | actions/setup-python@v5 |
UseDotNet@2 | actions/setup-dotnet@v4 |
UseJavaVersion@1 | actions/setup-java@v4 |
PublishBuildArtifacts@1 | actions/upload-artifact@v4 |
DownloadBuildArtifacts@0 | actions/download-artifact@v4 |
Cache@2 | actions/cache@v4 |
Docker@2 / DockerCompose@0 | docker/build-push-action@v6 ou la CLI docker directement dans run: |
AzureCLI@2 | azure/cli@v2 avec des identifiants issus de la fédération OIDC (voir l’étape 4) |
AzureKeyVault@2 | Secrets natifs fremforge (de préférence) ou azure/cli@v2 + az keyvault secret show |
SonarCloudPrepare@1 / SonarCloudAnalyze@1 | sonarsource/sonarcloud-github-action@master |
PublishTestResults@2 | dorny/test-reporter@v1 ou envoi d’artefact au niveau du job + rendu manuel du rapport |
HelmDeploy@0 | helm/helm-action@v1 ou la CLI helm directement |
KubernetesManifest@0 | azure/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 deployModè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 :
- Runners auto-hébergés (BYO) : enregistrez un runner Windows ou macOS sur votre propre infrastructure avec le label
windows-latestoumacos-latest. Vos pipelines le ciblent viaruns-on:. - 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
- 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
- Issuer :
- Accordez à l’App Registration les attributions de rôle nécessaires sur le ou les abonnements Azure cibles.
- 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 showPas 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 :
- 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.
- 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é.
- 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.