[{"data":1,"prerenderedAt":723},["ShallowReactive",2],{"/en-us/blog/gitlab-gdk-remote-development/":3,"navigation-en-us":39,"banner-en-us":468,"footer-en-us":485,"Raimund Hook":695,"next-steps-en-us":708},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":29,"_id":32,"_type":33,"title":34,"_source":35,"_file":36,"_stem":37,"_extension":38},"/en-us/blog/gitlab-gdk-remote-development","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Contributor how-to: Remote Development workspaces and GitLab Developer Kit","This tutorial helps you get GDK working inside Remote Development workspaces to begin contributing to GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749670563/Blog/Hero%20Images/cloudcomputing.jpg","https://about.gitlab.com/blog/gitlab-gdk-remote-development","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Contributor how-to: Remote Development workspaces and GitLab Developer Kit\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Raimund Hook\"}],\n        \"datePublished\": \"2023-07-31\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Raimund Hook","2023-07-31","Open source is fundamental to GitLab. We believe that [everyone can\ncontribute](https://about.gitlab.com/company/mission/#mission).\n\nTypically, we recommend that anyone contributing anything more than basic\nchanges to GitLab run the [GitLab Development\nKit](https://gitlab.com/gitlab-org/gitlab-development-kit) (GDK). Because\ncontributors can't always meet the GDK's resource demands, we're working to\nenable GDK inside the cloud-based GitLab Remote Development workspaces.\n\n\nIn this article, I'll explain how I used a Remote Development workspace\nrunning in my Kubernetes cluster to make working with the GDK faster and\neasier.\n\n\n## A preliminary note\n\nFirst, keep in mind that as of this writing the [Remote Development\nworkspaces](https://about.gitlab.com/direction/create/ide/remote_development/)\nfeature is still in Beta. My example here is therefore very much a proof of\nconcept — and as such, it has some rough edges.\n\n\nBefore getting started, I followed the \"[Set up a\nworkspace](https://docs.gitlab.com/ee/user/workspace/#set-up-a-workspace)\"\nprerequisites guide in the GitLab docs. For a more detailed set of\ninstructions, see Senior Developer Evangelist Michael Friedrich's tutorial\non [how to set up infrastructure for cloud development\nenvironments](https://about.gitlab.com/blog/set-up-infrastructure-for-cloud-development-environments/).\n\n\n## Getting started with workspaces\n\nTo start using workspaces, you will need a project configured with a\n`.devfile.yaml`. GitLab team members have curated [a number of example\nprojects](https://gitlab.com/gitlab-org/remote-development/examples) you can\nreview.\n\n\nInitially, I tried to do this with a fork of the GitLab project itself, but\nI ran into [some\nissues](https://gitlab.com/gitlab-org/gitlab/-/issues/414011) when the\nworkspace begins cloning the repository.\n\n\nTo figure out what was causing my problems, I looked more closely at what\nhappens behind the scenes when a workspace is created.\n\n\n## Behind the scenes with Remote Development workspaces\n\nWhen you create a new workspace, the following happens:\n\n1. The GitLab agent for Kubernetes creates a new namespace in your cluster.\nThe agent dynamically generates a name for and assumes management of the\nnamespace.\n\n1. Inside the namespace, a new deployment is created, specifying the\ncontainer you chose in your `.devfile.yaml` as the image to use.\n\n1. This deployment is configured with some [init\ncontainers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/)\nthat perform some actions:\n    1. Cloning the repository into `/project/${project_path}`.\n    1. Injecting the VS Code server binary into your container.\n1. Once those init containers are complete, your container starts and the\nworkspace becomes available.\n\n\n## The clone problem\n\nWhen cloning a repository, `git` tends to do much of the work in memory.\nThis can be a challenge on larger projects/repositories, as it can require\nsignificant amounts of RAM. When cloning the GitLab project, for instance,\ngit consumes approximately 1.6GB of RAM. This number is only going to\nincrease with time. Sure, strategies like [shallow\nclones](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt)\ncan help reduce this, but these are perhaps less suited to active use by a\ndeveloper as they can increase the amount of time required to perform\nongoing git operations.\n\n\nIn fact, creating a workspace using our `.devfile.yaml` in a fork of the\nGitLab project failed for this reason. The init container performing the\nclone is currently hard-limited to 128MiB of RAM, after which the memory\nmanagement processes on the node kill the container.\n\n\nTo overcome this limitation, move the `.devfile.yaml` into the a fork of the\nroot of the GDK repository. This project clones more quickly (and does so\nusing fewer resources), so it's a  perfect starting point for running GDK\nitself. Another (bonus) advantage: You're then primed to contribute to the\nGDK itself, in addition to any of the other GitLab projects that the GDK\nclones.\n\n\n## Components of a GDK installation\n\nGDK clones the following projects from the GitLab 'family':\n\n* [GitLab](https://gitlab.com/gitlab-org/gitlab)\n\n* [Gitaly](https://gitlab.com/gitlab-org/gitaly)\n\n* [GitLab shell](https://gitlab.com/gitlab-org/gitlab-shell)\n\n\nThis allows you to work on any items in those directories as a part of your\n\"live\" installation.\n\n\n## Getting GDK installed and running in a workspace\n\nOnce I had a workspace up and running, my next step was to get GDK installed\nand running *in* that workspace. The GDK's documentation presents [several\nroutes for doing\nthis](https://gitlab.com/gitlab-org/gitlab-development-kit/#installation).\n\n\nA complete installation can take some time, as GDK needs to bootstrap itself\nand install a number of prerequisites. This is less than ideal in the\ncontext of a Remote Development workspace, as one of remote development's\nprimary benefits is enabling access to a development environment rapidly.\nRequiring a user to bootstrap an environment that takes 50 minutes (or\nlonger) doesn't help achieve this goal.\n\n\nTo combat this, I built a container image that effectively bootstraps and\ninstalls GDK, pre-building the GDK prerequisites and pre-seeding the\ndatabase. This image and its associated tooling are currently [in\nreview](https://gitlab.com/gitlab-org/gitlab-development-kit/-/merge_requests/3231).\n\n\n## Pre-building\n\nPre-building the container and running the bootstrap process on a scheduled\nbasis allows us to perform that process once, without requiring the user to\nwait for something that can essentially be \"pre-canned\" for their use.\n\n\nOnce the workspace is running, we still need to \"reinstall\" the GDK\nenvironment with the latest version of our GitLab repository, but this step\ndoesn't take quite as long as a complete bootstrap.\n\n\n## Generating a gdk.yml file\n\nTo work properly, GDK also requires a [`gdk.yml`\nfile](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/configuration.md#gdkyml).\nThis file tells GDK how to configure GitLab to return the correct URLs and\nother items. To get GDK running in Remote Development, Rails needs to return\nURLs in a certain scheme (otherwise your browser won't know where to\nconnect). To help this along, we [inject an environment\nvariable](https://gitlab.com/gitlab-org/gitlab/-/issues/415328) into the\nworkspace container. This variable helps us determine the URL in use (which\nis dynamically generated for each workspace).\n\n\nWe [now have a\nscript](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/support/gitlab-remote-dev/remote-dev-gdk-bootstrap.sh?ref_type=heads)\nin GDK that will generate your `gdk.yml` file based on your workspace.\n\n\n## Creating our devfile\n\nThe contents of my `.devfile.yaml` looks like this:\n\n\n```yaml\n\nschemaVersion: 2.2.0\n\ncomponents:\n  - name: tooling-container\n    attributes:\n      gl/inject-editor: true\n    container:\n      # NB! This image is only in use until https://gitlab.com/gitlab-org/gitlab-development-kit/-/merge_requests/3231 is merged!\n      image: registry.gitlab.com/gitlab-org/gitlab-development-kit/gitlab-remote-workspace:stingrayza-gdk-remote-dev-add-container\n      memoryRequest: 10240M\n      memoryLimit: 16384M\n      cpuRequest: 2000m\n      cpuLimit: 6000m\n      endpoints:\n        - name: ssh-2222\n          targetPort: 2222\n        - name: gdk-3000\n          targetPort: 3000\n        - name: docs-3005\n          targetPort: 3005\n        - name: pages-3010\n          targetPort: 3010\n        - name: webpack-3808\n          targetPort: 3808\n        - name: devops-5000\n          targetPort: 5000\n        - name: jaeger-5778\n          targetPort: 5778\n        - name: objects-9000\n          targetPort: 9000\n        - name: shell-9122\n          targetPort: 9122\n```\n\n\nThis definition comes straight out of the [Workspace\ndocs](https://docs.gitlab.com/ee/user/workspace/#devfile), and opens a\nnumber of ports that GDK uses. (For now, I've only tested the port\n`gdk-3000`, which is the the link to our instance of GDK.)\n\n\n## From Workspace to GDK\n\nOnce we have a project with a `.devfile.yaml`, our final step is to [create\na new\nworkspace](https://docs.gitlab.com/ee/user/workspace/#create-a-workspace).\n\n\nAs a part of this step, your cluster will pull the image as defined in the\n`.devfile.yaml` and start it up. For the GDK image we pre-built, this can\ntake a few minutes.\n\n\nOnce the workspace is ready, the last step is to follow the link from the UI\nto connect to the workspace. This will open up a familiar VS Code IDE, with\nour GDK fork checked out.\n\n\nBut wait, where's GDK?\n\n\nWell, the pre-build did most of the work for us, but we still need to take a\nfew final steps before we can claim that GDK is up and running. These have\nbeen built into a script we can run from the integrated terminal within the\nworkspace.\n\n\nTo open a terminal, we can click on the VS Code Hamburger menu (top left),\nnavigate to `Terminal` and select `New Terminal`.\n\n\nNow we execute the following script, which completes the setup and copies a\ncouple of files over from the pre-built folders:\n\n\n```shell\n\nsupport/gitlab-remote-dev/remote-dev-gdk-bootstrap.sh\n\n```\n\n\nThis can take up to 15 minutes, but when it's done it should output the\nmagic words — something like the following (note the 3000 in the URL; we\nspecified that in the `.devfile.yaml` earlier):\n\n\n```shell\n\nSuccess! You can access your GDK here:\nhttps://3000-workspace-62637-2083197-apglwp.workspace.my-workspace.example.net/\n\n```\n\n\n## Connect to your GDK\n\nFollow the link as displayed using Cmd-click or Ctrl-click. After a couple\nof moments (GDK boot time), you should reach a familiar GitLab login screen.\n\n\nCongratulations! GDK is now running inside your Remote Development\nworkspace.\n\n\nTo log in, type `gdk` in your terminal and you'll see the default admin\ncredentials displayed near the bottom:\n\n\n```shell\n\n# Development admin account: xxxx / xxxx\n\n\nFor more information about GitLab development see\n\nhttps://docs.gitlab.com/ee/development/index.html.\n\n```\n\n\nLog into your GDK with the default credentials, change the admin user\npassword, and you're all set!\n\n\n## Demo of workspace launch\n\nHere's a demo of launching a workspace in my personal cluster:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube.com/embed/iXq1NnTjnX0\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n## How to contribute to GitLab\n\nIn this article I explained how to get GDK up and running in Remote\nDevelopment workspaces. This is not without its challenges, but the end\nresult should mean that contributing to GitLab (especially in\nresource-constrained environments) is quicker and easier.\n\n\nDo you want to contribute to GitLab? Come and join in the conversation in\nthe `#contribute` channel on GitLab's [Discord](https://discord.gg/gitlab),\nor just pop in and say \"hello.\"\n\n\n_Disclaimer: This blog contains information related to upcoming products,\nfeatures, and functionality. It is important to note that the information in\nthis blog post is for informational purposes only. Please do not rely on\nthis information for purchasing or planning purposes. As with all projects,\nthe items mentioned in this blog and linked pages are subject to change or\ndelay. The development, release, and timing of any products, features, or\nfunctionality remain at the sole discretion of GitLab._\n","engineering",[23,24,25,26,27,28],"tutorial","DevOps","workflow","cloud native","contributors","open source",{"slug":30,"featured":6,"template":31},"gitlab-gdk-remote-development","BlogPost","content:en-us:blog:gitlab-gdk-remote-development.yml","yaml","Gitlab Gdk Remote Development","content","en-us/blog/gitlab-gdk-remote-development.yml","en-us/blog/gitlab-gdk-remote-development","yml",{"_path":40,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"data":42,"_id":464,"_type":33,"title":465,"_source":35,"_file":466,"_stem":467,"_extension":38},"/shared/en-us/main-navigation","en-us",{"logo":43,"freeTrial":48,"sales":53,"login":58,"items":63,"search":395,"minimal":426,"duo":445,"pricingDeployment":454},{"config":44},{"href":45,"dataGaName":46,"dataGaLocation":47},"/","gitlab logo","header",{"text":49,"config":50},"Get free trial",{"href":51,"dataGaName":52,"dataGaLocation":47},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":54,"config":55},"Talk to sales",{"href":56,"dataGaName":57,"dataGaLocation":47},"/sales/","sales",{"text":59,"config":60},"Sign in",{"href":61,"dataGaName":62,"dataGaLocation":47},"https://gitlab.com/users/sign_in/","sign in",[64,108,206,211,316,376],{"text":65,"config":66,"cards":68,"footer":91},"Platform",{"dataNavLevelOne":67},"platform",[69,75,83],{"title":65,"description":70,"link":71},"The most comprehensive AI-powered DevSecOps Platform",{"text":72,"config":73},"Explore our Platform",{"href":74,"dataGaName":67,"dataGaLocation":47},"/platform/",{"title":76,"description":77,"link":78},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":79,"config":80},"Meet GitLab Duo",{"href":81,"dataGaName":82,"dataGaLocation":47},"/gitlab-duo/","gitlab duo ai",{"title":84,"description":85,"link":86},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":87,"config":88},"Learn more",{"href":89,"dataGaName":90,"dataGaLocation":47},"/why-gitlab/","why gitlab",{"title":92,"items":93},"Get started with",[94,99,104],{"text":95,"config":96},"Platform Engineering",{"href":97,"dataGaName":98,"dataGaLocation":47},"/solutions/platform-engineering/","platform engineering",{"text":100,"config":101},"Developer Experience",{"href":102,"dataGaName":103,"dataGaLocation":47},"/developer-experience/","Developer experience",{"text":105,"config":106},"MLOps",{"href":107,"dataGaName":105,"dataGaLocation":47},"/topics/devops/the-role-of-ai-in-devops/",{"text":109,"left":110,"config":111,"link":113,"lists":117,"footer":188},"Product",true,{"dataNavLevelOne":112},"solutions",{"text":114,"config":115},"View all Solutions",{"href":116,"dataGaName":112,"dataGaLocation":47},"/solutions/",[118,143,167],{"title":119,"description":120,"link":121,"items":126},"Automation","CI/CD and automation to accelerate deployment",{"config":122},{"icon":123,"href":124,"dataGaName":125,"dataGaLocation":47},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[127,131,135,139],{"text":128,"config":129},"CI/CD",{"href":130,"dataGaLocation":47,"dataGaName":128},"/solutions/continuous-integration/",{"text":132,"config":133},"AI-Assisted Development",{"href":81,"dataGaLocation":47,"dataGaName":134},"AI assisted development",{"text":136,"config":137},"Source Code Management",{"href":138,"dataGaLocation":47,"dataGaName":136},"/solutions/source-code-management/",{"text":140,"config":141},"Automated Software Delivery",{"href":124,"dataGaLocation":47,"dataGaName":142},"Automated software delivery",{"title":144,"description":145,"link":146,"items":151},"Security","Deliver code faster without compromising security",{"config":147},{"href":148,"dataGaName":149,"dataGaLocation":47,"icon":150},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[152,157,162],{"text":153,"config":154},"Application Security Testing",{"href":155,"dataGaName":156,"dataGaLocation":47},"/solutions/application-security-testing/","Application security testing",{"text":158,"config":159},"Software Supply Chain Security",{"href":160,"dataGaLocation":47,"dataGaName":161},"/solutions/supply-chain/","Software supply chain security",{"text":163,"config":164},"Software Compliance",{"href":165,"dataGaName":166,"dataGaLocation":47},"/solutions/software-compliance/","software compliance",{"title":168,"link":169,"items":174},"Measurement",{"config":170},{"icon":171,"href":172,"dataGaName":173,"dataGaLocation":47},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[175,179,183],{"text":176,"config":177},"Visibility & Measurement",{"href":172,"dataGaLocation":47,"dataGaName":178},"Visibility and Measurement",{"text":180,"config":181},"Value Stream Management",{"href":182,"dataGaLocation":47,"dataGaName":180},"/solutions/value-stream-management/",{"text":184,"config":185},"Analytics & Insights",{"href":186,"dataGaLocation":47,"dataGaName":187},"/solutions/analytics-and-insights/","Analytics and insights",{"title":189,"items":190},"GitLab for",[191,196,201],{"text":192,"config":193},"Enterprise",{"href":194,"dataGaLocation":47,"dataGaName":195},"/enterprise/","enterprise",{"text":197,"config":198},"Small Business",{"href":199,"dataGaLocation":47,"dataGaName":200},"/small-business/","small business",{"text":202,"config":203},"Public Sector",{"href":204,"dataGaLocation":47,"dataGaName":205},"/solutions/public-sector/","public sector",{"text":207,"config":208},"Pricing",{"href":209,"dataGaName":210,"dataGaLocation":47,"dataNavLevelOne":210},"/pricing/","pricing",{"text":212,"config":213,"link":215,"lists":219,"feature":303},"Resources",{"dataNavLevelOne":214},"resources",{"text":216,"config":217},"View all resources",{"href":218,"dataGaName":214,"dataGaLocation":47},"/resources/",[220,253,275],{"title":221,"items":222},"Getting started",[223,228,233,238,243,248],{"text":224,"config":225},"Install",{"href":226,"dataGaName":227,"dataGaLocation":47},"/install/","install",{"text":229,"config":230},"Quick start guides",{"href":231,"dataGaName":232,"dataGaLocation":47},"/get-started/","quick setup checklists",{"text":234,"config":235},"Learn",{"href":236,"dataGaLocation":47,"dataGaName":237},"https://university.gitlab.com/","learn",{"text":239,"config":240},"Product documentation",{"href":241,"dataGaName":242,"dataGaLocation":47},"https://docs.gitlab.com/","product documentation",{"text":244,"config":245},"Best practice videos",{"href":246,"dataGaName":247,"dataGaLocation":47},"/getting-started-videos/","best practice videos",{"text":249,"config":250},"Integrations",{"href":251,"dataGaName":252,"dataGaLocation":47},"/integrations/","integrations",{"title":254,"items":255},"Discover",[256,261,265,270],{"text":257,"config":258},"Customer success stories",{"href":259,"dataGaName":260,"dataGaLocation":47},"/customers/","customer success stories",{"text":262,"config":263},"Blog",{"href":264,"dataGaName":5,"dataGaLocation":47},"/blog/",{"text":266,"config":267},"Remote",{"href":268,"dataGaName":269,"dataGaLocation":47},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":271,"config":272},"TeamOps",{"href":273,"dataGaName":274,"dataGaLocation":47},"/teamops/","teamops",{"title":276,"items":277},"Connect",[278,283,288,293,298],{"text":279,"config":280},"GitLab Services",{"href":281,"dataGaName":282,"dataGaLocation":47},"/services/","services",{"text":284,"config":285},"Community",{"href":286,"dataGaName":287,"dataGaLocation":47},"/community/","community",{"text":289,"config":290},"Forum",{"href":291,"dataGaName":292,"dataGaLocation":47},"https://forum.gitlab.com/","forum",{"text":294,"config":295},"Events",{"href":296,"dataGaName":297,"dataGaLocation":47},"/events/","events",{"text":299,"config":300},"Partners",{"href":301,"dataGaName":302,"dataGaLocation":47},"/partners/","partners",{"backgroundColor":304,"textColor":305,"text":306,"image":307,"link":311},"#2f2a6b","#fff","Insights for the future of software development",{"altText":308,"config":309},"the source promo card",{"src":310},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":312,"config":313},"Read the latest",{"href":314,"dataGaName":315,"dataGaLocation":47},"/the-source/","the source",{"text":317,"config":318,"lists":320},"Company",{"dataNavLevelOne":319},"company",[321],{"items":322},[323,328,334,336,341,346,351,356,361,366,371],{"text":324,"config":325},"About",{"href":326,"dataGaName":327,"dataGaLocation":47},"/company/","about",{"text":329,"config":330,"footerGa":333},"Jobs",{"href":331,"dataGaName":332,"dataGaLocation":47},"/jobs/","jobs",{"dataGaName":332},{"text":294,"config":335},{"href":296,"dataGaName":297,"dataGaLocation":47},{"text":337,"config":338},"Leadership",{"href":339,"dataGaName":340,"dataGaLocation":47},"/company/team/e-group/","leadership",{"text":342,"config":343},"Team",{"href":344,"dataGaName":345,"dataGaLocation":47},"/company/team/","team",{"text":347,"config":348},"Handbook",{"href":349,"dataGaName":350,"dataGaLocation":47},"https://handbook.gitlab.com/","handbook",{"text":352,"config":353},"Investor relations",{"href":354,"dataGaName":355,"dataGaLocation":47},"https://ir.gitlab.com/","investor relations",{"text":357,"config":358},"Trust Center",{"href":359,"dataGaName":360,"dataGaLocation":47},"/security/","trust center",{"text":362,"config":363},"AI Transparency Center",{"href":364,"dataGaName":365,"dataGaLocation":47},"/ai-transparency-center/","ai transparency center",{"text":367,"config":368},"Newsletter",{"href":369,"dataGaName":370,"dataGaLocation":47},"/company/contact/","newsletter",{"text":372,"config":373},"Press",{"href":374,"dataGaName":375,"dataGaLocation":47},"/press/","press",{"text":377,"config":378,"lists":379},"Contact us",{"dataNavLevelOne":319},[380],{"items":381},[382,385,390],{"text":54,"config":383},{"href":56,"dataGaName":384,"dataGaLocation":47},"talk to sales",{"text":386,"config":387},"Get help",{"href":388,"dataGaName":389,"dataGaLocation":47},"/support/","get help",{"text":391,"config":392},"Customer portal",{"href":393,"dataGaName":394,"dataGaLocation":47},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":396,"login":397,"suggestions":404},"Close",{"text":398,"link":399},"To search repositories and projects, login to",{"text":400,"config":401},"gitlab.com",{"href":61,"dataGaName":402,"dataGaLocation":403},"search login","search",{"text":405,"default":406},"Suggestions",[407,409,413,415,419,423],{"text":76,"config":408},{"href":81,"dataGaName":76,"dataGaLocation":403},{"text":410,"config":411},"Code Suggestions (AI)",{"href":412,"dataGaName":410,"dataGaLocation":403},"/solutions/code-suggestions/",{"text":128,"config":414},{"href":130,"dataGaName":128,"dataGaLocation":403},{"text":416,"config":417},"GitLab on AWS",{"href":418,"dataGaName":416,"dataGaLocation":403},"/partners/technology-partners/aws/",{"text":420,"config":421},"GitLab on Google Cloud",{"href":422,"dataGaName":420,"dataGaLocation":403},"/partners/technology-partners/google-cloud-platform/",{"text":424,"config":425},"Why GitLab?",{"href":89,"dataGaName":424,"dataGaLocation":403},{"freeTrial":427,"mobileIcon":432,"desktopIcon":437,"secondaryButton":440},{"text":428,"config":429},"Start free trial",{"href":430,"dataGaName":52,"dataGaLocation":431},"https://gitlab.com/-/trials/new/","nav",{"altText":433,"config":434},"Gitlab Icon",{"src":435,"dataGaName":436,"dataGaLocation":431},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":433,"config":438},{"src":439,"dataGaName":436,"dataGaLocation":431},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":441,"config":442},"Get Started",{"href":443,"dataGaName":444,"dataGaLocation":431},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":446,"mobileIcon":450,"desktopIcon":452},{"text":447,"config":448},"Learn more about GitLab Duo",{"href":81,"dataGaName":449,"dataGaLocation":431},"gitlab duo",{"altText":433,"config":451},{"src":435,"dataGaName":436,"dataGaLocation":431},{"altText":433,"config":453},{"src":439,"dataGaName":436,"dataGaLocation":431},{"freeTrial":455,"mobileIcon":460,"desktopIcon":462},{"text":456,"config":457},"Back to pricing",{"href":209,"dataGaName":458,"dataGaLocation":431,"icon":459},"back to pricing","GoBack",{"altText":433,"config":461},{"src":435,"dataGaName":436,"dataGaLocation":431},{"altText":433,"config":463},{"src":439,"dataGaName":436,"dataGaLocation":431},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":469,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"title":470,"button":471,"image":476,"config":480,"_id":482,"_type":33,"_source":35,"_file":483,"_stem":484,"_extension":38},"/shared/en-us/banner","is now in public beta!",{"text":472,"config":473},"Try the Beta",{"href":474,"dataGaName":475,"dataGaLocation":47},"/gitlab-duo/agent-platform/","duo banner",{"altText":477,"config":478},"GitLab Duo Agent Platform",{"src":479},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":481},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":486,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"data":487,"_id":691,"_type":33,"title":692,"_source":35,"_file":693,"_stem":694,"_extension":38},"/shared/en-us/main-footer",{"text":488,"source":489,"edit":495,"contribute":500,"config":505,"items":510,"minimal":683},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":490,"config":491},"View page source",{"href":492,"dataGaName":493,"dataGaLocation":494},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":496,"config":497},"Edit this page",{"href":498,"dataGaName":499,"dataGaLocation":494},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":501,"config":502},"Please contribute",{"href":503,"dataGaName":504,"dataGaLocation":494},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":506,"facebook":507,"youtube":508,"linkedin":509},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[511,534,590,619,653],{"title":65,"links":512,"subMenu":517},[513],{"text":514,"config":515},"DevSecOps platform",{"href":74,"dataGaName":516,"dataGaLocation":494},"devsecops platform",[518],{"title":207,"links":519},[520,524,529],{"text":521,"config":522},"View plans",{"href":209,"dataGaName":523,"dataGaLocation":494},"view plans",{"text":525,"config":526},"Why Premium?",{"href":527,"dataGaName":528,"dataGaLocation":494},"/pricing/premium/","why premium",{"text":530,"config":531},"Why Ultimate?",{"href":532,"dataGaName":533,"dataGaLocation":494},"/pricing/ultimate/","why ultimate",{"title":535,"links":536},"Solutions",[537,542,544,546,551,556,560,563,567,572,574,577,580,585],{"text":538,"config":539},"Digital transformation",{"href":540,"dataGaName":541,"dataGaLocation":494},"/topics/digital-transformation/","digital transformation",{"text":153,"config":543},{"href":155,"dataGaName":153,"dataGaLocation":494},{"text":142,"config":545},{"href":124,"dataGaName":125,"dataGaLocation":494},{"text":547,"config":548},"Agile development",{"href":549,"dataGaName":550,"dataGaLocation":494},"/solutions/agile-delivery/","agile delivery",{"text":552,"config":553},"Cloud transformation",{"href":554,"dataGaName":555,"dataGaLocation":494},"/topics/cloud-native/","cloud transformation",{"text":557,"config":558},"SCM",{"href":138,"dataGaName":559,"dataGaLocation":494},"source code management",{"text":128,"config":561},{"href":130,"dataGaName":562,"dataGaLocation":494},"continuous integration & delivery",{"text":564,"config":565},"Value stream management",{"href":182,"dataGaName":566,"dataGaLocation":494},"value stream management",{"text":568,"config":569},"GitOps",{"href":570,"dataGaName":571,"dataGaLocation":494},"/solutions/gitops/","gitops",{"text":192,"config":573},{"href":194,"dataGaName":195,"dataGaLocation":494},{"text":575,"config":576},"Small business",{"href":199,"dataGaName":200,"dataGaLocation":494},{"text":578,"config":579},"Public sector",{"href":204,"dataGaName":205,"dataGaLocation":494},{"text":581,"config":582},"Education",{"href":583,"dataGaName":584,"dataGaLocation":494},"/solutions/education/","education",{"text":586,"config":587},"Financial services",{"href":588,"dataGaName":589,"dataGaLocation":494},"/solutions/finance/","financial services",{"title":212,"links":591},[592,594,596,598,601,603,605,607,609,611,613,615,617],{"text":224,"config":593},{"href":226,"dataGaName":227,"dataGaLocation":494},{"text":229,"config":595},{"href":231,"dataGaName":232,"dataGaLocation":494},{"text":234,"config":597},{"href":236,"dataGaName":237,"dataGaLocation":494},{"text":239,"config":599},{"href":241,"dataGaName":600,"dataGaLocation":494},"docs",{"text":262,"config":602},{"href":264,"dataGaName":5,"dataGaLocation":494},{"text":257,"config":604},{"href":259,"dataGaName":260,"dataGaLocation":494},{"text":266,"config":606},{"href":268,"dataGaName":269,"dataGaLocation":494},{"text":279,"config":608},{"href":281,"dataGaName":282,"dataGaLocation":494},{"text":271,"config":610},{"href":273,"dataGaName":274,"dataGaLocation":494},{"text":284,"config":612},{"href":286,"dataGaName":287,"dataGaLocation":494},{"text":289,"config":614},{"href":291,"dataGaName":292,"dataGaLocation":494},{"text":294,"config":616},{"href":296,"dataGaName":297,"dataGaLocation":494},{"text":299,"config":618},{"href":301,"dataGaName":302,"dataGaLocation":494},{"title":317,"links":620},[621,623,625,627,629,631,633,637,642,644,646,648],{"text":324,"config":622},{"href":326,"dataGaName":319,"dataGaLocation":494},{"text":329,"config":624},{"href":331,"dataGaName":332,"dataGaLocation":494},{"text":337,"config":626},{"href":339,"dataGaName":340,"dataGaLocation":494},{"text":342,"config":628},{"href":344,"dataGaName":345,"dataGaLocation":494},{"text":347,"config":630},{"href":349,"dataGaName":350,"dataGaLocation":494},{"text":352,"config":632},{"href":354,"dataGaName":355,"dataGaLocation":494},{"text":634,"config":635},"Sustainability",{"href":636,"dataGaName":634,"dataGaLocation":494},"/sustainability/",{"text":638,"config":639},"Diversity, inclusion and belonging (DIB)",{"href":640,"dataGaName":641,"dataGaLocation":494},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":357,"config":643},{"href":359,"dataGaName":360,"dataGaLocation":494},{"text":367,"config":645},{"href":369,"dataGaName":370,"dataGaLocation":494},{"text":372,"config":647},{"href":374,"dataGaName":375,"dataGaLocation":494},{"text":649,"config":650},"Modern Slavery Transparency Statement",{"href":651,"dataGaName":652,"dataGaLocation":494},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":654,"links":655},"Contact Us",[656,659,661,663,668,673,678],{"text":657,"config":658},"Contact an expert",{"href":56,"dataGaName":57,"dataGaLocation":494},{"text":386,"config":660},{"href":388,"dataGaName":389,"dataGaLocation":494},{"text":391,"config":662},{"href":393,"dataGaName":394,"dataGaLocation":494},{"text":664,"config":665},"Status",{"href":666,"dataGaName":667,"dataGaLocation":494},"https://status.gitlab.com/","status",{"text":669,"config":670},"Terms of use",{"href":671,"dataGaName":672,"dataGaLocation":494},"/terms/","terms of use",{"text":674,"config":675},"Privacy statement",{"href":676,"dataGaName":677,"dataGaLocation":494},"/privacy/","privacy statement",{"text":679,"config":680},"Cookie preferences",{"dataGaName":681,"dataGaLocation":494,"id":682,"isOneTrustButton":110},"cookie preferences","ot-sdk-btn",{"items":684},[685,687,689],{"text":669,"config":686},{"href":671,"dataGaName":672,"dataGaLocation":494},{"text":674,"config":688},{"href":676,"dataGaName":677,"dataGaLocation":494},{"text":679,"config":690},{"dataGaName":681,"dataGaLocation":494,"id":682,"isOneTrustButton":110},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[696],{"_path":697,"_dir":698,"_draft":6,"_partial":6,"_locale":7,"content":699,"config":703,"_id":705,"_type":33,"title":18,"_source":35,"_file":706,"_stem":707,"_extension":38},"/en-us/blog/authors/raimund-hook","authors",{"name":18,"config":700},{"headshot":701,"ctfId":702},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672472/Blog/Author%20Headshots/stingrayza-headshot.jpg","stingrayza",{"template":704},"BlogAuthor","content:en-us:blog:authors:raimund-hook.yml","en-us/blog/authors/raimund-hook.yml","en-us/blog/authors/raimund-hook",{"_path":709,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"header":710,"eyebrow":711,"blurb":712,"button":713,"secondaryButton":717,"_id":719,"_type":33,"title":720,"_source":35,"_file":721,"_stem":722,"_extension":38},"/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":49,"config":714},{"href":715,"dataGaName":52,"dataGaLocation":716},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":54,"config":718},{"href":56,"dataGaName":57,"dataGaLocation":716},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326261253]