[{"data":1,"prerenderedAt":720},["ShallowReactive",2],{"/en-us/blog/how-to-avoid-broken-master-with-pipelines-for-merge-requests/":3,"navigation-en-us":38,"banner-en-us":466,"footer-en-us":483,"Shinya Maeda":693,"next-steps-en-us":705},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":28,"_id":31,"_type":32,"title":33,"_source":34,"_file":35,"_stem":36,"_extension":37},"/en-us/blog/how-to-avoid-broken-master-with-pipelines-for-merge-requests","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"How to prevent broken master with merge trains & pipelines","Do you still run pipelines on source branches? Let's start running them on merge commits!","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749678366/Blog/Hero%20Images/merge-train.jpg","https://about.gitlab.com/blog/how-to-avoid-broken-master-with-pipelines-for-merge-requests","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to avoid broken master with Pipelines for Merged Results and Merge Trains\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Shinya Maeda\"}],\n        \"datePublished\": \"2019-09-11\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":20,"body":21,"category":22,"tags":23},"How to avoid broken master with Pipelines for Merged Results and Merge Trains",[19],"Shinya Maeda","2019-09-11","\nBroken master. This can happen when CI pipelines run on the master branch (or default branch), but don't\npass all tests. A red cross mark is shown in the project's top page, signalling unstable source\ncode and eroding the trust of users. Broken master could also be a blocker against\na continuous deployment/delivery stream line in which deployment jobs\nare executed after the test stage passed in master pipelines.\n\nAll maintainers want to avoid this critical state,\nbut how can we prevent it?\n\n## Let's look at how master is broken in the first place\n\nLet's say you're one of the maintainers of a project. It's a busy repository with hundreds of merges\nto master every day. A developer assigns a merge request (MR) to you. The MR passed all of the tests in the CI pipelines,\nhas been reviewed thoroughly by code reviewers, all open discussions have been resolved, and the MR has been\napproved by the relevant [code owners](https://docs.gitlab.com/ee/user/project/codeowners/).\n\nYou would press the \"Merge\" button without a second thought, but how are you confident that\na pipeline running on master branch after the merge will pass all tests again?\nIf your answer is \"It might break the master branch,\" then\nyou're right. This could happen, for example, if master has advanced by some\nnew commits, and one of them changed a lint rule. The MR in question\nstill contains an invalid coding style, but the latest pipeline on the MR passes,\nbecause the feature branch is based on an old version of master.\n\nEnter two new GitLab features: [Pipelines for Merged Results](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html)\nand [Merge Trains](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.html).\nLet me show you how they works and how to enable them.\n\n## How to continually run CI pipelines on the merge commit\n\nLet's break down what went wrong in the scenario above. Even though the pipeline on the\nmerge request passed all the tests, it ran on a source (feature) branch\nwhich could be based on an outdated version of master. In such a case,\nthe result of pipeline is considered as _untrusted_, because there may be a huge difference\nbetween an actual-and-future merge commit and the commit in question.\n\nAs a [boring solution](https://handbook.gitlab.com/handbook/values/#boring-solutions), developers can continually rebase their MR\non the latest master, but this is annoying and inefficient, given the speed of\ngrowth of the master branch.\nIt causes a lot of friction between developers and maintainers, slowing down the development cycle.\n\nTo address this problem, we introduced [Pipelines for Merged Results](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html)\nin [GitLab 11.10](/releases/2019/04/22/gitlab-11-10-released/#pipelines-for-merged-results).\n\nSimply put, the main difference between pipelines for merged results and normal pipelines is that\n**pipelines run on merge commits, instead of source branches, before the actual merge happens**.\nThis merge commit is generated from the latest commits of target branch and\nsource branch and written in a temporary place (`refs/merge-requests/:iid/merge`).\nTherefore, we can run a pipeline on it without interfering with master.\n\nHere is a sample workflow with the above scenario:\n\n1. A developer pushes a new commit to a merge request.\n1. GitLab creates a merge commit from the HEAD of the source branch and HEAD of the target branch.\n   This merge commit is written in `refs/merge-requests/:iid/merge` and does not change commit history of master branch.\n1. GitLab creates a pipeline on the merge commit, but this pipeline fails because the latest master changed a lint rule.\n1. A maintainer sees a failed pipeline in the merge request.\n\nAs you can see, the maintainer was able to hold off merging the dangerous MR\nbecause the latest pipeline on the MR didn't pass. The feature actually saved\nmaster from a broken state.\n\nAs a bonus, this workflow freeds developers from continual\nrebasing of their merge requests.\nAll they need to do is develop features with [Pipelines for Merged Results](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html).\nGitLab automatically creates an expected merge commit and validates the merge request prior to\nan actual merge.\n\n### How to get started with Pipelines for Merged Results\n\nYou can [start using this feature](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html#enabling-pipelines-for-merged-results)\ntoday, with just two steps:\n\n1. Edit the `.gitlab-ci.yml` config file to enable [pipelines for merge requests / merge request pipelines](https://docs.gitlab.com/ee/ci/merge_request_pipelines/).\n1. Enable the \"Merge pipelines will try to validate the post-merge result prior to merging\" option at **Settings > General > Merge requests** in your project.\n\n**Note:** If the configurations in your `.gitlab-ci.yml` file are too complex, you might stumble at the first point.\nWe're currently working on [improving the usability of pipelines for merge requests / merge request pipelines](https://gitlab.com/gitlab-org/gitlab-ce/issues/60085).\nPlease leave your feedback in the issue if that's the case.\n\n## How to avoid race condition of concurrent merges\n\nWith [Pipelines for Merged Results](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html),\nwe can confidently say that MRs are continually tested against the latest master branch.\nHowever, what if multiple MRs have been merged at the same time?\nFor example:\n\n- There are two merge requests: MR-1 and MR-2. The latest pipelines have already passed in both MRs.\n- John (maintainer) and Cathy (maintainer) merge MR-1 and MR-2 at the same time, respectively.\n\nLater on, it turns out that MR-2 contains a coding offence which has just been introduced by MR-1.\nMaintainers hit merge without knowing that, and\nneedless to say, this will result in broken master. How can we handle this race condition properly?\n\nIn [GitLab 12.1](/releases/2019/07/22/gitlab-12-1-released/#parallel-execution-strategy-for-merge-trains), we introduced a new feature,\n[Merge Trains](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/).\nBasically, a Merge Train is a queueing system that allows you to avoid this kind\nof race condition.\nAll you need to do is add merge requests to the merge train, and it\nhandles the rest of the work for you.\nIt creates merge commits according\nto the sequence of merge requests and runs pipelines on the expected merge commits.\nFor example, John and Cathy could have avoided broken master with the following workflow:\n\n1. John and Cathy add MR-1 and MR-2 to their [Merge Train](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/), respectively.\n1. In MR-1, the Merge Train creates an expected merge commit from HEAD of the source branch and HEAD of the target branch.\n   It creates a pipeline on the merge commit.\n1. In MR-2, the Merge Train creates an expected merge commit from HEAD of the source branch and the expected merge commit of MR-1.\n   It creates a pipeline on the merge commit.\n1. The pipeline in MR-1 passes all tests and merged into master branch.\n1. The pipeline in MR-2 fails because it violates a lint check which was changed by MR-1. MR-2 is dropped from the Merge Train.\n1. Developer revisits MR-2, fixes the coding offence, and asks Cathy to add it to the Merge Train again.\n\nAs you can see, the Merge Train successfully rejected MR-2 before it could break the master\nbranch. With this workflow, maintainers can feel more confident when they\ndecide to merge something. Also, this doesn't slow down development lifecycle\nthat pipelines are built on optimistic assumption that, in the above case,\nthe pipeline in MR-1 and the pipeline in MR-2 **start almost simultaneously**.\nMR-2 builds a merge commit as if MR-1 has already been merged, so that maintainers\ndon't need to wait for long time until each pipeline finished. If one of the\npipelines failed, the problematic merge request is dropped from the merge train\nand the train will be reconstructed without it.\n\n### How to get started with Merge Trains\n\nYou can [start using Merge Train](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.html#how-to-add-a-merge-request-to-a-merge-train)\ntoday, if you've already enabled [Pipelines for merged results](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/index.html#enabling-pipelines-for-merged-results). Click [\"Start/Add merge train\" button](https://docs.gitlab.com/ee/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.html#how-to-add-a-merge-request-to-a-merge-train) in merge requests.\n\n## A quick demonstration of Merge Trains\n\nHere is a demonstration video that explains the advantage of Merge Train feature.\nIn this video, we'll simulate the common problem in a workflow without\nMerge Trains, and later, we resolve the problem by enabling a Merge Train.\n\n\u003Cfigure class=\"video_container\">\n\u003Ciframe src=\"https://www.youtube.com/embed/D4qCqXgZkHQ\" frameborder=\"0\" allowfullscreen=\"true\">\n\u003C/iframe>\n\u003C/figure>\n\n## Wrap up\n\nRunning pipelines on expected merge commits allows us to predict what will happen\nin the future and avoid broken master proactively. It soothes the headache of\nrelease managers and gives maintainers and developers more confidence that their code\nis reliable enough to be merged and shipped. In addition, Merge Trains allow you\nto merge things safely without slowing down the development cycle.\n\nGive this advanced CI/CD feature a try today!\n\nFor more information, check out [the documentation on merge trains](https://docs.gitlab.com/ee/ci/pipelines/merge_trains.html) and [pipelines for merge requests / merge request pipelines](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html).\n\nCover image by [Dan Roizer](https://unsplash.com/@danny159) on [Unsplash](https://www.unsplash.com)\n{: .note}\n","engineering",[24,25,26,27],"CI/CD","demo","workflow","features",{"slug":29,"featured":6,"template":30},"how-to-avoid-broken-master-with-pipelines-for-merge-requests","BlogPost","content:en-us:blog:how-to-avoid-broken-master-with-pipelines-for-merge-requests.yml","yaml","How To Avoid Broken Master With Pipelines For Merge Requests","content","en-us/blog/how-to-avoid-broken-master-with-pipelines-for-merge-requests.yml","en-us/blog/how-to-avoid-broken-master-with-pipelines-for-merge-requests","yml",{"_path":39,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":41,"_id":462,"_type":32,"title":463,"_source":34,"_file":464,"_stem":465,"_extension":37},"/shared/en-us/main-navigation","en-us",{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":393,"minimal":424,"duo":443,"pricingDeployment":452},{"config":43},{"href":44,"dataGaName":45,"dataGaLocation":46},"/","gitlab logo","header",{"text":48,"config":49},"Get free trial",{"href":50,"dataGaName":51,"dataGaLocation":46},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":53,"config":54},"Talk to sales",{"href":55,"dataGaName":56,"dataGaLocation":46},"/sales/","sales",{"text":58,"config":59},"Sign in",{"href":60,"dataGaName":61,"dataGaLocation":46},"https://gitlab.com/users/sign_in/","sign in",[63,107,204,209,314,374],{"text":64,"config":65,"cards":67,"footer":90},"Platform",{"dataNavLevelOne":66},"platform",[68,74,82],{"title":64,"description":69,"link":70},"The most comprehensive AI-powered DevSecOps Platform",{"text":71,"config":72},"Explore our Platform",{"href":73,"dataGaName":66,"dataGaLocation":46},"/platform/",{"title":75,"description":76,"link":77},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":78,"config":79},"Meet GitLab Duo",{"href":80,"dataGaName":81,"dataGaLocation":46},"/gitlab-duo/","gitlab duo ai",{"title":83,"description":84,"link":85},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":86,"config":87},"Learn more",{"href":88,"dataGaName":89,"dataGaLocation":46},"/why-gitlab/","why gitlab",{"title":91,"items":92},"Get started with",[93,98,103],{"text":94,"config":95},"Platform Engineering",{"href":96,"dataGaName":97,"dataGaLocation":46},"/solutions/platform-engineering/","platform engineering",{"text":99,"config":100},"Developer Experience",{"href":101,"dataGaName":102,"dataGaLocation":46},"/developer-experience/","Developer experience",{"text":104,"config":105},"MLOps",{"href":106,"dataGaName":104,"dataGaLocation":46},"/topics/devops/the-role-of-ai-in-devops/",{"text":108,"left":109,"config":110,"link":112,"lists":116,"footer":186},"Product",true,{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"View all Solutions",{"href":115,"dataGaName":111,"dataGaLocation":46},"/solutions/",[117,141,165],{"title":118,"description":119,"link":120,"items":125},"Automation","CI/CD and automation to accelerate deployment",{"config":121},{"icon":122,"href":123,"dataGaName":124,"dataGaLocation":46},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[126,129,133,137],{"text":24,"config":127},{"href":128,"dataGaLocation":46,"dataGaName":24},"/solutions/continuous-integration/",{"text":130,"config":131},"AI-Assisted Development",{"href":80,"dataGaLocation":46,"dataGaName":132},"AI assisted development",{"text":134,"config":135},"Source Code Management",{"href":136,"dataGaLocation":46,"dataGaName":134},"/solutions/source-code-management/",{"text":138,"config":139},"Automated Software Delivery",{"href":123,"dataGaLocation":46,"dataGaName":140},"Automated software delivery",{"title":142,"description":143,"link":144,"items":149},"Security","Deliver code faster without compromising security",{"config":145},{"href":146,"dataGaName":147,"dataGaLocation":46,"icon":148},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[150,155,160],{"text":151,"config":152},"Application Security Testing",{"href":153,"dataGaName":154,"dataGaLocation":46},"/solutions/application-security-testing/","Application security testing",{"text":156,"config":157},"Software Supply Chain Security",{"href":158,"dataGaLocation":46,"dataGaName":159},"/solutions/supply-chain/","Software supply chain security",{"text":161,"config":162},"Software Compliance",{"href":163,"dataGaName":164,"dataGaLocation":46},"/solutions/software-compliance/","software compliance",{"title":166,"link":167,"items":172},"Measurement",{"config":168},{"icon":169,"href":170,"dataGaName":171,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[173,177,181],{"text":174,"config":175},"Visibility & Measurement",{"href":170,"dataGaLocation":46,"dataGaName":176},"Visibility and Measurement",{"text":178,"config":179},"Value Stream Management",{"href":180,"dataGaLocation":46,"dataGaName":178},"/solutions/value-stream-management/",{"text":182,"config":183},"Analytics & Insights",{"href":184,"dataGaLocation":46,"dataGaName":185},"/solutions/analytics-and-insights/","Analytics and insights",{"title":187,"items":188},"GitLab for",[189,194,199],{"text":190,"config":191},"Enterprise",{"href":192,"dataGaLocation":46,"dataGaName":193},"/enterprise/","enterprise",{"text":195,"config":196},"Small Business",{"href":197,"dataGaLocation":46,"dataGaName":198},"/small-business/","small business",{"text":200,"config":201},"Public Sector",{"href":202,"dataGaLocation":46,"dataGaName":203},"/solutions/public-sector/","public sector",{"text":205,"config":206},"Pricing",{"href":207,"dataGaName":208,"dataGaLocation":46,"dataNavLevelOne":208},"/pricing/","pricing",{"text":210,"config":211,"link":213,"lists":217,"feature":301},"Resources",{"dataNavLevelOne":212},"resources",{"text":214,"config":215},"View all resources",{"href":216,"dataGaName":212,"dataGaLocation":46},"/resources/",[218,251,273],{"title":219,"items":220},"Getting started",[221,226,231,236,241,246],{"text":222,"config":223},"Install",{"href":224,"dataGaName":225,"dataGaLocation":46},"/install/","install",{"text":227,"config":228},"Quick start guides",{"href":229,"dataGaName":230,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":232,"config":233},"Learn",{"href":234,"dataGaLocation":46,"dataGaName":235},"https://university.gitlab.com/","learn",{"text":237,"config":238},"Product documentation",{"href":239,"dataGaName":240,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":242,"config":243},"Best practice videos",{"href":244,"dataGaName":245,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":247,"config":248},"Integrations",{"href":249,"dataGaName":250,"dataGaLocation":46},"/integrations/","integrations",{"title":252,"items":253},"Discover",[254,259,263,268],{"text":255,"config":256},"Customer success stories",{"href":257,"dataGaName":258,"dataGaLocation":46},"/customers/","customer success stories",{"text":260,"config":261},"Blog",{"href":262,"dataGaName":5,"dataGaLocation":46},"/blog/",{"text":264,"config":265},"Remote",{"href":266,"dataGaName":267,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":269,"config":270},"TeamOps",{"href":271,"dataGaName":272,"dataGaLocation":46},"/teamops/","teamops",{"title":274,"items":275},"Connect",[276,281,286,291,296],{"text":277,"config":278},"GitLab Services",{"href":279,"dataGaName":280,"dataGaLocation":46},"/services/","services",{"text":282,"config":283},"Community",{"href":284,"dataGaName":285,"dataGaLocation":46},"/community/","community",{"text":287,"config":288},"Forum",{"href":289,"dataGaName":290,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":292,"config":293},"Events",{"href":294,"dataGaName":295,"dataGaLocation":46},"/events/","events",{"text":297,"config":298},"Partners",{"href":299,"dataGaName":300,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":302,"textColor":303,"text":304,"image":305,"link":309},"#2f2a6b","#fff","Insights for the future of software development",{"altText":306,"config":307},"the source promo card",{"src":308},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":310,"config":311},"Read the latest",{"href":312,"dataGaName":313,"dataGaLocation":46},"/the-source/","the source",{"text":315,"config":316,"lists":318},"Company",{"dataNavLevelOne":317},"company",[319],{"items":320},[321,326,332,334,339,344,349,354,359,364,369],{"text":322,"config":323},"About",{"href":324,"dataGaName":325,"dataGaLocation":46},"/company/","about",{"text":327,"config":328,"footerGa":331},"Jobs",{"href":329,"dataGaName":330,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":330},{"text":292,"config":333},{"href":294,"dataGaName":295,"dataGaLocation":46},{"text":335,"config":336},"Leadership",{"href":337,"dataGaName":338,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":340,"config":341},"Team",{"href":342,"dataGaName":343,"dataGaLocation":46},"/company/team/","team",{"text":345,"config":346},"Handbook",{"href":347,"dataGaName":348,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":350,"config":351},"Investor relations",{"href":352,"dataGaName":353,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":355,"config":356},"Trust Center",{"href":357,"dataGaName":358,"dataGaLocation":46},"/security/","trust center",{"text":360,"config":361},"AI Transparency Center",{"href":362,"dataGaName":363,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":365,"config":366},"Newsletter",{"href":367,"dataGaName":368,"dataGaLocation":46},"/company/contact/","newsletter",{"text":370,"config":371},"Press",{"href":372,"dataGaName":373,"dataGaLocation":46},"/press/","press",{"text":375,"config":376,"lists":377},"Contact us",{"dataNavLevelOne":317},[378],{"items":379},[380,383,388],{"text":53,"config":381},{"href":55,"dataGaName":382,"dataGaLocation":46},"talk to sales",{"text":384,"config":385},"Get help",{"href":386,"dataGaName":387,"dataGaLocation":46},"/support/","get help",{"text":389,"config":390},"Customer portal",{"href":391,"dataGaName":392,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":394,"login":395,"suggestions":402},"Close",{"text":396,"link":397},"To search repositories and projects, login to",{"text":398,"config":399},"gitlab.com",{"href":60,"dataGaName":400,"dataGaLocation":401},"search login","search",{"text":403,"default":404},"Suggestions",[405,407,411,413,417,421],{"text":75,"config":406},{"href":80,"dataGaName":75,"dataGaLocation":401},{"text":408,"config":409},"Code Suggestions (AI)",{"href":410,"dataGaName":408,"dataGaLocation":401},"/solutions/code-suggestions/",{"text":24,"config":412},{"href":128,"dataGaName":24,"dataGaLocation":401},{"text":414,"config":415},"GitLab on AWS",{"href":416,"dataGaName":414,"dataGaLocation":401},"/partners/technology-partners/aws/",{"text":418,"config":419},"GitLab on Google Cloud",{"href":420,"dataGaName":418,"dataGaLocation":401},"/partners/technology-partners/google-cloud-platform/",{"text":422,"config":423},"Why GitLab?",{"href":88,"dataGaName":422,"dataGaLocation":401},{"freeTrial":425,"mobileIcon":430,"desktopIcon":435,"secondaryButton":438},{"text":426,"config":427},"Start free trial",{"href":428,"dataGaName":51,"dataGaLocation":429},"https://gitlab.com/-/trials/new/","nav",{"altText":431,"config":432},"Gitlab Icon",{"src":433,"dataGaName":434,"dataGaLocation":429},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":431,"config":436},{"src":437,"dataGaName":434,"dataGaLocation":429},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":439,"config":440},"Get Started",{"href":441,"dataGaName":442,"dataGaLocation":429},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":444,"mobileIcon":448,"desktopIcon":450},{"text":445,"config":446},"Learn more about GitLab Duo",{"href":80,"dataGaName":447,"dataGaLocation":429},"gitlab duo",{"altText":431,"config":449},{"src":433,"dataGaName":434,"dataGaLocation":429},{"altText":431,"config":451},{"src":437,"dataGaName":434,"dataGaLocation":429},{"freeTrial":453,"mobileIcon":458,"desktopIcon":460},{"text":454,"config":455},"Back to pricing",{"href":207,"dataGaName":456,"dataGaLocation":429,"icon":457},"back to pricing","GoBack",{"altText":431,"config":459},{"src":433,"dataGaName":434,"dataGaLocation":429},{"altText":431,"config":461},{"src":437,"dataGaName":434,"dataGaLocation":429},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":467,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"title":468,"button":469,"image":474,"config":478,"_id":480,"_type":32,"_source":34,"_file":481,"_stem":482,"_extension":37},"/shared/en-us/banner","is now in public beta!",{"text":470,"config":471},"Try the Beta",{"href":472,"dataGaName":473,"dataGaLocation":46},"/gitlab-duo/agent-platform/","duo banner",{"altText":475,"config":476},"GitLab Duo Agent Platform",{"src":477},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":479},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":484,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":485,"_id":689,"_type":32,"title":690,"_source":34,"_file":691,"_stem":692,"_extension":37},"/shared/en-us/main-footer",{"text":486,"source":487,"edit":493,"contribute":498,"config":503,"items":508,"minimal":681},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":488,"config":489},"View page source",{"href":490,"dataGaName":491,"dataGaLocation":492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":494,"config":495},"Edit this page",{"href":496,"dataGaName":497,"dataGaLocation":492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":499,"config":500},"Please contribute",{"href":501,"dataGaName":502,"dataGaLocation":492},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":504,"facebook":505,"youtube":506,"linkedin":507},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[509,532,588,617,651],{"title":64,"links":510,"subMenu":515},[511],{"text":512,"config":513},"DevSecOps platform",{"href":73,"dataGaName":514,"dataGaLocation":492},"devsecops platform",[516],{"title":205,"links":517},[518,522,527],{"text":519,"config":520},"View plans",{"href":207,"dataGaName":521,"dataGaLocation":492},"view plans",{"text":523,"config":524},"Why Premium?",{"href":525,"dataGaName":526,"dataGaLocation":492},"/pricing/premium/","why premium",{"text":528,"config":529},"Why Ultimate?",{"href":530,"dataGaName":531,"dataGaLocation":492},"/pricing/ultimate/","why ultimate",{"title":533,"links":534},"Solutions",[535,540,542,544,549,554,558,561,565,570,572,575,578,583],{"text":536,"config":537},"Digital transformation",{"href":538,"dataGaName":539,"dataGaLocation":492},"/topics/digital-transformation/","digital transformation",{"text":151,"config":541},{"href":153,"dataGaName":151,"dataGaLocation":492},{"text":140,"config":543},{"href":123,"dataGaName":124,"dataGaLocation":492},{"text":545,"config":546},"Agile development",{"href":547,"dataGaName":548,"dataGaLocation":492},"/solutions/agile-delivery/","agile delivery",{"text":550,"config":551},"Cloud transformation",{"href":552,"dataGaName":553,"dataGaLocation":492},"/topics/cloud-native/","cloud transformation",{"text":555,"config":556},"SCM",{"href":136,"dataGaName":557,"dataGaLocation":492},"source code management",{"text":24,"config":559},{"href":128,"dataGaName":560,"dataGaLocation":492},"continuous integration & delivery",{"text":562,"config":563},"Value stream management",{"href":180,"dataGaName":564,"dataGaLocation":492},"value stream management",{"text":566,"config":567},"GitOps",{"href":568,"dataGaName":569,"dataGaLocation":492},"/solutions/gitops/","gitops",{"text":190,"config":571},{"href":192,"dataGaName":193,"dataGaLocation":492},{"text":573,"config":574},"Small business",{"href":197,"dataGaName":198,"dataGaLocation":492},{"text":576,"config":577},"Public sector",{"href":202,"dataGaName":203,"dataGaLocation":492},{"text":579,"config":580},"Education",{"href":581,"dataGaName":582,"dataGaLocation":492},"/solutions/education/","education",{"text":584,"config":585},"Financial services",{"href":586,"dataGaName":587,"dataGaLocation":492},"/solutions/finance/","financial services",{"title":210,"links":589},[590,592,594,596,599,601,603,605,607,609,611,613,615],{"text":222,"config":591},{"href":224,"dataGaName":225,"dataGaLocation":492},{"text":227,"config":593},{"href":229,"dataGaName":230,"dataGaLocation":492},{"text":232,"config":595},{"href":234,"dataGaName":235,"dataGaLocation":492},{"text":237,"config":597},{"href":239,"dataGaName":598,"dataGaLocation":492},"docs",{"text":260,"config":600},{"href":262,"dataGaName":5,"dataGaLocation":492},{"text":255,"config":602},{"href":257,"dataGaName":258,"dataGaLocation":492},{"text":264,"config":604},{"href":266,"dataGaName":267,"dataGaLocation":492},{"text":277,"config":606},{"href":279,"dataGaName":280,"dataGaLocation":492},{"text":269,"config":608},{"href":271,"dataGaName":272,"dataGaLocation":492},{"text":282,"config":610},{"href":284,"dataGaName":285,"dataGaLocation":492},{"text":287,"config":612},{"href":289,"dataGaName":290,"dataGaLocation":492},{"text":292,"config":614},{"href":294,"dataGaName":295,"dataGaLocation":492},{"text":297,"config":616},{"href":299,"dataGaName":300,"dataGaLocation":492},{"title":315,"links":618},[619,621,623,625,627,629,631,635,640,642,644,646],{"text":322,"config":620},{"href":324,"dataGaName":317,"dataGaLocation":492},{"text":327,"config":622},{"href":329,"dataGaName":330,"dataGaLocation":492},{"text":335,"config":624},{"href":337,"dataGaName":338,"dataGaLocation":492},{"text":340,"config":626},{"href":342,"dataGaName":343,"dataGaLocation":492},{"text":345,"config":628},{"href":347,"dataGaName":348,"dataGaLocation":492},{"text":350,"config":630},{"href":352,"dataGaName":353,"dataGaLocation":492},{"text":632,"config":633},"Sustainability",{"href":634,"dataGaName":632,"dataGaLocation":492},"/sustainability/",{"text":636,"config":637},"Diversity, inclusion and belonging (DIB)",{"href":638,"dataGaName":639,"dataGaLocation":492},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":355,"config":641},{"href":357,"dataGaName":358,"dataGaLocation":492},{"text":365,"config":643},{"href":367,"dataGaName":368,"dataGaLocation":492},{"text":370,"config":645},{"href":372,"dataGaName":373,"dataGaLocation":492},{"text":647,"config":648},"Modern Slavery Transparency Statement",{"href":649,"dataGaName":650,"dataGaLocation":492},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":652,"links":653},"Contact Us",[654,657,659,661,666,671,676],{"text":655,"config":656},"Contact an expert",{"href":55,"dataGaName":56,"dataGaLocation":492},{"text":384,"config":658},{"href":386,"dataGaName":387,"dataGaLocation":492},{"text":389,"config":660},{"href":391,"dataGaName":392,"dataGaLocation":492},{"text":662,"config":663},"Status",{"href":664,"dataGaName":665,"dataGaLocation":492},"https://status.gitlab.com/","status",{"text":667,"config":668},"Terms of use",{"href":669,"dataGaName":670,"dataGaLocation":492},"/terms/","terms of use",{"text":672,"config":673},"Privacy statement",{"href":674,"dataGaName":675,"dataGaLocation":492},"/privacy/","privacy statement",{"text":677,"config":678},"Cookie preferences",{"dataGaName":679,"dataGaLocation":492,"id":680,"isOneTrustButton":109},"cookie preferences","ot-sdk-btn",{"items":682},[683,685,687],{"text":667,"config":684},{"href":669,"dataGaName":670,"dataGaLocation":492},{"text":672,"config":686},{"href":674,"dataGaName":675,"dataGaLocation":492},{"text":677,"config":688},{"dataGaName":679,"dataGaLocation":492,"id":680,"isOneTrustButton":109},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[694],{"_path":695,"_dir":696,"_draft":6,"_partial":6,"_locale":7,"content":697,"config":700,"_id":702,"_type":32,"title":19,"_source":34,"_file":703,"_stem":704,"_extension":37},"/en-us/blog/authors/shinya-maeda","authors",{"name":19,"config":698},{"headshot":7,"ctfId":699},"dosuken123",{"template":701},"BlogAuthor","content:en-us:blog:authors:shinya-maeda.yml","en-us/blog/authors/shinya-maeda.yml","en-us/blog/authors/shinya-maeda",{"_path":706,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"header":707,"eyebrow":708,"blurb":709,"button":710,"secondaryButton":714,"_id":716,"_type":32,"title":717,"_source":34,"_file":718,"_stem":719,"_extension":37},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":48,"config":711},{"href":712,"dataGaName":51,"dataGaLocation":713},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":53,"config":715},{"href":55,"dataGaName":56,"dataGaLocation":713},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326256891]