[{"data":1,"prerenderedAt":2844},["ShallowReactive",2],{"/blog/migration-from-azure-devops-to-gitlab":3,"navigation-en-us":2047,"banner-en-us":2473,"footer-en-us":2484,"blog-post-authors-en-us-Evgeny Rudinsky|Michael Leopard":2729,"blog-related-posts-en-us-migration-from-azure-devops-to-gitlab":2755,"blog-promotions-en-us":2781,"next-steps-en-us":2834},{"id":4,"title":5,"authors":6,"body":9,"category":2025,"date":2026,"description":2027,"extension":2028,"externalUrl":2029,"faq":2029,"featured":260,"heroImage":2030,"meta":2031,"navigation":260,"path":2032,"seo":2033,"slug":2038,"stem":2039,"tags":2040,"template":2044,"updatedDate":2045,"__hash__":2046},"blogPosts/en-us/blog/migration-from-azure-devops-to-gitlab.md","Guide: Migrate from Azure DevOps to GitLab",[7,8],"Evgeny Rudinsky","Michael Leopard",{"type":10,"value":11,"toc":2019},"minimark",[12,16,46,49,52,55,60,87,90,101,104,316,320,326,343,346,351,365,374,377,392,400,405,439,442,446,449,460,478,482,485,612,615,640,645,648,668,671,678,681,689,694,707,733,742,745,1253,1537,1542,1562,1566,1569,1572,1583,1586,1597,1599,1607,1610,1616,1624,1629,1637,1642,1650,1655,1669,1680,1685,1690,1698,1703,1715,1719,2015],[13,14,15],"p",{},"Enterprise teams are increasingly migrating from Azure DevOps to GitLab to gain strategic advantages and accelerate secure software delivery.",[17,18,19,30,38],"ul",{},[20,21,22,23,29],"li",{},"GitLab comes with integrated controls, policies, and ",[24,25,28],"a",{"href":26,"rel":27},"https://docs.gitlab.com/user/compliance/compliance_frameworks/",[],"compliance frameworks"," that allow organizations to implement software delivery standards at scale. This is especially important for regulated industries.",[20,31,32,37],{},[24,33,36],{"href":34,"rel":35},"https://docs.gitlab.com/user/application_security/",[],"Security testing"," is embedded in the pipeline and results show in the developer workflow, including static application security testing (SAST), source code analysis (SCA), dynamic application security testing (DAST), infrastructure-as-code scanning (IaC), container scanning, and API scanning.",[20,39,40,45],{},[24,41,44],{"href":42,"rel":43},"https://about.gitlab.com/gitlab-duo-agent-platform/",[],"AI capabilities"," across the full software delivery lifecycle include advanced agent orchestration and customizable flows to support how your organizational teams work.",[13,47,48],{},"GitLab's open-source, open-core approach, flexible deployment options such as single-tenant dedicated and self-managed, and truly unified platform eliminate integration complexity and security gaps.",[13,50,51],{},"For teams facing mounting pressure to accelerate delivery while strengthening security posture and maintaining regulatory compliance, GitLab represents not just a migration but a platform evolution.",[13,53,54],{},"Migrating from Azure DevOps to GitLab can seem like a daunting task, but with the right approach and tools, it can be a smooth and efficient process. This guide will walk you through the steps needed to successfully migrate your projects, repositories, and pipelines from Azure DevOps to GitLab.",[56,57,59],"h2",{"id":58},"overview","Overview",[13,61,62,63,68,69,74,75,80,81,86],{},"GitLab provides both ",[24,64,67],{"href":65,"rel":66},"https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/",[],"Congregate"," (maintained by ",[24,70,73],{"href":71,"rel":72},"https://about.gitlab.com/professional-services/",[],"GitLab Professional Services"," organization) and ",[24,76,79],{"href":77,"rel":78},"https://docs.gitlab.com/user/project/import/repo_by_url/",[],"a built-in Git repository import"," for migrating projects from Azure DevOps (ADO). These options support repository-by-repository or bulk migration and preserve git commit history, branches, and tags. With Congregate and professional services tools, we support additional assets such as wikis, work items, CI/CD variables, container images, packages, pipelines, and more (see this ",[24,82,85],{"href":83,"rel":84},"https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/blob/master/customer/ado-migration-features-matrix.md",[],"feature matrix","). Use this guide to plan and execute your migration and complete post-migration follow-up tasks.",[13,88,89],{},"Enterprises migrating from ADO to GitLab commonly follow a multi-phase approach:",[17,91,92,95,98],{},[20,93,94],{},"Migrate repositories from ADO to GitLab using Congregate or GitLab's built-in repository migration.",[20,96,97],{},"Migrate pipelines from Azure Pipelines to GitLab CI/CD.",[20,99,100],{},"Migrate remaining assets such as boards, work items, and artifacts to GitLab Issues, Epics, and the Package and Container Registries.",[13,102,103],{},"High-level migration phases:",[105,106,111],"pre",{"className":107,"code":108,"language":109,"meta":110,"style":110},"language-mermaid shiki shiki-themes github-light","graph LR\n    subgraph Prerequisites\n        direction TB\n        A[\"Set up identity provider (IdP) and\u003Cbr/>provision users\"]\n        A --> B[\"Set up runners and\u003Cbr/>third-party integrations\"]\n        B --> I[\"Users enablement and\u003Cbr/>change management\"]\n    end\n    \n    subgraph MigrationPhase[\"Migration phase\"]\n        direction TB\n        C[\"Migrate source code\"]\n        C --> D[\"Preserve contributions and\u003Cbr/> format history\"]\n        D --> E[\"Migrate work items and\u003Cbr/>map to \u003Ca href=\"https://docs.gitlab.com/topics/plan_and_track/\">GitLab Plan \u003Cbr/>and track work\"]\n    end\n    \n    subgraph PostMigration[\"Post-migration steps\"]\n        direction TB\n        F[\"Create or translate \u003Cbr/>ADO pipelines to GitLab CI\"]\n        F --> G[\"Migrate other assets\u003Cbr/>packages and container images\"]\n        G --> H[\"Introduce \u003Ca href=\"https://docs.gitlab.com/user/application_security/secure_your_application/\">security\u003C/a> and\u003Cbr/>SDLC improvements\"]\n    end\n    \n    Prerequisites --> MigrationPhase\n    MigrationPhase --> PostMigration\n\n    style A fill:#FC6D26\n    style B fill:#FC6D26\n    style I fill:#FC6D26\n    style C fill:#8C929D\n    style D fill:#8C929D\n    style E fill:#8C929D\n    style F fill:#FFA500\n    style G fill:#FFA500\n    style H fill:#FFA500\n","mermaid","",[112,113,114,123,129,135,141,147,153,159,165,171,176,182,188,194,199,204,210,215,221,227,233,238,243,249,255,262,268,274,280,286,292,298,304,310],"code",{"__ignoreMap":110},[115,116,119],"span",{"class":117,"line":118},"line",1,[115,120,122],{"class":121},"sgsFI","graph LR\n",[115,124,126],{"class":117,"line":125},2,[115,127,128],{"class":121},"    subgraph Prerequisites\n",[115,130,132],{"class":117,"line":131},3,[115,133,134],{"class":121},"        direction TB\n",[115,136,138],{"class":117,"line":137},4,[115,139,140],{"class":121},"        A[\"Set up identity provider (IdP) and\u003Cbr/>provision users\"]\n",[115,142,144],{"class":117,"line":143},5,[115,145,146],{"class":121},"        A --> B[\"Set up runners and\u003Cbr/>third-party integrations\"]\n",[115,148,150],{"class":117,"line":149},6,[115,151,152],{"class":121},"        B --> I[\"Users enablement and\u003Cbr/>change management\"]\n",[115,154,156],{"class":117,"line":155},7,[115,157,158],{"class":121},"    end\n",[115,160,162],{"class":117,"line":161},8,[115,163,164],{"class":121},"    \n",[115,166,168],{"class":117,"line":167},9,[115,169,170],{"class":121},"    subgraph MigrationPhase[\"Migration phase\"]\n",[115,172,174],{"class":117,"line":173},10,[115,175,134],{"class":121},[115,177,179],{"class":117,"line":178},11,[115,180,181],{"class":121},"        C[\"Migrate source code\"]\n",[115,183,185],{"class":117,"line":184},12,[115,186,187],{"class":121},"        C --> D[\"Preserve contributions and\u003Cbr/> format history\"]\n",[115,189,191],{"class":117,"line":190},13,[115,192,193],{"class":121},"        D --> E[\"Migrate work items and\u003Cbr/>map to \u003Ca href=\"https://docs.gitlab.com/topics/plan_and_track/\">GitLab Plan \u003Cbr/>and track work\"]\n",[115,195,197],{"class":117,"line":196},14,[115,198,158],{"class":121},[115,200,202],{"class":117,"line":201},15,[115,203,164],{"class":121},[115,205,207],{"class":117,"line":206},16,[115,208,209],{"class":121},"    subgraph PostMigration[\"Post-migration steps\"]\n",[115,211,213],{"class":117,"line":212},17,[115,214,134],{"class":121},[115,216,218],{"class":117,"line":217},18,[115,219,220],{"class":121},"        F[\"Create or translate \u003Cbr/>ADO pipelines to GitLab CI\"]\n",[115,222,224],{"class":117,"line":223},19,[115,225,226],{"class":121},"        F --> G[\"Migrate other assets\u003Cbr/>packages and container images\"]\n",[115,228,230],{"class":117,"line":229},20,[115,231,232],{"class":121},"        G --> H[\"Introduce \u003Ca href=\"https://docs.gitlab.com/user/application_security/secure_your_application/\">security\u003C/a> and\u003Cbr/>SDLC improvements\"]\n",[115,234,236],{"class":117,"line":235},21,[115,237,158],{"class":121},[115,239,241],{"class":117,"line":240},22,[115,242,164],{"class":121},[115,244,246],{"class":117,"line":245},23,[115,247,248],{"class":121},"    Prerequisites --> MigrationPhase\n",[115,250,252],{"class":117,"line":251},24,[115,253,254],{"class":121},"    MigrationPhase --> PostMigration\n",[115,256,258],{"class":117,"line":257},25,[115,259,261],{"emptyLinePlaceholder":260},true,"\n",[115,263,265],{"class":117,"line":264},26,[115,266,267],{"class":121},"    style A fill:#FC6D26\n",[115,269,271],{"class":117,"line":270},27,[115,272,273],{"class":121},"    style B fill:#FC6D26\n",[115,275,277],{"class":117,"line":276},28,[115,278,279],{"class":121},"    style I fill:#FC6D26\n",[115,281,283],{"class":117,"line":282},29,[115,284,285],{"class":121},"    style C fill:#8C929D\n",[115,287,289],{"class":117,"line":288},30,[115,290,291],{"class":121},"    style D fill:#8C929D\n",[115,293,295],{"class":117,"line":294},31,[115,296,297],{"class":121},"    style E fill:#8C929D\n",[115,299,301],{"class":117,"line":300},32,[115,302,303],{"class":121},"    style F fill:#FFA500\n",[115,305,307],{"class":117,"line":306},33,[115,308,309],{"class":121},"    style G fill:#FFA500\n",[115,311,313],{"class":117,"line":312},34,[115,314,315],{"class":121},"    style H fill:#FFA500\n",[56,317,319],{"id":318},"planning-your-migration","Planning your migration",[13,321,322],{},[323,324,325],"strong",{},"To plan your migration, ask these questions:",[17,327,328,331,334,337,340],{},[20,329,330],{},"How soon do we need to complete the migration?",[20,332,333],{},"Do we understand what will be migrated?",[20,335,336],{},"Who will run the migration?",[20,338,339],{},"What organizational structure do we want in GitLab?",[20,341,342],{},"Are there any constraints, limitations, or pitfalls that need to be taken into account?",[13,344,345],{},"Determine your timeline, as it will largely dictate your migration approach. Identify champions or groups familiar with both ADO and GitLab platforms (such as early adopters) to help drive adoption and provide guidance.",[13,347,348],{},[323,349,350],{},"Inventory what you need to migrate:",[17,352,353,356,359,362],{},[20,354,355],{},"The number of repositories, pull requests, and contributors",[20,357,358],{},"The number and complexity of work items and pipelines",[20,360,361],{},"Repository sizes and dependency relationships",[20,363,364],{},"Critical integrations and runner requirements (agent pools with specific capabilities)",[13,366,367,368,373],{},"Use GitLab Professional Services's ",[24,369,372],{"href":370,"rel":371},"https://gitlab.com/gitlab-org/professional-services-automation/tools/utilities/evaluate#beta-azure-devops",[],"Evaluate"," tool to produce a complete inventory of your entire Azure DevOps organization, including repositories, PR counts, contributor lists, number of pipelines, work items, CI/CD variables and more. If you're working with the GitLab Professional Services team, share this report with your engagement manager or technical architect to help plan the migration.",[13,375,376],{},"Migration timing is primarily driven by pull request count, repository size, and amount of contributions (e.g. comments in PR, work items, etc). For example, 1,000 small repositories with few PRs and limited contributors can migrate much faster than a smaller set of repositories containing tens of thousands of PRs and thousands of contributors. Use your inventory data to estimate effort and plan test runs before proceeding with production migrations.",[13,378,379,380,385,386,391],{},"Compare inventory against your desired timeline and decide whether to migrate all repositories at once or in batches. If teams cannot migrate simultaneously, batch and stagger migrations to align with team schedules. For example, in Professional Services engagements, we organize migrations into waves of 200-300 projects to manage complexity and respect API rate limits, both in ",[24,381,384],{"href":382,"rel":383},"https://docs.gitlab.com/security/rate_limits/",[],"GitLab"," and ",[24,387,390],{"href":388,"rel":389},"https://learn.microsoft.com/en-us/azure/devops/integrate/concepts/rate-limits?view=azure-devops",[],"ADO",".",[13,393,394,395,399],{},"GitLab's built-in ",[24,396,398],{"href":77,"rel":397},[],"repository importer"," migrates Git repositories (commits, branches, and tags) one-by-one. Congregate is designed to preserve pull requests (known in GitLab as merge requests), comments, and related metadata where possible; the simple built-in repository import focuses only on the Git data (history, branches, and tags).",[13,401,402],{},[323,403,404],{},"Items that typically require separate migration or manual recreation:",[17,406,407,422,425,428,431],{},[20,408,409,410,415,416,421],{},"Azure Pipelines - create equivalent GitLab CI/CD pipelines (consult with ",[24,411,414],{"href":412,"rel":413},"https://docs.gitlab.com/ci/yaml/",[],"CI/CD YAML"," and/or with ",[24,417,420],{"href":418,"rel":419},"https://docs.gitlab.com/ci/components/",[],"CI/CD components","). Alternatively, consider using AI-based pipeline conversion available in Congregate.",[20,423,424],{},"Work items and boards - map to GitLab Issues, Epics, and Issue Boards.",[20,426,427],{},"Artifacts, container images (ACR) - migrate to GitLab Package Registry or Container Registry.",[20,429,430],{},"Service hooks and external integrations - recreate in GitLab.",[20,432,433,438],{},[24,434,437],{"href":435,"rel":436},"https://docs.gitlab.com/user/permissions/",[],"Permissions models"," differ between ADO and GitLab; review and plan permissions mapping rather than assuming exact preservation.",[13,440,441],{},"Review what each tool (Congregate vs. built-in import) will migrate and choose the one that fits your needs. Make a list of any data or integrations that must be migrated or recreated manually.",[13,443,444],{},[323,445,336],{},[13,447,448],{},"Migrations are typically run by a GitLab group owner or instance administrator, or by a designated migrator who has been granted the necessary permissions on the destination group/project. Congregate and the GitLab import APIs require valid authentication tokens for both Azure DevOps and GitLab.",[17,450,451,454,457],{},[20,452,453],{},"Decide whether a group owner/admin will perform the migrations or whether you will grant a specific team/person delegated access.",[20,455,456],{},"Ensure the migrator has correctly configured personal access tokens (Azure DevOps and GitLab) with the scopes required by your chosen migration tool (for example, api/read_repository scopes and any tool-specific requirements).",[20,458,459],{},"Test tokens and permissions with a small pilot migration.",[13,461,462,465,466,471,472,477],{},[323,463,464],{},"Note:"," Congregate leverages file-based import functionality for ADO migrations and requires instance administrator permissions to run (",[24,467,470],{"href":468,"rel":469},"https://docs.gitlab.com/user/project/settings/import_export/#migrate-projects-by-uploading-an-export-file",[],"see our documentation","). If you are migrating to GitLab.com, consider engaging Professional Services. For more information, see the ",[24,473,476],{"href":474,"rel":475},"https://about.gitlab.com/professional-services/catalog/",[],"Professional Services Full Catalog",". Non-admin account cannot preserve contribution attribution!",[13,479,480],{},[323,481,339],{},[13,483,484],{},"While it's possible to map ADO structure directly to GitLab structure, it's recommended to rationalize and simplify the structure during migration. Consider how teams will work in GitLab and design the structure to facilitate collaboration and access management. Here is a way to think about mapping ADO structure to GitLab structure:",[105,486,488],{"className":107,"code":487,"language":109,"meta":110,"style":110},"graph TD\n    subgraph GitLab\n        direction TB\n        A[\"Top-level Group\"]\n        B[\"Subgroup (optional)\"]\n        C[\"Projects\"]\n        A --> B\n        A --> C\n        B --> C\n    end\n\n    subgraph AzureDevOps[\"Azure DevOps\"]\n        direction TB\n        F[\"Organizations\"]\n        G[\"Projects\"]\n        H[\"Repositories\"]\n        F --> G\n        G --> H\n    end\n\n    style A fill:#FC6D26\n    style B fill:#FC6D26\n    style C fill:#FC6D26\n    style F fill:#8C929D\n    style G fill:#8C929D\n    style H fill:#8C929D\n",[112,489,490,495,500,504,509,514,519,524,529,534,538,542,547,551,556,561,566,571,576,580,584,588,592,597,602,607],{"__ignoreMap":110},[115,491,492],{"class":117,"line":118},[115,493,494],{"class":121},"graph TD\n",[115,496,497],{"class":117,"line":125},[115,498,499],{"class":121},"    subgraph GitLab\n",[115,501,502],{"class":117,"line":131},[115,503,134],{"class":121},[115,505,506],{"class":117,"line":137},[115,507,508],{"class":121},"        A[\"Top-level Group\"]\n",[115,510,511],{"class":117,"line":143},[115,512,513],{"class":121},"        B[\"Subgroup (optional)\"]\n",[115,515,516],{"class":117,"line":149},[115,517,518],{"class":121},"        C[\"Projects\"]\n",[115,520,521],{"class":117,"line":155},[115,522,523],{"class":121},"        A --> B\n",[115,525,526],{"class":117,"line":161},[115,527,528],{"class":121},"        A --> C\n",[115,530,531],{"class":117,"line":167},[115,532,533],{"class":121},"        B --> C\n",[115,535,536],{"class":117,"line":173},[115,537,158],{"class":121},[115,539,540],{"class":117,"line":178},[115,541,261],{"emptyLinePlaceholder":260},[115,543,544],{"class":117,"line":184},[115,545,546],{"class":121},"    subgraph AzureDevOps[\"Azure DevOps\"]\n",[115,548,549],{"class":117,"line":190},[115,550,134],{"class":121},[115,552,553],{"class":117,"line":196},[115,554,555],{"class":121},"        F[\"Organizations\"]\n",[115,557,558],{"class":117,"line":201},[115,559,560],{"class":121},"        G[\"Projects\"]\n",[115,562,563],{"class":117,"line":206},[115,564,565],{"class":121},"        H[\"Repositories\"]\n",[115,567,568],{"class":117,"line":212},[115,569,570],{"class":121},"        F --> G\n",[115,572,573],{"class":117,"line":217},[115,574,575],{"class":121},"        G --> H\n",[115,577,578],{"class":117,"line":223},[115,579,158],{"class":121},[115,581,582],{"class":117,"line":229},[115,583,261],{"emptyLinePlaceholder":260},[115,585,586],{"class":117,"line":235},[115,587,267],{"class":121},[115,589,590],{"class":117,"line":240},[115,591,273],{"class":121},[115,593,594],{"class":117,"line":245},[115,595,596],{"class":121},"    style C fill:#FC6D26\n",[115,598,599],{"class":117,"line":251},[115,600,601],{"class":121},"    style F fill:#8C929D\n",[115,603,604],{"class":117,"line":257},[115,605,606],{"class":121},"    style G fill:#8C929D\n",[115,608,609],{"class":117,"line":264},[115,610,611],{"class":121},"    style H fill:#8C929D\n",[13,613,614],{},"Recommended approach:",[17,616,617,620,623,626],{},[20,618,619],{},"Map each ADO organization to a GitLab group (or a small set of groups), not to many small groups. Avoid creating a GitLab group for every ADO team project. Use migration as an opportunity to rationalize your GitLab structure.",[20,621,622],{},"Use subgroups and project-level permissions to group related repositories.",[20,624,625],{},"Manage access to sets of projects by using GitLab groups and group membership (groups and subgroups) rather than one group per team project.",[20,627,628,629,633,634,639],{},"Review GitLab ",[24,630,632],{"href":435,"rel":631},[],"permissions"," and consider ",[24,635,638],{"href":636,"rel":637},"https://docs.gitlab.com/user/group/saml_sso/group_sync/",[],"SAML Group Links"," to implement an enterprise RBAC model for your GitLab instance (or a GitLab.com namespace).",[13,641,642],{},[323,643,644],{},"ADO Boards and work items: State of migration",[13,646,647],{},"It's important to understand how work items migrate from ADO into GitLab Plan (issues, epics, and boards).",[17,649,650,653,656,659,662,665],{},[20,651,652],{},"ADO Boards and work items map to GitLab Issues, Epics, and Issue Boards. Plan how your workflows and board configurations will translate.",[20,654,655],{},"ADO Epics and Features become GitLab Epics.",[20,657,658],{},"Other work item types (e.g., user stories, tasks, bugs) become project-scoped issues.",[20,660,661],{},"Most standard fields are preserved; selected custom fields can be migrated when supported.",[20,663,664],{},"Parent-child relationships are retained so Epics reference all related issues.",[20,666,667],{},"Links to pull requests are converted to merge request links to maintain development traceability.",[13,669,670],{},"Example: Migration of an individual work item to a GitLab Issue, including field accuracy and relationships:",[13,672,673],{},[674,675],"img",{"alt":676,"src":677},"Example: Migration of an individual work item to a GitLab Issue","https://res.cloudinary.com/about-gitlab-com/image/upload/v1764769188/ztesjnxxfbwmfmtckyga.png",[13,679,680],{},"Batching guidance:",[17,682,683,686],{},[20,684,685],{},"If you need to run migrations in batches, use your new group/subgroup structure to define batches (for example, by ADO organization or by product area).",[20,687,688],{},"Use inventory reports to drive batch selection and test each batch with a pilot migration before scaling.",[13,690,691],{},[323,692,693],{},"Pipelines migration",[13,695,696,697,702,703,706],{},"Congregate ",[24,698,701],{"href":699,"rel":700},"https://gitlab.com/gitlab-org/professional-services-automation/tools/migration/congregate/-/merge_requests/1298",[],"recently introduced"," AI-powered conversion for multi-stage YAML pipelines from Azure DevOps to GitLab CI/CD. This automated conversion works best for simple, single-file pipelines and is designed to provide a working starting point rather than a production-ready ",[112,704,705],{},".gitlab-ci.yml"," file. The tool generates a functionally equivalent GitLab pipeline that you can then refine and optimize for your specific needs.",[17,708,709,715,718,721,724],{},[20,710,711,712,714],{},"Converts Azure Pipelines YAML to ",[112,713,705],{}," format automatically.",[20,716,717],{},"Best suited for straightforward, single-file pipeline configurations.",[20,719,720],{},"Provides a boilerplate to accelerate migration, not a final production artifact.",[20,722,723],{},"Requires review and adjustment for complex scenarios, custom tasks, or enterprise requirements.",[20,725,726,727,732],{},"Does not support Azure DevOps classic release pipelines — ",[24,728,731],{"href":729,"rel":730},"https://learn.microsoft.com/en-us/azure/devops/pipelines/release/from-classic-pipelines?view=azure-devops",[],"convert these to multi-stage YAML"," first.",[13,734,735,736,741],{},"Repository owners should review the ",[24,737,740],{"href":738,"rel":739},"https://docs.gitlab.com/ci/",[],"GitLab CI/CD documentation"," to further optimize and enhance their pipelines after the initial conversion.",[13,743,744],{},"Example of converted pipelines:",[105,746,750],{"className":747,"code":748,"language":749,"meta":110,"style":110},"language-yml shiki shiki-themes github-light","\n# azure-pipelines.yml\n\ntrigger:\n  - main\n\nvariables:\n  imageName: myapp\n\nstages:\n  - stage: Build\n    jobs:\n      - job: Build\n        pool:\n          vmImage: 'ubuntu-latest'\n        steps:\n          - checkout: self\n\n          - task: Docker@2\n            displayName: Build Docker image\n            inputs:\n              command: build\n              repository: $(imageName)\n              Dockerfile: '**/Dockerfile'\n              tags: |\n                $(Build.BuildId)\n\n  - stage: Test\n    jobs:\n      - job: Test\n        pool:\n          vmImage: 'ubuntu-latest'\n        steps:\n          - checkout: self\n\n          # Example: run tests inside the container\n          - script: |\n              docker run --rm $(imageName):$(Build.BuildId) npm test\n            displayName: Run tests\n\n  - stage: Push\n    jobs:\n      - job: Push\n        pool:\n          vmImage: 'ubuntu-latest'\n        steps:\n          - checkout: self\n\n          - task: Docker@2\n            displayName: Login to ACR\n            inputs:\n              command: login\n              containerRegistry: '\u003Cyour-acr-service-connection>'\n\n          - task: Docker@2\n            displayName: Push image to ACR\n            inputs:\n              command: push\n              repository: $(imageName)\n              tags: |\n                $(Build.BuildId)\n\n","yml",[112,751,752,756,762,766,775,784,788,795,806,810,817,829,836,848,855,865,872,885,889,901,911,918,928,938,948,959,964,968,979,985,995,1001,1009,1015,1025,1030,1036,1048,1054,1064,1069,1081,1088,1099,1106,1115,1122,1133,1138,1149,1159,1166,1176,1187,1192,1203,1213,1220,1230,1239,1248],{"__ignoreMap":110},[115,753,754],{"class":117,"line":118},[115,755,261],{"emptyLinePlaceholder":260},[115,757,758],{"class":117,"line":125},[115,759,761],{"class":760},"sAwPA","# azure-pipelines.yml\n",[115,763,764],{"class":117,"line":131},[115,765,261],{"emptyLinePlaceholder":260},[115,767,768,772],{"class":117,"line":137},[115,769,771],{"class":770},"shJU0","trigger",[115,773,774],{"class":121},":\n",[115,776,777,780],{"class":117,"line":143},[115,778,779],{"class":121},"  - ",[115,781,783],{"class":782},"sYBdl","main\n",[115,785,786],{"class":117,"line":149},[115,787,261],{"emptyLinePlaceholder":260},[115,789,790,793],{"class":117,"line":155},[115,791,792],{"class":770},"variables",[115,794,774],{"class":121},[115,796,797,800,803],{"class":117,"line":161},[115,798,799],{"class":770},"  imageName",[115,801,802],{"class":121},": ",[115,804,805],{"class":782},"myapp\n",[115,807,808],{"class":117,"line":167},[115,809,261],{"emptyLinePlaceholder":260},[115,811,812,815],{"class":117,"line":173},[115,813,814],{"class":770},"stages",[115,816,774],{"class":121},[115,818,819,821,824,826],{"class":117,"line":178},[115,820,779],{"class":121},[115,822,823],{"class":770},"stage",[115,825,802],{"class":121},[115,827,828],{"class":782},"Build\n",[115,830,831,834],{"class":117,"line":184},[115,832,833],{"class":770},"    jobs",[115,835,774],{"class":121},[115,837,838,841,844,846],{"class":117,"line":190},[115,839,840],{"class":121},"      - ",[115,842,843],{"class":770},"job",[115,845,802],{"class":121},[115,847,828],{"class":782},[115,849,850,853],{"class":117,"line":196},[115,851,852],{"class":770},"        pool",[115,854,774],{"class":121},[115,856,857,860,862],{"class":117,"line":201},[115,858,859],{"class":770},"          vmImage",[115,861,802],{"class":121},[115,863,864],{"class":782},"'ubuntu-latest'\n",[115,866,867,870],{"class":117,"line":206},[115,868,869],{"class":770},"        steps",[115,871,774],{"class":121},[115,873,874,877,880,882],{"class":117,"line":212},[115,875,876],{"class":121},"          - ",[115,878,879],{"class":770},"checkout",[115,881,802],{"class":121},[115,883,884],{"class":782},"self\n",[115,886,887],{"class":117,"line":217},[115,888,261],{"emptyLinePlaceholder":260},[115,890,891,893,896,898],{"class":117,"line":223},[115,892,876],{"class":121},[115,894,895],{"class":770},"task",[115,897,802],{"class":121},[115,899,900],{"class":782},"Docker@2\n",[115,902,903,906,908],{"class":117,"line":229},[115,904,905],{"class":770},"            displayName",[115,907,802],{"class":121},[115,909,910],{"class":782},"Build Docker image\n",[115,912,913,916],{"class":117,"line":235},[115,914,915],{"class":770},"            inputs",[115,917,774],{"class":121},[115,919,920,923,925],{"class":117,"line":240},[115,921,922],{"class":770},"              command",[115,924,802],{"class":121},[115,926,927],{"class":782},"build\n",[115,929,930,933,935],{"class":117,"line":245},[115,931,932],{"class":770},"              repository",[115,934,802],{"class":121},[115,936,937],{"class":782},"$(imageName)\n",[115,939,940,943,945],{"class":117,"line":251},[115,941,942],{"class":770},"              Dockerfile",[115,944,802],{"class":121},[115,946,947],{"class":782},"'**/Dockerfile'\n",[115,949,950,953,955],{"class":117,"line":257},[115,951,952],{"class":770},"              tags",[115,954,802],{"class":121},[115,956,958],{"class":957},"sD7c4","|\n",[115,960,961],{"class":117,"line":264},[115,962,963],{"class":782},"                $(Build.BuildId)\n",[115,965,966],{"class":117,"line":270},[115,967,261],{"emptyLinePlaceholder":260},[115,969,970,972,974,976],{"class":117,"line":276},[115,971,779],{"class":121},[115,973,823],{"class":770},[115,975,802],{"class":121},[115,977,978],{"class":782},"Test\n",[115,980,981,983],{"class":117,"line":282},[115,982,833],{"class":770},[115,984,774],{"class":121},[115,986,987,989,991,993],{"class":117,"line":288},[115,988,840],{"class":121},[115,990,843],{"class":770},[115,992,802],{"class":121},[115,994,978],{"class":782},[115,996,997,999],{"class":117,"line":294},[115,998,852],{"class":770},[115,1000,774],{"class":121},[115,1002,1003,1005,1007],{"class":117,"line":300},[115,1004,859],{"class":770},[115,1006,802],{"class":121},[115,1008,864],{"class":782},[115,1010,1011,1013],{"class":117,"line":306},[115,1012,869],{"class":770},[115,1014,774],{"class":121},[115,1016,1017,1019,1021,1023],{"class":117,"line":312},[115,1018,876],{"class":121},[115,1020,879],{"class":770},[115,1022,802],{"class":121},[115,1024,884],{"class":782},[115,1026,1028],{"class":117,"line":1027},35,[115,1029,261],{"emptyLinePlaceholder":260},[115,1031,1033],{"class":117,"line":1032},36,[115,1034,1035],{"class":760},"          # Example: run tests inside the container\n",[115,1037,1039,1041,1044,1046],{"class":117,"line":1038},37,[115,1040,876],{"class":121},[115,1042,1043],{"class":770},"script",[115,1045,802],{"class":121},[115,1047,958],{"class":957},[115,1049,1051],{"class":117,"line":1050},38,[115,1052,1053],{"class":782},"              docker run --rm $(imageName):$(Build.BuildId) npm test\n",[115,1055,1057,1059,1061],{"class":117,"line":1056},39,[115,1058,905],{"class":770},[115,1060,802],{"class":121},[115,1062,1063],{"class":782},"Run tests\n",[115,1065,1067],{"class":117,"line":1066},40,[115,1068,261],{"emptyLinePlaceholder":260},[115,1070,1072,1074,1076,1078],{"class":117,"line":1071},41,[115,1073,779],{"class":121},[115,1075,823],{"class":770},[115,1077,802],{"class":121},[115,1079,1080],{"class":782},"Push\n",[115,1082,1084,1086],{"class":117,"line":1083},42,[115,1085,833],{"class":770},[115,1087,774],{"class":121},[115,1089,1091,1093,1095,1097],{"class":117,"line":1090},43,[115,1092,840],{"class":121},[115,1094,843],{"class":770},[115,1096,802],{"class":121},[115,1098,1080],{"class":782},[115,1100,1102,1104],{"class":117,"line":1101},44,[115,1103,852],{"class":770},[115,1105,774],{"class":121},[115,1107,1109,1111,1113],{"class":117,"line":1108},45,[115,1110,859],{"class":770},[115,1112,802],{"class":121},[115,1114,864],{"class":782},[115,1116,1118,1120],{"class":117,"line":1117},46,[115,1119,869],{"class":770},[115,1121,774],{"class":121},[115,1123,1125,1127,1129,1131],{"class":117,"line":1124},47,[115,1126,876],{"class":121},[115,1128,879],{"class":770},[115,1130,802],{"class":121},[115,1132,884],{"class":782},[115,1134,1136],{"class":117,"line":1135},48,[115,1137,261],{"emptyLinePlaceholder":260},[115,1139,1141,1143,1145,1147],{"class":117,"line":1140},49,[115,1142,876],{"class":121},[115,1144,895],{"class":770},[115,1146,802],{"class":121},[115,1148,900],{"class":782},[115,1150,1152,1154,1156],{"class":117,"line":1151},50,[115,1153,905],{"class":770},[115,1155,802],{"class":121},[115,1157,1158],{"class":782},"Login to ACR\n",[115,1160,1162,1164],{"class":117,"line":1161},51,[115,1163,915],{"class":770},[115,1165,774],{"class":121},[115,1167,1169,1171,1173],{"class":117,"line":1168},52,[115,1170,922],{"class":770},[115,1172,802],{"class":121},[115,1174,1175],{"class":782},"login\n",[115,1177,1179,1182,1184],{"class":117,"line":1178},53,[115,1180,1181],{"class":770},"              containerRegistry",[115,1183,802],{"class":121},[115,1185,1186],{"class":782},"'\u003Cyour-acr-service-connection>'\n",[115,1188,1190],{"class":117,"line":1189},54,[115,1191,261],{"emptyLinePlaceholder":260},[115,1193,1195,1197,1199,1201],{"class":117,"line":1194},55,[115,1196,876],{"class":121},[115,1198,895],{"class":770},[115,1200,802],{"class":121},[115,1202,900],{"class":782},[115,1204,1206,1208,1210],{"class":117,"line":1205},56,[115,1207,905],{"class":770},[115,1209,802],{"class":121},[115,1211,1212],{"class":782},"Push image to ACR\n",[115,1214,1216,1218],{"class":117,"line":1215},57,[115,1217,915],{"class":770},[115,1219,774],{"class":121},[115,1221,1223,1225,1227],{"class":117,"line":1222},58,[115,1224,922],{"class":770},[115,1226,802],{"class":121},[115,1228,1229],{"class":782},"push\n",[115,1231,1233,1235,1237],{"class":117,"line":1232},59,[115,1234,932],{"class":770},[115,1236,802],{"class":121},[115,1238,937],{"class":782},[115,1240,1242,1244,1246],{"class":117,"line":1241},60,[115,1243,952],{"class":770},[115,1245,802],{"class":121},[115,1247,958],{"class":957},[115,1249,1251],{"class":117,"line":1250},61,[115,1252,963],{"class":782},[105,1254,1258],{"className":1255,"code":1256,"language":1257,"meta":110,"style":110},"language-yaml shiki shiki-themes github-light","\n# .gitlab-ci.yml\n\nvariables:\n  imageName: myapp\n\nstages:\n  - build\n  - test\n  - push\n\nbuild:\n  stage: build\n  image: docker:latest\n  services:\n    - docker:dind\n  script:\n    - docker build -t $imageName:$CI_PIPELINE_ID -f $(find . -name Dockerfile) .\n  only:\n    - main\n\ntest:\n  stage: test\n  image: docker:latest\n  services:\n    - docker:dind\n  script:\n    - docker run --rm $imageName:$CI_PIPELINE_ID npm test\n  only:\n    - main\n\npush:\n  stage: push\n  image: docker:latest\n  services:\n    - docker:dind\n  before_script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n  script:\n    - docker tag $imageName:$CI_PIPELINE_ID $CI_REGISTRY/$CI_PROJECT_PATH/$imageName:$CI_PIPELINE_ID\n    - docker push $CI_REGISTRY/$CI_PROJECT_PATH/$imageName:$CI_PIPELINE_ID\n  only:\n    - main\n\n","yaml",[112,1259,1260,1264,1269,1273,1279,1287,1291,1297,1303,1310,1316,1320,1327,1336,1346,1353,1361,1368,1375,1382,1388,1392,1399,1407,1415,1421,1427,1433,1440,1446,1452,1456,1463,1471,1479,1485,1491,1498,1505,1511,1518,1525,1531],{"__ignoreMap":110},[115,1261,1262],{"class":117,"line":118},[115,1263,261],{"emptyLinePlaceholder":260},[115,1265,1266],{"class":117,"line":125},[115,1267,1268],{"class":760},"# .gitlab-ci.yml\n",[115,1270,1271],{"class":117,"line":131},[115,1272,261],{"emptyLinePlaceholder":260},[115,1274,1275,1277],{"class":117,"line":137},[115,1276,792],{"class":770},[115,1278,774],{"class":121},[115,1280,1281,1283,1285],{"class":117,"line":143},[115,1282,799],{"class":770},[115,1284,802],{"class":121},[115,1286,805],{"class":782},[115,1288,1289],{"class":117,"line":149},[115,1290,261],{"emptyLinePlaceholder":260},[115,1292,1293,1295],{"class":117,"line":155},[115,1294,814],{"class":770},[115,1296,774],{"class":121},[115,1298,1299,1301],{"class":117,"line":161},[115,1300,779],{"class":121},[115,1302,927],{"class":782},[115,1304,1305,1307],{"class":117,"line":167},[115,1306,779],{"class":121},[115,1308,1309],{"class":782},"test\n",[115,1311,1312,1314],{"class":117,"line":173},[115,1313,779],{"class":121},[115,1315,1229],{"class":782},[115,1317,1318],{"class":117,"line":178},[115,1319,261],{"emptyLinePlaceholder":260},[115,1321,1322,1325],{"class":117,"line":184},[115,1323,1324],{"class":770},"build",[115,1326,774],{"class":121},[115,1328,1329,1332,1334],{"class":117,"line":190},[115,1330,1331],{"class":770},"  stage",[115,1333,802],{"class":121},[115,1335,927],{"class":782},[115,1337,1338,1341,1343],{"class":117,"line":196},[115,1339,1340],{"class":770},"  image",[115,1342,802],{"class":121},[115,1344,1345],{"class":782},"docker:latest\n",[115,1347,1348,1351],{"class":117,"line":201},[115,1349,1350],{"class":770},"  services",[115,1352,774],{"class":121},[115,1354,1355,1358],{"class":117,"line":206},[115,1356,1357],{"class":121},"    - ",[115,1359,1360],{"class":782},"docker:dind\n",[115,1362,1363,1366],{"class":117,"line":212},[115,1364,1365],{"class":770},"  script",[115,1367,774],{"class":121},[115,1369,1370,1372],{"class":117,"line":217},[115,1371,1357],{"class":121},[115,1373,1374],{"class":782},"docker build -t $imageName:$CI_PIPELINE_ID -f $(find . -name Dockerfile) .\n",[115,1376,1377,1380],{"class":117,"line":223},[115,1378,1379],{"class":770},"  only",[115,1381,774],{"class":121},[115,1383,1384,1386],{"class":117,"line":229},[115,1385,1357],{"class":121},[115,1387,783],{"class":782},[115,1389,1390],{"class":117,"line":235},[115,1391,261],{"emptyLinePlaceholder":260},[115,1393,1394,1397],{"class":117,"line":240},[115,1395,1396],{"class":770},"test",[115,1398,774],{"class":121},[115,1400,1401,1403,1405],{"class":117,"line":245},[115,1402,1331],{"class":770},[115,1404,802],{"class":121},[115,1406,1309],{"class":782},[115,1408,1409,1411,1413],{"class":117,"line":251},[115,1410,1340],{"class":770},[115,1412,802],{"class":121},[115,1414,1345],{"class":782},[115,1416,1417,1419],{"class":117,"line":257},[115,1418,1350],{"class":770},[115,1420,774],{"class":121},[115,1422,1423,1425],{"class":117,"line":264},[115,1424,1357],{"class":121},[115,1426,1360],{"class":782},[115,1428,1429,1431],{"class":117,"line":270},[115,1430,1365],{"class":770},[115,1432,774],{"class":121},[115,1434,1435,1437],{"class":117,"line":276},[115,1436,1357],{"class":121},[115,1438,1439],{"class":782},"docker run --rm $imageName:$CI_PIPELINE_ID npm test\n",[115,1441,1442,1444],{"class":117,"line":282},[115,1443,1379],{"class":770},[115,1445,774],{"class":121},[115,1447,1448,1450],{"class":117,"line":288},[115,1449,1357],{"class":121},[115,1451,783],{"class":782},[115,1453,1454],{"class":117,"line":294},[115,1455,261],{"emptyLinePlaceholder":260},[115,1457,1458,1461],{"class":117,"line":300},[115,1459,1460],{"class":770},"push",[115,1462,774],{"class":121},[115,1464,1465,1467,1469],{"class":117,"line":306},[115,1466,1331],{"class":770},[115,1468,802],{"class":121},[115,1470,1229],{"class":782},[115,1472,1473,1475,1477],{"class":117,"line":312},[115,1474,1340],{"class":770},[115,1476,802],{"class":121},[115,1478,1345],{"class":782},[115,1480,1481,1483],{"class":117,"line":1027},[115,1482,1350],{"class":770},[115,1484,774],{"class":121},[115,1486,1487,1489],{"class":117,"line":1032},[115,1488,1357],{"class":121},[115,1490,1360],{"class":782},[115,1492,1493,1496],{"class":117,"line":1038},[115,1494,1495],{"class":770},"  before_script",[115,1497,774],{"class":121},[115,1499,1500,1502],{"class":117,"line":1050},[115,1501,1357],{"class":121},[115,1503,1504],{"class":782},"docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n",[115,1506,1507,1509],{"class":117,"line":1056},[115,1508,1365],{"class":770},[115,1510,774],{"class":121},[115,1512,1513,1515],{"class":117,"line":1066},[115,1514,1357],{"class":121},[115,1516,1517],{"class":782},"docker tag $imageName:$CI_PIPELINE_ID $CI_REGISTRY/$CI_PROJECT_PATH/$imageName:$CI_PIPELINE_ID\n",[115,1519,1520,1522],{"class":117,"line":1071},[115,1521,1357],{"class":121},[115,1523,1524],{"class":782},"docker push $CI_REGISTRY/$CI_PROJECT_PATH/$imageName:$CI_PIPELINE_ID\n",[115,1526,1527,1529],{"class":117,"line":1083},[115,1528,1379],{"class":770},[115,1530,774],{"class":121},[115,1532,1533,1535],{"class":117,"line":1090},[115,1534,1357],{"class":121},[115,1536,783],{"class":782},[13,1538,1539],{},[323,1540,1541],{},"Final checklist:",[17,1543,1544,1547,1550,1553,1556,1559],{},[20,1545,1546],{},"Decide timeline and batch strategy.",[20,1548,1549],{},"Produce a full inventory of repositories, PRs, and contributors.",[20,1551,1552],{},"Choose Congregate or the built-in import based on scope (PRs and metadata vs. Git data only).",[20,1554,1555],{},"Decide who will run migrations and ensure tokens/permissions are configured.",[20,1557,1558],{},"Identify assets that must be migrated separately (pipelines, work items, artifacts, and hooks) and plan those efforts.",[20,1560,1561],{},"Run pilot migrations, validate results, then scale according to your plan.",[56,1563,1565],{"id":1564},"running-your-migrations","Running your migrations",[13,1567,1568],{},"After planning, execute migrations in stages, starting with trial runs. Trial migrations help surface org-specific issues early and let you measure duration, validate outcomes, and fine-tune your approach before production.",[13,1570,1571],{},"What trial migrations validate:",[17,1573,1574,1577,1580],{},[20,1575,1576],{},"Whether a given repository and related assets migrate successfully (history, branches, tags; plus MRs/comments if using Congregate)",[20,1578,1579],{},"Whether the destination is usable immediately (permissions, runners, CI/CD variables, integrations)",[20,1581,1582],{},"How long each batch takes, to set schedules and stakeholder expectations",[13,1584,1585],{},"Downtime guidance:",[17,1587,1588,1591,1594],{},[20,1589,1590],{},"GitLab's built-in Git import and Congregate do not inherently require downtime.",[20,1592,1593],{},"For production waves, freeze changes in ADO (branch protections or read-only) to avoid missed commits, PR updates, or work items created mid-migration.",[20,1595,1596],{},"Trial runs do not require freezes and can be run anytime.",[13,1598,680],{},[17,1600,1601,1604],{},[20,1602,1603],{},"Run trial batches back-to-back to shorten elapsed time; let teams validate results asynchronously.",[20,1605,1606],{},"Use your planned group/subgroup structure to define batches and respect API rate limits.",[13,1608,1609],{},"Recommended steps:",[1611,1612,1613],"ol",{},[20,1614,1615],{},"Create a test destination in GitLab for trials:",[17,1617,1618,1621],{},[20,1619,1620],{},"GitLab.com: create a dedicated group/namespace (for example, my-org-sandbox)",[20,1622,1623],{},"Self-managed: create a top-level group or a separate test instance if needed",[1611,1625,1626],{"start":125},[20,1627,1628],{},"Prepare authentication:",[17,1630,1631,1634],{},[20,1632,1633],{},"Azure DevOps PAT with required scopes.",[20,1635,1636],{},"GitLab Personal Access Token with api and read_repository (plus admin access for file-based imports used by Congregate).",[1611,1638,1639],{"start":131},[20,1640,1641],{},"Run trial migrations:",[17,1643,1644,1647],{},[20,1645,1646],{},"Repos only: use GitLab's built-in import (Repo by URL)",[20,1648,1649],{},"Repos + PRs/MRs and additional assets: use Congregate",[1611,1651,1652],{"start":137},[20,1653,1654],{},"Post-trial follow-up:",[17,1656,1657,1660,1663],{},[20,1658,1659],{},"Verify repo history, branches, tags; merge requests (if migrated), issues/epics (if migrated), labels, and relationships.",[20,1661,1662],{},"Check permissions/roles, protected branches, required approvals, runners/tags, variables/secrets, integrations/webhooks.",[20,1664,1665,1666,1668],{},"Validate pipelines (",[112,1667,705],{},") or converted pipelines where applicable.",[1611,1670,1671,1674,1677],{"start":143},[20,1672,1673],{},"Ask users to validate functionality and data fidelity.",[20,1675,1676],{},"Resolve issues uncovered during trials and update your runbooks.",[20,1678,1679],{},"Network and security:",[17,1681,1682],{},[20,1683,1684],{},"If your destination uses IP allow lists, add the IPs of your migration host and any required runners/integrations so imports can succeed.",[1611,1686,1687],{"start":161},[20,1688,1689],{},"Run production migrations in waves:",[17,1691,1692,1695],{},[20,1693,1694],{},"Enforce change freezes in ADO during each wave.",[20,1696,1697],{},"Monitor progress and logs; retry or adjust batch sizes if you hit rate limits.",[1611,1699,1700],{"start":167},[20,1701,1702],{},"Optional: remove the sandbox group or archive it after you finish.",[1704,1705,1708,1709],"figure",{"className":1706},[1707],"video_container","\n  ",[1710,1711],"iframe",{"src":1712,"frameBorder":1713,"allowFullScreen":1714},"https://www.youtube.com/embed/ibIXGfrVbi4?si=ZxOVnXjCF-h4Ne0N","0","true",[56,1716,1718],{"id":1717},"terminology-reference-for-gitlab-and-azure-devops","Terminology reference for GitLab and Azure DevOps",[1720,1721,1722,1737],"table",{},[1723,1724,1725],"thead",{},[1726,1727,1728,1731,1734],"tr",{},[1729,1730,384],"th",{},[1729,1732,1733],{},"Azure DevOps",[1729,1735,1736],{},"Similarities & Key Differences",[1738,1739,1740,1752,1763,1774,1785,1796,1807,1817,1828,1839,1850,1861,1872,1883,1894,1905,1916,1927,1938,1949,1960,1971,1982,1993,2004],"tbody",{},[1726,1741,1742,1746,1749],{},[1743,1744,1745],"td",{},"Group",[1743,1747,1748],{},"Organization",[1743,1750,1751],{},"Top-level namespace, membership, policies. ADO org contains Projects; GitLab Group contains Subgroups and Projects.",[1726,1753,1754,1757,1760],{},[1743,1755,1756],{},"Group or Subgroup",[1743,1758,1759],{},"Project",[1743,1761,1762],{},"Logical container, permissions boundary. ADO Project holds many repos; GitLab Groups/Subgroups organize many Projects.",[1726,1764,1765,1768,1771],{},[1743,1766,1767],{},"Project (includes a Git repo)",[1743,1769,1770],{},"Repository (inside a Project)",[1743,1772,1773],{},"Git history, branches, tags. In GitLab, a \"Project\" is the repo plus issues, CI/CD, wiki, etc. One repo per Project.",[1726,1775,1776,1779,1782],{},[1743,1777,1778],{},"Merge Request (MR)",[1743,1780,1781],{},"Pull Request (PR)",[1743,1783,1784],{},"Code review, discussions, approvals. MR rules include approvals, required pipelines, code owners.",[1726,1786,1787,1790,1793],{},[1743,1788,1789],{},"Protected Branches, MR Approval Rules, Status Checks",[1743,1791,1792],{},"Branch Policies",[1743,1794,1795],{},"Enforce reviews and checks. GitLab combines protections + approval rules + required status checks.",[1726,1797,1798,1801,1804],{},[1743,1799,1800],{},"GitLab CI/CD",[1743,1802,1803],{},"Azure Pipelines",[1743,1805,1806],{},"YAML pipelines, stages/jobs, logs. ADO also has classic UI pipelines; GitLab centers on .gitlab-ci.yml.",[1726,1808,1809,1811,1814],{},[1743,1810,705],{},[1743,1812,1813],{},"azure-pipelines.yml",[1743,1815,1816],{},"Defines stages/jobs/triggers. Syntax/features differ; map jobs, variables, artifacts, and triggers.",[1726,1818,1819,1822,1825],{},[1743,1820,1821],{},"Runners (shared/specific)",[1743,1823,1824],{},"Agents / Agent Pools",[1743,1826,1827],{},"Execute jobs on machines/containers. Target via demands (ADO) vs tags (GitLab). Registration/scoping differs.",[1726,1829,1830,1833,1836],{},[1743,1831,1832],{},"CI/CD Variables (project/group/instance), Protected/Masked",[1743,1834,1835],{},"Pipeline Variables, Variable Groups, Library",[1743,1837,1838],{},"Pass config/secrets to jobs. GitLab supports group inheritance and masking/protection flags.",[1726,1840,1841,1844,1847],{},[1743,1842,1843],{},"Integrations, CI/CD Variables, Deploy Keys",[1743,1845,1846],{},"Service Connections",[1743,1848,1849],{},"External auth to services/clouds. Map to integrations or variables; cloud-specific helpers available.",[1726,1851,1852,1855,1858],{},[1743,1853,1854],{},"Environments & Deployments (protected envs)",[1743,1856,1857],{},"Environments (with approvals)",[1743,1859,1860],{},"Track deploy targets/history. Approvals via protected envs and manual jobs in GitLab.",[1726,1862,1863,1866,1869],{},[1743,1864,1865],{},"Releases (tag + notes)",[1743,1867,1868],{},"Releases (classic or pipelines)",[1743,1870,1871],{},"Versioned notes/artifacts. GitLab Release ties to tags; deployments tracked separately.",[1726,1873,1874,1877,1880],{},[1743,1875,1876],{},"Job Artifacts",[1743,1878,1879],{},"Pipeline Artifacts",[1743,1881,1882],{},"Persist job outputs. Retention/expiry configured per job or project.",[1726,1884,1885,1888,1891],{},[1743,1886,1887],{},"Package Registry (NuGet/npm/Maven/PyPI/Composer, etc.)",[1743,1889,1890],{},"Azure Artifacts (NuGet/npm/Maven, etc.)",[1743,1892,1893],{},"Package hosting. Auth/namespace differ; migrate per package type.",[1726,1895,1896,1899,1902],{},[1743,1897,1898],{},"GitLab Container Registry",[1743,1900,1901],{},"Azure Container Registry (ACR) or others",[1743,1903,1904],{},"OCI images. GitLab provides per-project/group registries.",[1726,1906,1907,1910,1913],{},[1743,1908,1909],{},"Issue Boards",[1743,1911,1912],{},"Boards",[1743,1914,1915],{},"Visualize work by columns. GitLab boards are label-driven; multiple boards per project/group.",[1726,1917,1918,1921,1924],{},[1743,1919,1920],{},"Issues (types/labels), Epics",[1743,1922,1923],{},"Work Items (User Story/Bug/Task)",[1743,1925,1926],{},"Track units of work. Map ADO types/fields to labels/custom fields; epics at group level.",[1726,1928,1929,1932,1935],{},[1743,1930,1931],{},"Epics, Parent/Child Issues",[1743,1933,1934],{},"Epics/Features",[1743,1936,1937],{},"Hierarchy of work. Schema differs; use epics + issue relationships.",[1726,1939,1940,1943,1946],{},[1743,1941,1942],{},"Milestones and Iterations",[1743,1944,1945],{},"Iteration Paths",[1743,1947,1948],{},"Time-boxing. GitLab Iterations (group feature) or Milestones per project/group.",[1726,1950,1951,1954,1957],{},[1743,1952,1953],{},"Labels (scoped labels)",[1743,1955,1956],{},"Area Paths",[1743,1958,1959],{},"Categorization/ownership. Replace hierarchical areas with scoped labels.",[1726,1961,1962,1965,1968],{},[1743,1963,1964],{},"Project/Group Wiki",[1743,1966,1967],{},"Project Wiki",[1743,1969,1970],{},"Markdown wiki. Backed by repos in both; layout/auth differ slightly.",[1726,1972,1973,1976,1979],{},[1743,1974,1975],{},"Test reports via CI, Requirements/Test Management, integrations",[1743,1977,1978],{},"Test Plans/Cases/Runs",[1743,1980,1981],{},"QA evidence/traceability. No 1:1 with ADO Test Plans; often use CI reports + issues/requirements.",[1726,1983,1984,1987,1990],{},[1743,1985,1986],{},"Roles (Owner/Maintainer/Developer/Reporter/Guest) + custom roles",[1743,1988,1989],{},"Access levels + granular permissions",[1743,1991,1992],{},"Control read/write/admin. Models differ; leverage group inheritance and protected resources.",[1726,1994,1995,1998,2001],{},[1743,1996,1997],{},"Webhooks",[1743,1999,2000],{},"Service Hooks",[1743,2002,2003],{},"Event-driven integrations. Event names/payloads differ; reconfigure endpoints.",[1726,2005,2006,2009,2012],{},[1743,2007,2008],{},"Advanced Search",[1743,2010,2011],{},"Code Search",[1743,2013,2014],{},"Full-text repo search. Self-managed GitLab may need Elasticsearch/OpenSearch for advanced features.",[2016,2017,2018],"style",{},"html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}",{"title":110,"searchDepth":125,"depth":125,"links":2020},[2021,2022,2023,2024],{"id":58,"depth":125,"text":59},{"id":318,"depth":125,"text":319},{"id":1564,"depth":125,"text":1565},{"id":1717,"depth":125,"text":1718},"engineering","2025-12-03","Learn how to carry out the full migration from Azure DevOps to GitLab using GitLab Professional Services migration tools — from planning and execution to post-migration follow-up tasks.","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749658924/Blog/Hero%20Images/securitylifecycle-light.png",{},"/en-us/blog/migration-from-azure-devops-to-gitlab",{"title":5,"description":2034,"ogTitle":5,"ogDescription":2027,"ogUrl":2035,"ogSiteName":2036,"ogType":2037,"canonicalUrls":2035,"ogImage":2030},"Learn how to migrate from Azure DevOps to GitLab using GitLab Professional Services migration tools — from planning and execution to follow-up tasks.","https://about.gitlab.com/blog/migration-from-azure-devops-to-gitlab","https://about.gitlab.com","article","migration-from-azure-devops-to-gitlab","en-us/blog/migration-from-azure-devops-to-gitlab",[2041,2042,2043],"tutorial","git","CI/CD","BlogPost","2026-01-16","bYxr3sSRT_VN2kcSpEyF4zey_Re1nL7gvteaVhVaDJk",{"logo":2048,"freeTrial":2053,"sales":2058,"login":2063,"items":2068,"search":2393,"minimal":2424,"duo":2443,"switchNav":2452,"pricingDeployment":2463},{"config":2049},{"href":2050,"dataGaName":2051,"dataGaLocation":2052},"/","gitlab logo","header",{"text":2054,"config":2055},"Get free trial",{"href":2056,"dataGaName":2057,"dataGaLocation":2052},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":2059,"config":2060},"Request a demo",{"href":2061,"dataGaName":2062,"dataGaLocation":2052},"/sales/?contact-topic=request-demo","sales",{"text":2064,"config":2065},"Sign in",{"href":2066,"dataGaName":2067,"dataGaLocation":2052},"https://gitlab.com/users/sign_in/","sign in",[2069,2098,2196,2201,2315,2371],{"text":2070,"config":2071,"menu":2073},"Platform",{"dataNavLevelOne":2072},"platform",{"type":2074,"columns":2075},"cards",[2076,2082,2090],{"title":2070,"description":2077,"link":2078},"The intelligent orchestration platform for DevSecOps",{"text":2079,"config":2080},"Explore our Platform",{"href":2081,"dataGaName":2072,"dataGaLocation":2052},"/platform/",{"title":2083,"description":2084,"link":2085},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":2086,"config":2087},"Meet GitLab Duo",{"href":2088,"dataGaName":2089,"dataGaLocation":2052},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2091,"description":2092,"link":2093},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":2094,"config":2095},"Learn more",{"href":2096,"dataGaName":2097,"dataGaLocation":2052},"/why-gitlab/","why gitlab",{"text":2099,"left":260,"config":2100,"menu":2102},"Product",{"dataNavLevelOne":2101},"solutions",{"type":2103,"link":2104,"columns":2108,"feature":2176},"lists",{"text":2105,"config":2106},"View all Solutions",{"href":2107,"dataGaName":2101,"dataGaLocation":2052},"/solutions/",[2109,2132,2155],{"title":2110,"description":2111,"link":2112,"items":2117},"Automation","CI/CD and automation to accelerate deployment",{"config":2113},{"icon":2114,"href":2115,"dataGaName":2116,"dataGaLocation":2052},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[2118,2121,2124,2128],{"text":2043,"config":2119},{"href":2120,"dataGaLocation":2052,"dataGaName":2043},"/solutions/continuous-integration/",{"text":2083,"config":2122},{"href":2088,"dataGaLocation":2052,"dataGaName":2123},"gitlab duo agent platform - product menu",{"text":2125,"config":2126},"Source Code Management",{"href":2127,"dataGaLocation":2052,"dataGaName":2125},"/solutions/source-code-management/",{"text":2129,"config":2130},"Automated Software Delivery",{"href":2115,"dataGaLocation":2052,"dataGaName":2131},"Automated software delivery",{"title":2133,"description":2134,"link":2135,"items":2140},"Security","Deliver code faster without compromising security",{"config":2136},{"href":2137,"dataGaName":2138,"dataGaLocation":2052,"icon":2139},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2141,2145,2150],{"text":2142,"config":2143},"Application Security Testing",{"href":2137,"dataGaName":2144,"dataGaLocation":2052},"Application security testing",{"text":2146,"config":2147},"Software Supply Chain Security",{"href":2148,"dataGaLocation":2052,"dataGaName":2149},"/solutions/supply-chain/","Software supply chain security",{"text":2151,"config":2152},"Software Compliance",{"href":2153,"dataGaName":2154,"dataGaLocation":2052},"/solutions/software-compliance/","software compliance",{"title":2156,"link":2157,"items":2162},"Measurement",{"config":2158},{"icon":2159,"href":2160,"dataGaName":2161,"dataGaLocation":2052},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[2163,2167,2171],{"text":2164,"config":2165},"Visibility & Measurement",{"href":2160,"dataGaLocation":2052,"dataGaName":2166},"Visibility and Measurement",{"text":2168,"config":2169},"Value Stream Management",{"href":2170,"dataGaLocation":2052,"dataGaName":2168},"/solutions/value-stream-management/",{"text":2172,"config":2173},"Analytics & Insights",{"href":2174,"dataGaLocation":2052,"dataGaName":2175},"/solutions/analytics-and-insights/","Analytics and insights",{"title":2177,"type":2103,"items":2178},"GitLab for",[2179,2185,2191],{"text":2180,"config":2181},"Enterprise",{"icon":2182,"href":2183,"dataGaLocation":2052,"dataGaName":2184},"Building","/enterprise/","enterprise",{"text":2186,"config":2187},"Small Business",{"icon":2188,"href":2189,"dataGaLocation":2052,"dataGaName":2190},"Work","/small-business/","small business",{"text":2192,"config":2193},"Public Sector",{"icon":1748,"href":2194,"dataGaLocation":2052,"dataGaName":2195},"/solutions/public-sector/","public sector",{"text":2197,"config":2198},"Pricing",{"href":2199,"dataGaName":2200,"dataGaLocation":2052,"dataNavLevelOne":2200},"/pricing/","pricing",{"text":2202,"config":2203,"menu":2205},"Resources",{"dataNavLevelOne":2204},"resources",{"type":2103,"link":2206,"columns":2210,"feature":2304},{"text":2207,"config":2208},"View all resources",{"href":2209,"dataGaName":2204,"dataGaLocation":2052},"/resources/",[2211,2244,2271],{"title":2212,"items":2213},"Getting started",[2214,2219,2224,2229,2234,2239],{"text":2215,"config":2216},"Install",{"href":2217,"dataGaName":2218,"dataGaLocation":2052},"/install/","install",{"text":2220,"config":2221},"Quick start guides",{"href":2222,"dataGaName":2223,"dataGaLocation":2052},"/get-started/","quick setup checklists",{"text":2225,"config":2226},"Learn",{"href":2227,"dataGaLocation":2052,"dataGaName":2228},"https://university.gitlab.com/","learn",{"text":2230,"config":2231},"Product documentation",{"href":2232,"dataGaName":2233,"dataGaLocation":2052},"https://docs.gitlab.com/","product documentation",{"text":2235,"config":2236},"Best practice videos",{"href":2237,"dataGaName":2238,"dataGaLocation":2052},"/getting-started-videos/","best practice videos",{"text":2240,"config":2241},"Integrations",{"href":2242,"dataGaName":2243,"dataGaLocation":2052},"/integrations/","integrations",{"title":2245,"items":2246},"Discover",[2247,2252,2257,2262,2266],{"text":2248,"config":2249},"Customer success stories",{"href":2250,"dataGaName":2251,"dataGaLocation":2052},"/customers/","customer success stories",{"text":2253,"config":2254},"Blog",{"href":2255,"dataGaName":2256,"dataGaLocation":2052},"/blog/","blog",{"text":2258,"config":2259},"Demo Hub",{"href":2260,"dataGaName":2261,"dataGaLocation":2052},"/demo-hub/","demo hub",{"text":2263,"config":2264},"The Source",{"href":2265,"dataGaName":2256,"dataGaLocation":2052},"/the-source/",{"text":2267,"config":2268},"Remote",{"href":2269,"dataGaName":2270,"dataGaLocation":2052},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2272,"items":2273},"Connect",[2274,2279,2284,2289,2294,2299],{"text":2275,"config":2276},"GitLab Services",{"href":2277,"dataGaName":2278,"dataGaLocation":2052},"/services/","services",{"text":2280,"config":2281},"Contribute",{"href":2282,"dataGaName":2283,"dataGaLocation":2052},"https://contributors.gitlab.com","contribute",{"text":2285,"config":2286},"Community",{"href":2287,"dataGaName":2288,"dataGaLocation":2052},"/community/","community",{"text":2290,"config":2291},"Forum",{"href":2292,"dataGaName":2293,"dataGaLocation":2052},"https://forum.gitlab.com/","forum",{"text":2295,"config":2296},"Events",{"href":2297,"dataGaName":2298,"dataGaLocation":2052},"/events/","events",{"text":2300,"config":2301},"Partners",{"href":2302,"dataGaName":2303,"dataGaLocation":2052},"/partners/","partners",{"config":2305,"title":2308,"text":2309,"link":2310},{"background":2306,"textColor":2307},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":2311,"config":2312},"Read the latest",{"href":2313,"dataGaName":2314,"dataGaLocation":2052},"/whats-new/","whats new",{"text":2316,"config":2317,"menu":2319},"Company",{"dataNavLevelOne":2318},"company",{"type":2103,"columns":2320},[2321],{"items":2322},[2323,2328,2334,2336,2341,2346,2351,2356,2361,2366],{"text":2324,"config":2325},"About",{"href":2326,"dataGaName":2327,"dataGaLocation":2052},"/company/","about",{"text":2329,"config":2330,"footerGa":2333},"Jobs",{"href":2331,"dataGaName":2332,"dataGaLocation":2052},"/jobs/","jobs",{"dataGaName":2332},{"text":2295,"config":2335},{"href":2297,"dataGaName":2298,"dataGaLocation":2052},{"text":2337,"config":2338},"Leadership",{"href":2339,"dataGaName":2340,"dataGaLocation":2052},"/company/team/e-group/","leadership",{"text":2342,"config":2343},"Handbook",{"href":2344,"dataGaName":2345,"dataGaLocation":2052},"https://handbook.gitlab.com/","handbook",{"text":2347,"config":2348},"Investor relations",{"href":2349,"dataGaName":2350,"dataGaLocation":2052},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":2352,"config":2353},"Trust Center",{"href":2354,"dataGaName":2355,"dataGaLocation":2052},"/security/","trust center",{"text":2357,"config":2358},"AI Transparency Center",{"href":2359,"dataGaName":2360,"dataGaLocation":2052},"/ai-transparency-center/","ai transparency center",{"text":2362,"config":2363},"Newsletter",{"href":2364,"dataGaName":2365,"dataGaLocation":2052},"/company/contact/#contact-forms","newsletter",{"text":2367,"config":2368},"Press",{"href":2369,"dataGaName":2370,"dataGaLocation":2052},"/press/","press",{"text":2372,"config":2373,"menu":2374},"Contact us",{"dataNavLevelOne":2318},{"type":2103,"columns":2375},[2376],{"items":2377},[2378,2383,2388],{"text":2379,"config":2380},"Talk to sales",{"href":2381,"dataGaName":2382,"dataGaLocation":2052},"/sales/","talk to sales",{"text":2384,"config":2385},"Support portal",{"href":2386,"dataGaName":2387,"dataGaLocation":2052},"https://support.gitlab.com/hc/en-us","support portal",{"text":2389,"config":2390},"Customer portal",{"href":2391,"dataGaName":2392,"dataGaLocation":2052},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2394,"login":2395,"suggestions":2402},"Close",{"text":2396,"link":2397},"To search repositories and projects, login to",{"text":2398,"config":2399},"gitlab.com",{"href":2066,"dataGaName":2400,"dataGaLocation":2401},"search login","search",{"text":2403,"default":2404},"Suggestions",[2405,2407,2411,2413,2417,2421],{"text":2083,"config":2406},{"href":2088,"dataGaName":2083,"dataGaLocation":2401},{"text":2408,"config":2409},"Code Suggestions (AI)",{"href":2410,"dataGaName":2408,"dataGaLocation":2401},"/solutions/code-suggestions/",{"text":2043,"config":2412},{"href":2120,"dataGaName":2043,"dataGaLocation":2401},{"text":2414,"config":2415},"GitLab on AWS",{"href":2416,"dataGaName":2414,"dataGaLocation":2401},"/partners/technology-partners/aws/",{"text":2418,"config":2419},"GitLab on Google Cloud",{"href":2420,"dataGaName":2418,"dataGaLocation":2401},"/partners/technology-partners/google-cloud-platform/",{"text":2422,"config":2423},"Why GitLab?",{"href":2096,"dataGaName":2422,"dataGaLocation":2401},{"freeTrial":2425,"mobileIcon":2430,"desktopIcon":2435,"secondaryButton":2438},{"text":2426,"config":2427},"Start free trial",{"href":2428,"dataGaName":2057,"dataGaLocation":2429},"https://gitlab.com/-/trials/new/","nav",{"altText":2431,"config":2432},"Gitlab Icon",{"src":2433,"dataGaName":2434,"dataGaLocation":2429},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2431,"config":2436},{"src":2437,"dataGaName":2434,"dataGaLocation":2429},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2439,"config":2440},"Get Started",{"href":2441,"dataGaName":2442,"dataGaLocation":2429},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":2444,"mobileIcon":2448,"desktopIcon":2450},{"text":2445,"config":2446},"Learn more about GitLab Duo",{"href":2088,"dataGaName":2447,"dataGaLocation":2429},"gitlab duo",{"altText":2431,"config":2449},{"src":2433,"dataGaName":2434,"dataGaLocation":2429},{"altText":2431,"config":2451},{"src":2437,"dataGaName":2434,"dataGaLocation":2429},{"button":2453,"mobileIcon":2458,"desktopIcon":2460},{"text":2454,"config":2455},"/switch",{"href":2456,"dataGaName":2457,"dataGaLocation":2429},"#contact","switch",{"altText":2431,"config":2459},{"src":2433,"dataGaName":2434,"dataGaLocation":2429},{"altText":2431,"config":2461},{"src":2462,"dataGaName":2434,"dataGaLocation":2429},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2464,"mobileIcon":2469,"desktopIcon":2471},{"text":2465,"config":2466},"Back to pricing",{"href":2199,"dataGaName":2467,"dataGaLocation":2429,"icon":2468},"back to pricing","GoBack",{"altText":2431,"config":2470},{"src":2433,"dataGaName":2434,"dataGaLocation":2429},{"altText":2431,"config":2472},{"src":2437,"dataGaName":2434,"dataGaLocation":2429},{"title":2474,"titleMobile":2475,"button":2476,"config":2481},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":2094,"config":2477},{"href":2478,"dataGaName":2479,"dataGaLocation":2480},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":2482,"disabled":2483},"release",false,{"data":2485},{"text":2486,"source":2487,"edit":2493,"contribute":2498,"config":2503,"items":2508,"minimal":2718},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":2488,"config":2489},"View page source",{"href":2490,"dataGaName":2491,"dataGaLocation":2492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2494,"config":2495},"Edit this page",{"href":2496,"dataGaName":2497,"dataGaLocation":2492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2499,"config":2500},"Please contribute",{"href":2501,"dataGaName":2502,"dataGaLocation":2492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2504,"facebook":2505,"youtube":2506,"linkedin":2507},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2509,2556,2610,2654,2686],{"title":2197,"links":2510,"subMenu":2525},[2511,2515,2520],{"text":2512,"config":2513},"View plans",{"href":2199,"dataGaName":2514,"dataGaLocation":2492},"view plans",{"text":2516,"config":2517},"Why Premium?",{"href":2518,"dataGaName":2519,"dataGaLocation":2492},"/pricing/premium/","why premium",{"text":2521,"config":2522},"Why Ultimate?",{"href":2523,"dataGaName":2524,"dataGaLocation":2492},"/pricing/ultimate/","why ultimate",[2526],{"title":2527,"links":2528},"Contact Us",[2529,2532,2534,2536,2541,2546,2551],{"text":2530,"config":2531},"Contact sales",{"href":2381,"dataGaName":2062,"dataGaLocation":2492},{"text":2384,"config":2533},{"href":2386,"dataGaName":2387,"dataGaLocation":2492},{"text":2389,"config":2535},{"href":2391,"dataGaName":2392,"dataGaLocation":2492},{"text":2537,"config":2538},"Status",{"href":2539,"dataGaName":2540,"dataGaLocation":2492},"https://status.gitlab.com/","status",{"text":2542,"config":2543},"Terms of use",{"href":2544,"dataGaName":2545,"dataGaLocation":2492},"/terms/","terms of use",{"text":2547,"config":2548},"Privacy statement",{"href":2549,"dataGaName":2550,"dataGaLocation":2492},"/privacy/","privacy statement",{"text":2552,"config":2553},"Cookie preferences",{"dataGaName":2554,"dataGaLocation":2492,"id":2555,"isOneTrustButton":260},"cookie preferences","ot-sdk-btn",{"title":2099,"links":2557,"subMenu":2566},[2558,2562],{"text":2559,"config":2560},"DevSecOps platform",{"href":2081,"dataGaName":2561,"dataGaLocation":2492},"devsecops platform",{"text":2563,"config":2564},"AI-Assisted Development",{"href":2088,"dataGaName":2565,"dataGaLocation":2492},"ai-assisted development",[2567],{"title":2568,"links":2569},"Topics",[2570,2575,2580,2585,2590,2595,2600,2605],{"text":2571,"config":2572},"CICD",{"href":2573,"dataGaName":2574,"dataGaLocation":2492},"/topics/ci-cd/","cicd",{"text":2576,"config":2577},"GitOps",{"href":2578,"dataGaName":2579,"dataGaLocation":2492},"/topics/gitops/","gitops",{"text":2581,"config":2582},"DevOps",{"href":2583,"dataGaName":2584,"dataGaLocation":2492},"/topics/devops/","devops",{"text":2586,"config":2587},"Version Control",{"href":2588,"dataGaName":2589,"dataGaLocation":2492},"/topics/version-control/","version control",{"text":2591,"config":2592},"DevSecOps",{"href":2593,"dataGaName":2594,"dataGaLocation":2492},"/topics/devsecops/","devsecops",{"text":2596,"config":2597},"Cloud Native",{"href":2598,"dataGaName":2599,"dataGaLocation":2492},"/topics/cloud-native/","cloud native",{"text":2601,"config":2602},"AI for Coding",{"href":2603,"dataGaName":2604,"dataGaLocation":2492},"/topics/devops/ai-for-coding/","ai for coding",{"text":2606,"config":2607},"Agentic AI",{"href":2608,"dataGaName":2609,"dataGaLocation":2492},"/topics/agentic-ai/","agentic ai",{"title":2611,"links":2612},"Solutions",[2613,2615,2617,2622,2626,2629,2633,2636,2638,2641,2644,2649],{"text":2142,"config":2614},{"href":2137,"dataGaName":2142,"dataGaLocation":2492},{"text":2131,"config":2616},{"href":2115,"dataGaName":2116,"dataGaLocation":2492},{"text":2618,"config":2619},"Agile development",{"href":2620,"dataGaName":2621,"dataGaLocation":2492},"/solutions/agile-delivery/","agile delivery",{"text":2623,"config":2624},"SCM",{"href":2127,"dataGaName":2625,"dataGaLocation":2492},"source code management",{"text":2571,"config":2627},{"href":2120,"dataGaName":2628,"dataGaLocation":2492},"continuous integration & delivery",{"text":2630,"config":2631},"Value stream management",{"href":2170,"dataGaName":2632,"dataGaLocation":2492},"value stream management",{"text":2576,"config":2634},{"href":2635,"dataGaName":2579,"dataGaLocation":2492},"/solutions/gitops/",{"text":2180,"config":2637},{"href":2183,"dataGaName":2184,"dataGaLocation":2492},{"text":2639,"config":2640},"Small business",{"href":2189,"dataGaName":2190,"dataGaLocation":2492},{"text":2642,"config":2643},"Public sector",{"href":2194,"dataGaName":2195,"dataGaLocation":2492},{"text":2645,"config":2646},"Education",{"href":2647,"dataGaName":2648,"dataGaLocation":2492},"/solutions/education/","education",{"text":2650,"config":2651},"Financial services",{"href":2652,"dataGaName":2653,"dataGaLocation":2492},"/solutions/finance/","financial services",{"title":2202,"links":2655},[2656,2658,2660,2662,2665,2667,2670,2672,2674,2676,2678,2680,2682,2684],{"text":2215,"config":2657},{"href":2217,"dataGaName":2218,"dataGaLocation":2492},{"text":2220,"config":2659},{"href":2222,"dataGaName":2223,"dataGaLocation":2492},{"text":2225,"config":2661},{"href":2227,"dataGaName":2228,"dataGaLocation":2492},{"text":2230,"config":2663},{"href":2232,"dataGaName":2664,"dataGaLocation":2492},"docs",{"text":2253,"config":2666},{"href":2255,"dataGaName":2256,"dataGaLocation":2492},{"text":2668,"config":2669},"What's new",{"href":2313,"dataGaName":2314,"dataGaLocation":2492},{"text":2248,"config":2671},{"href":2250,"dataGaName":2251,"dataGaLocation":2492},{"text":2267,"config":2673},{"href":2269,"dataGaName":2270,"dataGaLocation":2492},{"text":2275,"config":2675},{"href":2277,"dataGaName":2278,"dataGaLocation":2492},{"text":2280,"config":2677},{"href":2282,"dataGaName":2283,"dataGaLocation":2492},{"text":2285,"config":2679},{"href":2287,"dataGaName":2288,"dataGaLocation":2492},{"text":2290,"config":2681},{"href":2292,"dataGaName":2293,"dataGaLocation":2492},{"text":2295,"config":2683},{"href":2297,"dataGaName":2298,"dataGaLocation":2492},{"text":2300,"config":2685},{"href":2302,"dataGaName":2303,"dataGaLocation":2492},{"title":2316,"links":2687},[2688,2690,2692,2694,2696,2698,2702,2707,2709,2711,2713],{"text":2324,"config":2689},{"href":2326,"dataGaName":2318,"dataGaLocation":2492},{"text":2329,"config":2691},{"href":2331,"dataGaName":2332,"dataGaLocation":2492},{"text":2337,"config":2693},{"href":2339,"dataGaName":2340,"dataGaLocation":2492},{"text":2342,"config":2695},{"href":2344,"dataGaName":2345,"dataGaLocation":2492},{"text":2347,"config":2697},{"href":2349,"dataGaName":2350,"dataGaLocation":2492},{"text":2699,"config":2700},"Sustainability",{"href":2701,"dataGaName":2699,"dataGaLocation":2492},"/sustainability/",{"text":2703,"config":2704},"Diversity, inclusion and belonging (DIB)",{"href":2705,"dataGaName":2706,"dataGaLocation":2492},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2352,"config":2708},{"href":2354,"dataGaName":2355,"dataGaLocation":2492},{"text":2362,"config":2710},{"href":2364,"dataGaName":2365,"dataGaLocation":2492},{"text":2367,"config":2712},{"href":2369,"dataGaName":2370,"dataGaLocation":2492},{"text":2714,"config":2715},"Modern Slavery Transparency Statement",{"href":2716,"dataGaName":2717,"dataGaLocation":2492},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2719},[2720,2723,2726],{"text":2721,"config":2722},"Terms",{"href":2544,"dataGaName":2545,"dataGaLocation":2492},{"text":2724,"config":2725},"Cookies",{"dataGaName":2554,"dataGaLocation":2492,"id":2555,"isOneTrustButton":260},{"text":2727,"config":2728},"Privacy",{"href":2549,"dataGaName":2550,"dataGaLocation":2492},[2730,2743],{"id":2731,"title":7,"body":2029,"config":2732,"content":2734,"description":2029,"extension":749,"meta":2738,"navigation":260,"path":2739,"seo":2740,"stem":2741,"__hash__":2742},"blogAuthors/en-us/blog/authors/evgeny-rudinsky.yml",{"template":2733},"BlogAuthor",{"name":7,"config":2735},{"ctfId":2736,"headshot":2737},"erudinsky","https://res.cloudinary.com/about-gitlab-com/image/upload/v1761069206/yppyhhdmdrw4u1nz7het.jpg",{},"/en-us/blog/authors/evgeny-rudinsky",{},"en-us/blog/authors/evgeny-rudinsky","OtgSXy1cMxWS2khqtu-PdUFWhG9Eck_jUQfH5JUwzWM",{"id":2744,"title":8,"body":2029,"config":2745,"content":2746,"description":2029,"extension":749,"meta":2750,"navigation":260,"path":2751,"seo":2752,"stem":2753,"__hash__":2754},"blogAuthors/en-us/blog/authors/michael-leopard.yml",{"template":2733},{"name":8,"config":2747},{"ctfId":2748,"headshot":2749},"leopardm","https://res.cloudinary.com/about-gitlab-com/image/upload/v1761069206/tjpzzunnzhen77u6tf5s.jpg",{},"/en-us/blog/authors/michael-leopard",{},"en-us/blog/authors/michael-leopard","Yavr1VB0sBdgyY2GfU8OYVm_Byiv9EzriWbuDzn6Al4",[2756,2765,2773],{"title":2757,"description":2758,"heroImage":2759,"category":2025,"date":2760,"authors":2761,"slug":2764,"externalUrl":2029},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[2762,2763],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":2766,"description":2767,"heroImage":2768,"category":2025,"date":2769,"authors":2770,"slug":2772,"externalUrl":2029},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[2771],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":2774,"description":2775,"heroImage":2776,"category":2025,"date":2777,"authors":2778,"slug":2780,"externalUrl":2029},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[2779],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":2782},[2783,2797,2809,2821],{"id":2784,"categories":2785,"header":2787,"text":2788,"button":2789,"image":2794},"ai-modernization",[2786],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":2790,"config":2791},"Get your AI maturity score",{"href":2792,"dataGaName":2793,"dataGaLocation":2256},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":2795},{"src":2796},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2798,"categories":2799,"header":2801,"text":2788,"button":2802,"image":2806},"devops-modernization",[2800,2594],"product","Are you just managing tools or shipping innovation?",{"text":2803,"config":2804},"Get your DevOps maturity score",{"href":2805,"dataGaName":2793,"dataGaLocation":2256},"/assessments/devops-modernization-assessment/",{"config":2807},{"src":2808},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2810,"categories":2811,"header":2813,"text":2788,"button":2814,"image":2818},"security-modernization",[2812],"security","Are you trading speed for security?",{"text":2815,"config":2816},"Get your security maturity score",{"href":2817,"dataGaName":2793,"dataGaLocation":2256},"/assessments/security-modernization-assessment/",{"config":2819},{"src":2820},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2822,"paths":2823,"header":2825,"text":2826,"button":2827,"image":2832},"github-azure-migration",[2038,2824],"integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":2828,"config":2829},"See how GitLab compares to GitHub",{"href":2830,"dataGaName":2831,"dataGaLocation":2256},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2833},{"src":2808},{"header":2835,"blurb":2836,"button":2837,"secondaryButton":2842},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":2838,"config":2839},"Get your free trial",{"href":2840,"dataGaName":2057,"dataGaLocation":2841},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":2530,"config":2843},{"href":2381,"dataGaName":2062,"dataGaLocation":2841},1786803773161]