[{"data":1,"prerenderedAt":758},["ShallowReactive",2],{"/en-us/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way":3,"navigation-en-us":35,"banner-en-us":462,"footer-en-us":479,"Sam Morris":724,"next-steps-en-us":737,"footer-source-/en-us/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way/":752},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":25,"_id":28,"_type":29,"title":30,"_source":31,"_file":32,"_stem":33,"_extension":34},"/en-us/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Building a GitLab CI/CD pipeline for a monorepo the easy way","Learn how to create a GitLab CI/CD pipeline for a monorepo to host multiple applications in one repository.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660151/Blog/Hero%20Images/blog-image-template-1800x945__26_.png","https://about.gitlab.com/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Building a GitLab CI/CD pipeline for a monorepo the easy way\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Sam Morris\"}],\n        \"datePublished\": \"2024-07-30\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Sam Morris","2024-07-30","Monorepos allow you to host multiple applications’ code in a single\nrepository. In GitLab, that involves placing disparate application source\ncode in separate directories in one project. While this strategy allows for\nversion controlled storage of your code, it was tricky leveraging the full\npower of GitLab’s [CI/CD](https://about.gitlab.com/topics/ci-cd/) pipeline\ncapabilities… until now!\n\n\n## The ideal case: CI/CD in a monorepo\n\n\nSince you have more than one application’s code living in your repository,\nyou will want to have more than one pipeline configuration. For example, if\nyou have a .NET application and a Spring application in one project, each\napplication may have different build and test jobs to complete. Ideally, you\ncan completely decouple the pipelines and only run each pipeline based on\nchanges to that specific application’s source code.\n\n\nThe technical approach for this would be to have a project-level\n`.gitlab-ci.yml` pipeline configuration file that includes a specific YAML\nfile based on changes in a certain directory. The `.gitlab-ci.yml` pipeline\nserves as the control plane that triggers the appropriate pipeline based on\nthe changes made to the code.\n\n\n## The legacy approach\n\n\nPrior to GitLab 16.4, we were not able to include a YAML file based on\nchanges to a directory or file in a project. However, we could accomplish\nthis functionality via a workaround. \n\n\nIn our monorepo project, we have two directories for different applications.\nIn this example, there are `java` and `python` directories representing a\nJava and Python app, respectively. Each directory has an\napplication-specific YAML file to build each app. In the project’s pipeline\nfile, we simply include both application pipeline files, and do the logic\nhandling in those files directly.\n\n\n`.gitlab-ci.yml`:\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\ntop-level-job:\n  stage: build\n  script:\n    - echo \"Hello world...\"\n\ninclude:\n  - local: '/java/j.gitlab-ci.yml'\n  - local: '/python/py.gitlab-ci.yml'\n\n```\n\n\nIn each application-specific pipeline file, we create a hidden job named\n.java-common or .python-common that only runs if there are changes to that\napp’s directory. [Hidden\njobs](https://docs.gitlab.com/ee/ci/jobs/#hide-jobs) do not run by default,\nand are often utilized to reuse specific job configurations. Each pipeline\nextends that hidden job to inherit the rules defining which files to watch\nfor changes, which would then initiate the pipeline job. \n\n\n`j.gitlab-ci.yml`:\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\n.java-common:\n  rules:\n    - changes:\n      - '../java/*'\n\njava-build-job:\n  extends: .java-common\n  stage: build\n  script:\n    - echo \"Building Java\"\n\njava-test-job:\n  extends: .java-common\n  stage: test\n  script:\n    - echo \"Testing Java\"\n\n```\n\n\n`py.gitlab-ci.yml`:\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\n.python-common:\n  rules:\n    - changes:\n      - '../python/*'\n\npython-build-job:\n  extends: .python-common\n  stage: build\n  script:\n    - echo \"Building Python\"\n\npython-test-job:\n  extends: .python-common\n  stage: test\n  script:\n    - echo \"Testing Python\"\n\n```\n\n\nThere are some downsides to this, including having to extend the job for\neach other job in the YAML file to ensure it complies with the rules,\ncreating a lot of redundant code and room for human error. Additionally,\nextended jobs cannot have duplicate keys, so you could not define your own\n`rules` logic in each job since there would be a collision in the keys and\ntheir [values are not\nmerged](https://docs.gitlab.com/ee/ci/yaml/index.html#extends). \n\n\nThis results in a pipeline running that includes the j.gitlab-ci.yml jobs\nwhen `java/` is updated, and py.gitlab-ci.yml when `python/` is updated. \n\n\n## The new approach: Conditionally include pipeline files\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/6phvk8jioAo?si=y6ztZODvUtM-cHmZ\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\nIn GitLab 16.4, we introduced [`include` with `rules:changes` for\npipelines](https://docs.gitlab.com/ee/ci/yaml/includes.html#include-with-ruleschanges).\nPreviously, you could `include` with `rules:if`, but not `rules:changes`\nmaking this update extremely powerful. Now, you can simply use the `include`\nkeyword and define the monorepo rules in your project pipeline\nconfiguration. \n\n\nNew `.gitlab-ci.yml`:\n\n\n```\n\nstages:\n  - build\n  - test\n\ntop-level-job:\n  stage: build\n  script:\n    - echo \"Hello world...\"\n\ninclude:\n  - local: '/java/j.gitlab-ci.yml'\n    rules:\n      - changes:\n        - 'java/*'\n  - local: '/python/py.gitlab-ci.yml'\n    rules:\n      - changes:\n        - 'python/*'\n\n```\n\n\nThen each application’s YAML can just focus on building and testing that\napplication’s code, without extending a hidden job repeatedly. This allows\nfor more flexibility in job definitions and reduces code rewriting for\nengineers.\n\n\nNew `j.gitlab-ci.yml`:\n\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\njava-build-job:\n  stage: build\n  script:\n    - echo \"Building Java\"\n\njava-test-job:\n  stage: test\n  script:\n    - echo \"Testing Java\"\n\n```\n\n\nNew `py.gitlab-ci.yml`:\n\n```\n\nstages:\n  - build\n  - test\n  - deploy\n\npython-build-job:\n  stage: build\n  script:\n    - echo \"Building Python\"\n\npython-test-job:\n  stage: test\n  script:\n    - echo \"Testing Python\"\n\n```\n\n\nThis accomplishes the same task of including the Java and Python jobs only\nwhen their directories are modified. Something to consider in your\nimplementation is that [jobs can run unexpectedly when using\n`changes`](https://docs.gitlab.com/ee/ci/jobs/job_troubleshooting.html#jobs-or-pipelines-run-unexpectedly-when-using-changes).\nThe changes rule always evaluates to true when pushing a new branch or a new\ntag to GitLab, so all jobs included will run upon first push to a branch\nregardless of the `rules:changes` definition. You can mitigate this\nexperience by creating your feature branch first and then opening a merge\nrequest to begin your development, since the first push to the branch when\nit is created will force all jobs to run.\n\n\nUltimately, monorepos are a strategy that can be used with GitLab and CI/CD,\nand, with our new `include` with `rules:changes` feature, we have a better\nbest practice for using GitLab CI with monorepos. To get started with\nmonorepos, take out a free Gitlab Ultimate trial today.\n\n\n## More CI/CD resources\n\n\n* [5 tips for managing monorepos in\nGitLab](https://about.gitlab.com/blog/tips-for-managing-monorepos-in-gitlab/)\n\n* [How to learn CI/CD\nfast](https://about.gitlab.com/blog/how-to-learn-ci-cd-fast/)\n","engineering",[23,24],"CI/CD","tutorial",{"slug":26,"featured":6,"template":27},"building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","BlogPost","content:en-us:blog:building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way.yml","yaml","Building A Gitlab Ci Cd Pipeline For A Monorepo The Easy Way","content","en-us/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way.yml","en-us/blog/building-a-gitlab-ci-cd-pipeline-for-a-monorepo-the-easy-way","yml",{"_path":36,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":38,"_id":458,"_type":29,"title":459,"_source":31,"_file":460,"_stem":461,"_extension":34},"/shared/en-us/main-navigation","en-us",{"logo":39,"freeTrial":44,"sales":49,"login":54,"items":59,"search":389,"minimal":420,"duo":439,"pricingDeployment":448},{"config":40},{"href":41,"dataGaName":42,"dataGaLocation":43},"/","gitlab logo","header",{"text":45,"config":46},"Get free trial",{"href":47,"dataGaName":48,"dataGaLocation":43},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":50,"config":51},"Talk to sales",{"href":52,"dataGaName":53,"dataGaLocation":43},"/sales/","sales",{"text":55,"config":56},"Sign in",{"href":57,"dataGaName":58,"dataGaLocation":43},"https://gitlab.com/users/sign_in/","sign in",[60,104,200,205,310,370],{"text":61,"config":62,"cards":64,"footer":87},"Platform",{"dataNavLevelOne":63},"platform",[65,71,79],{"title":61,"description":66,"link":67},"The most comprehensive AI-powered DevSecOps Platform",{"text":68,"config":69},"Explore our Platform",{"href":70,"dataGaName":63,"dataGaLocation":43},"/platform/",{"title":72,"description":73,"link":74},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":75,"config":76},"Meet GitLab Duo",{"href":77,"dataGaName":78,"dataGaLocation":43},"/gitlab-duo/","gitlab duo ai",{"title":80,"description":81,"link":82},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":83,"config":84},"Learn more",{"href":85,"dataGaName":86,"dataGaLocation":43},"/why-gitlab/","why gitlab",{"title":88,"items":89},"Get started with",[90,95,100],{"text":91,"config":92},"Platform Engineering",{"href":93,"dataGaName":94,"dataGaLocation":43},"/solutions/platform-engineering/","platform engineering",{"text":96,"config":97},"Developer Experience",{"href":98,"dataGaName":99,"dataGaLocation":43},"/developer-experience/","Developer experience",{"text":101,"config":102},"MLOps",{"href":103,"dataGaName":101,"dataGaLocation":43},"/topics/devops/the-role-of-ai-in-devops/",{"text":105,"left":106,"config":107,"link":109,"lists":113,"footer":182},"Product",true,{"dataNavLevelOne":108},"solutions",{"text":110,"config":111},"View all Solutions",{"href":112,"dataGaName":108,"dataGaLocation":43},"/solutions/",[114,138,161],{"title":115,"description":116,"link":117,"items":122},"Automation","CI/CD and automation to accelerate deployment",{"config":118},{"icon":119,"href":120,"dataGaName":121,"dataGaLocation":43},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[123,126,130,134],{"text":23,"config":124},{"href":125,"dataGaLocation":43,"dataGaName":23},"/solutions/continuous-integration/",{"text":127,"config":128},"AI-Assisted Development",{"href":77,"dataGaLocation":43,"dataGaName":129},"AI assisted development",{"text":131,"config":132},"Source Code Management",{"href":133,"dataGaLocation":43,"dataGaName":131},"/solutions/source-code-management/",{"text":135,"config":136},"Automated Software Delivery",{"href":120,"dataGaLocation":43,"dataGaName":137},"Automated software delivery",{"title":139,"description":140,"link":141,"items":146},"Security","Deliver code faster without compromising security",{"config":142},{"href":143,"dataGaName":144,"dataGaLocation":43,"icon":145},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[147,151,156],{"text":148,"config":149},"Application Security Testing",{"href":143,"dataGaName":150,"dataGaLocation":43},"Application security testing",{"text":152,"config":153},"Software Supply Chain Security",{"href":154,"dataGaLocation":43,"dataGaName":155},"/solutions/supply-chain/","Software supply chain security",{"text":157,"config":158},"Software Compliance",{"href":159,"dataGaName":160,"dataGaLocation":43},"/solutions/software-compliance/","software compliance",{"title":162,"link":163,"items":168},"Measurement",{"config":164},{"icon":165,"href":166,"dataGaName":167,"dataGaLocation":43},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[169,173,177],{"text":170,"config":171},"Visibility & Measurement",{"href":166,"dataGaLocation":43,"dataGaName":172},"Visibility and Measurement",{"text":174,"config":175},"Value Stream Management",{"href":176,"dataGaLocation":43,"dataGaName":174},"/solutions/value-stream-management/",{"text":178,"config":179},"Analytics & Insights",{"href":180,"dataGaLocation":43,"dataGaName":181},"/solutions/analytics-and-insights/","Analytics and insights",{"title":183,"items":184},"GitLab for",[185,190,195],{"text":186,"config":187},"Enterprise",{"href":188,"dataGaLocation":43,"dataGaName":189},"/enterprise/","enterprise",{"text":191,"config":192},"Small Business",{"href":193,"dataGaLocation":43,"dataGaName":194},"/small-business/","small business",{"text":196,"config":197},"Public Sector",{"href":198,"dataGaLocation":43,"dataGaName":199},"/solutions/public-sector/","public sector",{"text":201,"config":202},"Pricing",{"href":203,"dataGaName":204,"dataGaLocation":43,"dataNavLevelOne":204},"/pricing/","pricing",{"text":206,"config":207,"link":209,"lists":213,"feature":297},"Resources",{"dataNavLevelOne":208},"resources",{"text":210,"config":211},"View all resources",{"href":212,"dataGaName":208,"dataGaLocation":43},"/resources/",[214,247,269],{"title":215,"items":216},"Getting started",[217,222,227,232,237,242],{"text":218,"config":219},"Install",{"href":220,"dataGaName":221,"dataGaLocation":43},"/install/","install",{"text":223,"config":224},"Quick start guides",{"href":225,"dataGaName":226,"dataGaLocation":43},"/get-started/","quick setup checklists",{"text":228,"config":229},"Learn",{"href":230,"dataGaLocation":43,"dataGaName":231},"https://university.gitlab.com/","learn",{"text":233,"config":234},"Product documentation",{"href":235,"dataGaName":236,"dataGaLocation":43},"https://docs.gitlab.com/","product documentation",{"text":238,"config":239},"Best practice videos",{"href":240,"dataGaName":241,"dataGaLocation":43},"/getting-started-videos/","best practice videos",{"text":243,"config":244},"Integrations",{"href":245,"dataGaName":246,"dataGaLocation":43},"/integrations/","integrations",{"title":248,"items":249},"Discover",[250,255,259,264],{"text":251,"config":252},"Customer success stories",{"href":253,"dataGaName":254,"dataGaLocation":43},"/customers/","customer success stories",{"text":256,"config":257},"Blog",{"href":258,"dataGaName":5,"dataGaLocation":43},"/blog/",{"text":260,"config":261},"Remote",{"href":262,"dataGaName":263,"dataGaLocation":43},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":265,"config":266},"TeamOps",{"href":267,"dataGaName":268,"dataGaLocation":43},"/teamops/","teamops",{"title":270,"items":271},"Connect",[272,277,282,287,292],{"text":273,"config":274},"GitLab Services",{"href":275,"dataGaName":276,"dataGaLocation":43},"/services/","services",{"text":278,"config":279},"Community",{"href":280,"dataGaName":281,"dataGaLocation":43},"/community/","community",{"text":283,"config":284},"Forum",{"href":285,"dataGaName":286,"dataGaLocation":43},"https://forum.gitlab.com/","forum",{"text":288,"config":289},"Events",{"href":290,"dataGaName":291,"dataGaLocation":43},"/events/","events",{"text":293,"config":294},"Partners",{"href":295,"dataGaName":296,"dataGaLocation":43},"/partners/","partners",{"backgroundColor":298,"textColor":299,"text":300,"image":301,"link":305},"#2f2a6b","#fff","Insights for the future of software development",{"altText":302,"config":303},"the source promo card",{"src":304},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":306,"config":307},"Read the latest",{"href":308,"dataGaName":309,"dataGaLocation":43},"/the-source/","the source",{"text":311,"config":312,"lists":314},"Company",{"dataNavLevelOne":313},"company",[315],{"items":316},[317,322,328,330,335,340,345,350,355,360,365],{"text":318,"config":319},"About",{"href":320,"dataGaName":321,"dataGaLocation":43},"/company/","about",{"text":323,"config":324,"footerGa":327},"Jobs",{"href":325,"dataGaName":326,"dataGaLocation":43},"/jobs/","jobs",{"dataGaName":326},{"text":288,"config":329},{"href":290,"dataGaName":291,"dataGaLocation":43},{"text":331,"config":332},"Leadership",{"href":333,"dataGaName":334,"dataGaLocation":43},"/company/team/e-group/","leadership",{"text":336,"config":337},"Team",{"href":338,"dataGaName":339,"dataGaLocation":43},"/company/team/","team",{"text":341,"config":342},"Handbook",{"href":343,"dataGaName":344,"dataGaLocation":43},"https://handbook.gitlab.com/","handbook",{"text":346,"config":347},"Investor relations",{"href":348,"dataGaName":349,"dataGaLocation":43},"https://ir.gitlab.com/","investor relations",{"text":351,"config":352},"Trust Center",{"href":353,"dataGaName":354,"dataGaLocation":43},"/security/","trust center",{"text":356,"config":357},"AI Transparency Center",{"href":358,"dataGaName":359,"dataGaLocation":43},"/ai-transparency-center/","ai transparency center",{"text":361,"config":362},"Newsletter",{"href":363,"dataGaName":364,"dataGaLocation":43},"/company/contact/","newsletter",{"text":366,"config":367},"Press",{"href":368,"dataGaName":369,"dataGaLocation":43},"/press/","press",{"text":371,"config":372,"lists":373},"Contact us",{"dataNavLevelOne":313},[374],{"items":375},[376,379,384],{"text":50,"config":377},{"href":52,"dataGaName":378,"dataGaLocation":43},"talk to sales",{"text":380,"config":381},"Support portal",{"href":382,"dataGaName":383,"dataGaLocation":43},"https://support.gitlab.com","support portal",{"text":385,"config":386},"Customer portal",{"href":387,"dataGaName":388,"dataGaLocation":43},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":390,"login":391,"suggestions":398},"Close",{"text":392,"link":393},"To search repositories and projects, login to",{"text":394,"config":395},"gitlab.com",{"href":57,"dataGaName":396,"dataGaLocation":397},"search login","search",{"text":399,"default":400},"Suggestions",[401,403,407,409,413,417],{"text":72,"config":402},{"href":77,"dataGaName":72,"dataGaLocation":397},{"text":404,"config":405},"Code Suggestions (AI)",{"href":406,"dataGaName":404,"dataGaLocation":397},"/solutions/code-suggestions/",{"text":23,"config":408},{"href":125,"dataGaName":23,"dataGaLocation":397},{"text":410,"config":411},"GitLab on AWS",{"href":412,"dataGaName":410,"dataGaLocation":397},"/partners/technology-partners/aws/",{"text":414,"config":415},"GitLab on Google Cloud",{"href":416,"dataGaName":414,"dataGaLocation":397},"/partners/technology-partners/google-cloud-platform/",{"text":418,"config":419},"Why GitLab?",{"href":85,"dataGaName":418,"dataGaLocation":397},{"freeTrial":421,"mobileIcon":426,"desktopIcon":431,"secondaryButton":434},{"text":422,"config":423},"Start free trial",{"href":424,"dataGaName":48,"dataGaLocation":425},"https://gitlab.com/-/trials/new/","nav",{"altText":427,"config":428},"Gitlab Icon",{"src":429,"dataGaName":430,"dataGaLocation":425},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":427,"config":432},{"src":433,"dataGaName":430,"dataGaLocation":425},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":435,"config":436},"Get Started",{"href":437,"dataGaName":438,"dataGaLocation":425},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":440,"mobileIcon":444,"desktopIcon":446},{"text":441,"config":442},"Learn more about GitLab Duo",{"href":77,"dataGaName":443,"dataGaLocation":425},"gitlab duo",{"altText":427,"config":445},{"src":429,"dataGaName":430,"dataGaLocation":425},{"altText":427,"config":447},{"src":433,"dataGaName":430,"dataGaLocation":425},{"freeTrial":449,"mobileIcon":454,"desktopIcon":456},{"text":450,"config":451},"Back to pricing",{"href":203,"dataGaName":452,"dataGaLocation":425,"icon":453},"back to pricing","GoBack",{"altText":427,"config":455},{"src":429,"dataGaName":430,"dataGaLocation":425},{"altText":427,"config":457},{"src":433,"dataGaName":430,"dataGaLocation":425},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":463,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"title":464,"button":465,"image":470,"config":474,"_id":476,"_type":29,"_source":31,"_file":477,"_stem":478,"_extension":34},"/shared/en-us/banner","is now in public beta!",{"text":466,"config":467},"Try the Beta",{"href":468,"dataGaName":469,"dataGaLocation":43},"/gitlab-duo/agent-platform/","duo banner",{"altText":471,"config":472},"GitLab Duo Agent Platform",{"src":473},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":475},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":480,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"data":481,"_id":720,"_type":29,"title":721,"_source":31,"_file":722,"_stem":723,"_extension":34},"/shared/en-us/main-footer",{"text":482,"source":483,"edit":489,"contribute":494,"config":499,"items":504,"minimal":712},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":484,"config":485},"View page source",{"href":486,"dataGaName":487,"dataGaLocation":488},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":490,"config":491},"Edit this page",{"href":492,"dataGaName":493,"dataGaLocation":488},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":495,"config":496},"Please contribute",{"href":497,"dataGaName":498,"dataGaLocation":488},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":500,"facebook":501,"youtube":502,"linkedin":503},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[505,552,605,649,678],{"title":201,"links":506,"subMenu":521},[507,511,516],{"text":508,"config":509},"View plans",{"href":203,"dataGaName":510,"dataGaLocation":488},"view plans",{"text":512,"config":513},"Why Premium?",{"href":514,"dataGaName":515,"dataGaLocation":488},"/pricing/premium/","why premium",{"text":517,"config":518},"Why Ultimate?",{"href":519,"dataGaName":520,"dataGaLocation":488},"/pricing/ultimate/","why ultimate",[522],{"title":523,"links":524},"Contact Us",[525,528,530,532,537,542,547],{"text":526,"config":527},"Contact sales",{"href":52,"dataGaName":53,"dataGaLocation":488},{"text":380,"config":529},{"href":382,"dataGaName":383,"dataGaLocation":488},{"text":385,"config":531},{"href":387,"dataGaName":388,"dataGaLocation":488},{"text":533,"config":534},"Status",{"href":535,"dataGaName":536,"dataGaLocation":488},"https://status.gitlab.com/","status",{"text":538,"config":539},"Terms of use",{"href":540,"dataGaName":541,"dataGaLocation":488},"/terms/","terms of use",{"text":543,"config":544},"Privacy statement",{"href":545,"dataGaName":546,"dataGaLocation":488},"/privacy/","privacy statement",{"text":548,"config":549},"Cookie preferences",{"dataGaName":550,"dataGaLocation":488,"id":551,"isOneTrustButton":106},"cookie preferences","ot-sdk-btn",{"title":105,"links":553,"subMenu":561},[554,558],{"text":555,"config":556},"DevSecOps platform",{"href":70,"dataGaName":557,"dataGaLocation":488},"devsecops platform",{"text":127,"config":559},{"href":77,"dataGaName":560,"dataGaLocation":488},"ai-assisted development",[562],{"title":563,"links":564},"Topics",[565,570,575,580,585,590,595,600],{"text":566,"config":567},"CICD",{"href":568,"dataGaName":569,"dataGaLocation":488},"/topics/ci-cd/","cicd",{"text":571,"config":572},"GitOps",{"href":573,"dataGaName":574,"dataGaLocation":488},"/topics/gitops/","gitops",{"text":576,"config":577},"DevOps",{"href":578,"dataGaName":579,"dataGaLocation":488},"/topics/devops/","devops",{"text":581,"config":582},"Version Control",{"href":583,"dataGaName":584,"dataGaLocation":488},"/topics/version-control/","version control",{"text":586,"config":587},"DevSecOps",{"href":588,"dataGaName":589,"dataGaLocation":488},"/topics/devsecops/","devsecops",{"text":591,"config":592},"Cloud Native",{"href":593,"dataGaName":594,"dataGaLocation":488},"/topics/cloud-native/","cloud native",{"text":596,"config":597},"AI for Coding",{"href":598,"dataGaName":599,"dataGaLocation":488},"/topics/devops/ai-for-coding/","ai for coding",{"text":601,"config":602},"Agentic AI",{"href":603,"dataGaName":604,"dataGaLocation":488},"/topics/agentic-ai/","agentic ai",{"title":606,"links":607},"Solutions",[608,610,612,617,621,624,628,631,633,636,639,644],{"text":148,"config":609},{"href":143,"dataGaName":148,"dataGaLocation":488},{"text":137,"config":611},{"href":120,"dataGaName":121,"dataGaLocation":488},{"text":613,"config":614},"Agile development",{"href":615,"dataGaName":616,"dataGaLocation":488},"/solutions/agile-delivery/","agile delivery",{"text":618,"config":619},"SCM",{"href":133,"dataGaName":620,"dataGaLocation":488},"source code management",{"text":566,"config":622},{"href":125,"dataGaName":623,"dataGaLocation":488},"continuous integration & delivery",{"text":625,"config":626},"Value stream management",{"href":176,"dataGaName":627,"dataGaLocation":488},"value stream management",{"text":571,"config":629},{"href":630,"dataGaName":574,"dataGaLocation":488},"/solutions/gitops/",{"text":186,"config":632},{"href":188,"dataGaName":189,"dataGaLocation":488},{"text":634,"config":635},"Small business",{"href":193,"dataGaName":194,"dataGaLocation":488},{"text":637,"config":638},"Public sector",{"href":198,"dataGaName":199,"dataGaLocation":488},{"text":640,"config":641},"Education",{"href":642,"dataGaName":643,"dataGaLocation":488},"/solutions/education/","education",{"text":645,"config":646},"Financial services",{"href":647,"dataGaName":648,"dataGaLocation":488},"/solutions/finance/","financial services",{"title":206,"links":650},[651,653,655,657,660,662,664,666,668,670,672,674,676],{"text":218,"config":652},{"href":220,"dataGaName":221,"dataGaLocation":488},{"text":223,"config":654},{"href":225,"dataGaName":226,"dataGaLocation":488},{"text":228,"config":656},{"href":230,"dataGaName":231,"dataGaLocation":488},{"text":233,"config":658},{"href":235,"dataGaName":659,"dataGaLocation":488},"docs",{"text":256,"config":661},{"href":258,"dataGaName":5,"dataGaLocation":488},{"text":251,"config":663},{"href":253,"dataGaName":254,"dataGaLocation":488},{"text":260,"config":665},{"href":262,"dataGaName":263,"dataGaLocation":488},{"text":273,"config":667},{"href":275,"dataGaName":276,"dataGaLocation":488},{"text":265,"config":669},{"href":267,"dataGaName":268,"dataGaLocation":488},{"text":278,"config":671},{"href":280,"dataGaName":281,"dataGaLocation":488},{"text":283,"config":673},{"href":285,"dataGaName":286,"dataGaLocation":488},{"text":288,"config":675},{"href":290,"dataGaName":291,"dataGaLocation":488},{"text":293,"config":677},{"href":295,"dataGaName":296,"dataGaLocation":488},{"title":311,"links":679},[680,682,684,686,688,690,692,696,701,703,705,707],{"text":318,"config":681},{"href":320,"dataGaName":313,"dataGaLocation":488},{"text":323,"config":683},{"href":325,"dataGaName":326,"dataGaLocation":488},{"text":331,"config":685},{"href":333,"dataGaName":334,"dataGaLocation":488},{"text":336,"config":687},{"href":338,"dataGaName":339,"dataGaLocation":488},{"text":341,"config":689},{"href":343,"dataGaName":344,"dataGaLocation":488},{"text":346,"config":691},{"href":348,"dataGaName":349,"dataGaLocation":488},{"text":693,"config":694},"Sustainability",{"href":695,"dataGaName":693,"dataGaLocation":488},"/sustainability/",{"text":697,"config":698},"Diversity, inclusion and belonging (DIB)",{"href":699,"dataGaName":700,"dataGaLocation":488},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":351,"config":702},{"href":353,"dataGaName":354,"dataGaLocation":488},{"text":361,"config":704},{"href":363,"dataGaName":364,"dataGaLocation":488},{"text":366,"config":706},{"href":368,"dataGaName":369,"dataGaLocation":488},{"text":708,"config":709},"Modern Slavery Transparency Statement",{"href":710,"dataGaName":711,"dataGaLocation":488},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":713},[714,716,718],{"text":538,"config":715},{"href":540,"dataGaName":541,"dataGaLocation":488},{"text":543,"config":717},{"href":545,"dataGaName":546,"dataGaLocation":488},{"text":548,"config":719},{"dataGaName":550,"dataGaLocation":488,"id":551,"isOneTrustButton":106},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[725],{"_path":726,"_dir":727,"_draft":6,"_partial":6,"_locale":7,"content":728,"config":732,"_id":734,"_type":29,"title":18,"_source":31,"_file":735,"_stem":736,"_extension":34},"/en-us/blog/authors/sam-morris","authors",{"name":18,"config":729},{"headshot":730,"ctfId":731},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660148/Blog/Author%20Headshots/sam_morris.png","6JTrhUIqSCU30Y9KZOaan8",{"template":733},"BlogAuthor","content:en-us:blog:authors:sam-morris.yml","en-us/blog/authors/sam-morris.yml","en-us/blog/authors/sam-morris",{"_path":738,"_dir":37,"_draft":6,"_partial":6,"_locale":7,"header":739,"eyebrow":740,"blurb":741,"button":742,"secondaryButton":746,"_id":748,"_type":29,"title":749,"_source":31,"_file":750,"_stem":751,"_extension":34},"/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":45,"config":743},{"href":744,"dataGaName":48,"dataGaLocation":745},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":50,"config":747},{"href":52,"dataGaName":53,"dataGaLocation":745},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":753,"content":754,"config":757,"_id":28,"_type":29,"title":30,"_source":31,"_file":32,"_stem":33,"_extension":34},{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},{"title":9,"description":10,"authors":755,"heroImage":11,"date":19,"body":20,"category":21,"tags":756},[18],[23,24],{"slug":26,"featured":6,"template":27},1761814420334]