[{"data":1,"prerenderedAt":758},["ShallowReactive",2],{"/en-us/blog/custom-actions-rasa-gitlab-devops":3,"navigation-en-us":37,"banner-en-us":465,"footer-en-us":482,"William Arias":724,"next-steps-en-us":737,"footer-source-/en-us/blog/custom-actions-rasa-gitlab-devops/":752},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":27,"_id":30,"_type":31,"title":32,"_source":33,"_file":34,"_stem":35,"_extension":36},"/en-us/blog/custom-actions-rasa-gitlab-devops","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Creating custom action containers for Rasa X with GitLab","Using the GitLab DevOps Platform together with Rasa X can make it easier for stakeholders to deliver a virtual assistant by automating potentially time-consuming, error-prone steps. In this case, we’ve shown how you can build Rasa custom action servers and deploy them to Kubernetes.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749668410/Blog/Hero%20Images/vablog.jpg","https://about.gitlab.com/blog/custom-actions-rasa-gitlab-devops","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Create and Deploy Custom Actions Containers to Rasa X using Gitlab DevOps Platform\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"William Arias\"}],\n        \"datePublished\": \"2021-04-06\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":20,"body":21,"category":22,"tags":23},"Create and Deploy Custom Actions Containers to Rasa X using Gitlab DevOps Platform",[19],"William Arias","2021-04-06","**This blog post was a collaboration between William Arias, from Gitlab, and\nVincent D. Warmerdam, from Rasa. You can find the same blog post on [Rasa's\nblog](https://blog.rasa.com/create-and-deploy-custom-actions-containers-to-rasa-x-using-gitlab-devops-platform/)**.  \n\n\n## Create and Deploy Custom Actions Containers to Rasa X using Gitlab DevOps\nPlatform\n\nVirtual assistants do more than just carry on conversations. They can send\nemails, make updates to a calendar, or call an API endpoint. Essentially,\nthey can do actions that add significant value and convenience to the user\nexperience.\n\nIn assistants built with Rasa*, this type of functionality is executed by\ncustom code called custom actions. As with any code you run in production,\nyou’ll need to think about how you want to deploy updates to custom actions.\nIn this blog post, we’ll show you how to set up GitLab to deploy custom\naction Docker containers to your Kubernetes cluster. If we follow [good\nDevOps practices](/stages-devops-lifecycle/) we can greatly speed up the\ndevelopment and quality of our  virtual assistants.\n\n* Rasa Open Source is a machine learning framework for building text and\nvoice-based virtual assistants. It provides infrastructure for understanding\nmessages, holding conversations, and connecting to many messaging channels\nand APIs. Rasa X is a toolset that runs on top of Rasa Open Source,\nextending its capabilities. Rasa X includes key features for sharing the\nassistant with test users, reviewing and annotating conversation data, and\ndeploying the assistant. [Learn more about Rasa.](https://rasa.com/docs/)\n\n\n## Deployment high-level overview\n\nThe typical workflow for deploying a new version of custom actions is\noutlined below.  \n\n![actions-process](https://about.gitlab.com/images/blogimages/actions-process.png){:\n.shadow}\n\n\nEvery change to your custom actions code will require a new container image\nto be built and pulled by Rasa X. Gitlab CI/CD can save you from doing a lot\nof manual work and automate steps like the ones described in the workflow\nabove. Let's see how to do it.  \n\n\n## Using Rasa with Gitlab DevOps Platform\n\nLet's create a pipeline that will automate manual steps.\n\n\n---\n\n**NOTE**\n\nThis article assumes you have your [Gitlab\nProject](https://gitlab.com/warias/gl-commit-2020) with your customs Actions\nCode created along with a [Google Kubernetes\nCluster](https://cloud.google.com/kubernetes-engine/docs/quickstart).\n\n\n---\n\n\nIf you are a Gitlab user you are probably familiar with .gitlab-ci.yml file\nand its CI/CD capabilities. Every time you commit a change to your customs\nactions code you want Gitlab to run a script that will build and update your\ndocker containers. \n\n![actions-process-2](https://about.gitlab.com/images/blogimages/process2.png){:\n.shadow}\n\n\nLet's breakdown the CI/CD pipeline by describing the gitlab-ci.yml file so\nyou can use it and customize it to your needs\n\n## Variables\n\nWe make use of environment variables created in Gitlab at the moment of\nrunning the Jobs to define our actions Docker image  \n\n\n```\n\nvariables:\n    ACTIONS_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG\n    TAG: $CI_COMMIT_SHA\n    K8S_SECRET: secret-gitlab-registry\n\n```\n\n\nThe snippet above does the following:\n\n- It defines the name of the Docker Image for custom actions using\nenvironment variables ```$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG.``` This\nwill make the name of the Docker image different for every commit\n\n- It creates a secret used to pull the Rasa Action Image from the Gitlab\nPrivate Registry to the Google Kubernetes Cluster. \n\n\n## Stages\n\nWe have two main stages in our pipeline, build and deploy:\n\n```\n\nstages:\n  - build\n  - deploy \n```\n\nEvery time there is a new commit with changes to our custom actions code, or\nwhen we decide to run the CI/CD Pipeline it will:\n\n- Build: Here, we automate the building of the Docker image using the\nvariables defined above, and the Dockerfile. We also tag the image and push\nit to the GitLab container registry.\n\n- Deploy: Here we log-in to Kubernetes Engine on Google Cloud and deploy the\nnewly created Actions image to Rasa X.\n\nLet's see it in more detail:  \n\n\n**Build**:\n\n```\n\nbuild-actions-image:\n image: docker:19.03.1\n services:\n   - docker:dind\n stage: build\n script:\n   - docker login -u ```$CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY```\n   - docker build -t $ACTIONS_CONTAINER_IMAGE:$TAG -f Dockerfile .\n   - docker push $ACTIONS_CONTAINER_IMAGE:$TAG\n```\n\nThe job build-actions-image executed on the build stage takes advantage of\nthe CI/CD variables that are part of the environment where the pipelines\nrun. It automates the usage of Docker commands to build the Actions image by\nreading its corresponding Dockerfile. The output of this stage is a new\nCustom Actions image per every commit with code changes.  \n\n\n**Deploy**:\n\n```\n\ndeploy-custom-action-x:\n  stage: deploy\n  image: crileroro/gcloud-kubectl-helm\n  variables:\n    GCP_PROJECT: gke-project-302411\n    GCP_REGION: europe-west1\n    CLUSTER_NAME: gke-python-demo\n    NAMESPACE_RASA: rasa-environment \n  before_script:\n    - gcloud auth activate-service-account --key-file $SERVICE_ACCOUNT_GCP\n    - gcloud config set project $GCP_PROJECT\n    - gcloud config set compute/region $GCP_REGION\n    - gcloud container clusters get-credentials $CLUSTER_NAME\n  script:\n    - kubectl create ns $NAMESPACE_RASA --dry-run=client -o yaml | kubectl apply -f -\n    - kubectl create secret docker-registry $K8S_SECRET\n              --docker-server=$CI_REGISTRY\n              --docker-username=$CI_DEPLOY_USER\n              --docker-password=$CI_DEPLOY_PASSWORD\n              --namespace $NAMESPACE_RASA\n              -o yaml --dry-run=client | kubectl apply -f -\n    - helm repo add rasa-x https://rasahq.github.io/rasa-x-helm\n    - helm upgrade -i --reuse-values \n                      --namespace $NAMESPACE_RASA\n                      --set app.name=$ACTIONS_CONTAINER_IMAGE\n                      --set app.tag=$TAG \n                      --set images.imagePullSecrets[0].name=$K8S_SECRET rasa-x rasa-x/rasa-x\n```\n\n\nNotice the variables in ```before_script```, these ones are needed to\nauthenticate to GCP where we have our Kubernetes cluster. This step is\noptional and could be skipped in cases where you have [Gitlab\npre-integrated](https://docs.gitlab.com/ee/user/project/clusters/add_remove_clusters.html)\nwith your Kubernetes cluster running on Google Cloud.  \n\n\nThe main and most interesting part of the script is:  \n\n```\n\nscript:\n    - kubectl create ns $NAMESPACE_RASA --dry-run=client -o yaml | kubectl apply -f -\n    - kubectl create secret docker-registry $K8S_SECRET\n              --docker-server=$CI_REGISTRY\n              --docker-username=$CI_DEPLOY_USER\n              --docker-password=$CI_DEPLOY_PASSWORD\n              --namespace $NAMESPACE_RASA\n              -o yaml --dry-run=client | kubectl apply -f -\n    - helm repo add rasa-x https://rasahq.github.io/rasa-x-helm\n    - helm upgrade -i --reuse-values \n                      --namespace $NAMESPACE_RASA\n                      --set app.name=$ACTIONS_CONTAINER_IMAGE\n                      --set app.tag=$TAG \n                      --set images.imagePullSecrets[0].name=$K8S_SECRET rasa-x rasa-x/rasa-x\n\n```\n\n\nWe start by creating the *namespace* for our custom actions code, and if it\nalready exists, then we proceed to apply Kubernetes commands using kubectl\nand helm.  \n\n```\n\nhelm repo add rasa-x https://rasahq.github.io/rasa-x-helm\n    - helm upgrade -i --reuse-values \n                      --namespace $NAMESPACE_RASA\n                      --set app.name=$ACTIONS_CONTAINER_IMAGE\n                      --set app.tag=$TAG \n                      --set images.imagePullSecrets[0].name=$K8S_SECRET rasa-x rasa-x/rasa-x\n```\n\nThe snippet above adds a rasa-x Helm chart and upgrades or changes the\nvalues corresponding to the new **Custom Action Image** by assigning to it\nthe ```$ACTIONS_CONTAINER_IMAGE``` created in the build stage.\n\nNote that the pipeline described above focuses only on creating and\ndeploying the ACTIONS_CONTAINER_IMAGE. It could be extended by adding more\nstages, for example, code quality, security testing, and unit testing among\nothers.  \n\n\n## Summary\n\nUsing the GitLab DevOps Platform together with Rasa X can make it easier for\nstakeholders to deliver a virtual assistant by automating potentially\ntime-consuming, error-prone steps. In this case, we’ve shown how you can\nbuild Rasa custom action servers and deploy them to Kubernetes.\n\nPushing new custom action containers to Kubernetes only scratches the\nsurface of what you can automate with GitLab. You could also add steps for\ncode quality, security audits and unit tests. The main goal is to automate\nthe manual parts of deployment so that you can focus on what is important.\nIn the case of Rasa X, that means that more time can be spent learning from\nyour users and making a better assistant in the process.\n\n\nDo you want to learn more? Watch this video of Gitlab DevOps Platform and\nRasa [Deploy your Rasa Chatbots like a boss with\nDevOps](https://youtu.be/ko9-zPDuhQo)\n\n\nHappy hacking!\n\n\nCover image by [Eric\nKrull](https://unsplash.com/@ekrull?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non [Unsplash](https://unsplash.com)\n\n{: .note}\n","devsecops",[24,25,26],"CI","cloud native","DevOps",{"slug":28,"featured":6,"template":29},"custom-actions-rasa-gitlab-devops","BlogPost","content:en-us:blog:custom-actions-rasa-gitlab-devops.yml","yaml","Custom Actions Rasa Gitlab Devops","content","en-us/blog/custom-actions-rasa-gitlab-devops.yml","en-us/blog/custom-actions-rasa-gitlab-devops","yml",{"_path":38,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":40,"_id":461,"_type":31,"title":462,"_source":33,"_file":463,"_stem":464,"_extension":36},"/shared/en-us/main-navigation","en-us",{"logo":41,"freeTrial":46,"sales":51,"login":56,"items":61,"search":392,"minimal":423,"duo":442,"pricingDeployment":451},{"config":42},{"href":43,"dataGaName":44,"dataGaLocation":45},"/","gitlab logo","header",{"text":47,"config":48},"Get free trial",{"href":49,"dataGaName":50,"dataGaLocation":45},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":52,"config":53},"Talk to sales",{"href":54,"dataGaName":55,"dataGaLocation":45},"/sales/","sales",{"text":57,"config":58},"Sign in",{"href":59,"dataGaName":60,"dataGaLocation":45},"https://gitlab.com/users/sign_in/","sign in",[62,106,203,208,313,373],{"text":63,"config":64,"cards":66,"footer":89},"Platform",{"dataNavLevelOne":65},"platform",[67,73,81],{"title":63,"description":68,"link":69},"The most comprehensive AI-powered DevSecOps Platform",{"text":70,"config":71},"Explore our Platform",{"href":72,"dataGaName":65,"dataGaLocation":45},"/platform/",{"title":74,"description":75,"link":76},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":77,"config":78},"Meet GitLab Duo",{"href":79,"dataGaName":80,"dataGaLocation":45},"/gitlab-duo/","gitlab duo ai",{"title":82,"description":83,"link":84},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":85,"config":86},"Learn more",{"href":87,"dataGaName":88,"dataGaLocation":45},"/why-gitlab/","why gitlab",{"title":90,"items":91},"Get started with",[92,97,102],{"text":93,"config":94},"Platform Engineering",{"href":95,"dataGaName":96,"dataGaLocation":45},"/solutions/platform-engineering/","platform engineering",{"text":98,"config":99},"Developer Experience",{"href":100,"dataGaName":101,"dataGaLocation":45},"/developer-experience/","Developer experience",{"text":103,"config":104},"MLOps",{"href":105,"dataGaName":103,"dataGaLocation":45},"/topics/devops/the-role-of-ai-in-devops/",{"text":107,"left":108,"config":109,"link":111,"lists":115,"footer":185},"Product",true,{"dataNavLevelOne":110},"solutions",{"text":112,"config":113},"View all Solutions",{"href":114,"dataGaName":110,"dataGaLocation":45},"/solutions/",[116,141,164],{"title":117,"description":118,"link":119,"items":124},"Automation","CI/CD and automation to accelerate deployment",{"config":120},{"icon":121,"href":122,"dataGaName":123,"dataGaLocation":45},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[125,129,133,137],{"text":126,"config":127},"CI/CD",{"href":128,"dataGaLocation":45,"dataGaName":126},"/solutions/continuous-integration/",{"text":130,"config":131},"AI-Assisted Development",{"href":79,"dataGaLocation":45,"dataGaName":132},"AI assisted development",{"text":134,"config":135},"Source Code Management",{"href":136,"dataGaLocation":45,"dataGaName":134},"/solutions/source-code-management/",{"text":138,"config":139},"Automated Software Delivery",{"href":122,"dataGaLocation":45,"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":45,"icon":148},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[150,154,159],{"text":151,"config":152},"Application Security Testing",{"href":146,"dataGaName":153,"dataGaLocation":45},"Application security testing",{"text":155,"config":156},"Software Supply Chain Security",{"href":157,"dataGaLocation":45,"dataGaName":158},"/solutions/supply-chain/","Software supply chain security",{"text":160,"config":161},"Software Compliance",{"href":162,"dataGaName":163,"dataGaLocation":45},"/solutions/software-compliance/","software compliance",{"title":165,"link":166,"items":171},"Measurement",{"config":167},{"icon":168,"href":169,"dataGaName":170,"dataGaLocation":45},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[172,176,180],{"text":173,"config":174},"Visibility & Measurement",{"href":169,"dataGaLocation":45,"dataGaName":175},"Visibility and Measurement",{"text":177,"config":178},"Value Stream Management",{"href":179,"dataGaLocation":45,"dataGaName":177},"/solutions/value-stream-management/",{"text":181,"config":182},"Analytics & Insights",{"href":183,"dataGaLocation":45,"dataGaName":184},"/solutions/analytics-and-insights/","Analytics and insights",{"title":186,"items":187},"GitLab for",[188,193,198],{"text":189,"config":190},"Enterprise",{"href":191,"dataGaLocation":45,"dataGaName":192},"/enterprise/","enterprise",{"text":194,"config":195},"Small Business",{"href":196,"dataGaLocation":45,"dataGaName":197},"/small-business/","small business",{"text":199,"config":200},"Public Sector",{"href":201,"dataGaLocation":45,"dataGaName":202},"/solutions/public-sector/","public sector",{"text":204,"config":205},"Pricing",{"href":206,"dataGaName":207,"dataGaLocation":45,"dataNavLevelOne":207},"/pricing/","pricing",{"text":209,"config":210,"link":212,"lists":216,"feature":300},"Resources",{"dataNavLevelOne":211},"resources",{"text":213,"config":214},"View all resources",{"href":215,"dataGaName":211,"dataGaLocation":45},"/resources/",[217,250,272],{"title":218,"items":219},"Getting started",[220,225,230,235,240,245],{"text":221,"config":222},"Install",{"href":223,"dataGaName":224,"dataGaLocation":45},"/install/","install",{"text":226,"config":227},"Quick start guides",{"href":228,"dataGaName":229,"dataGaLocation":45},"/get-started/","quick setup checklists",{"text":231,"config":232},"Learn",{"href":233,"dataGaLocation":45,"dataGaName":234},"https://university.gitlab.com/","learn",{"text":236,"config":237},"Product documentation",{"href":238,"dataGaName":239,"dataGaLocation":45},"https://docs.gitlab.com/","product documentation",{"text":241,"config":242},"Best practice videos",{"href":243,"dataGaName":244,"dataGaLocation":45},"/getting-started-videos/","best practice videos",{"text":246,"config":247},"Integrations",{"href":248,"dataGaName":249,"dataGaLocation":45},"/integrations/","integrations",{"title":251,"items":252},"Discover",[253,258,262,267],{"text":254,"config":255},"Customer success stories",{"href":256,"dataGaName":257,"dataGaLocation":45},"/customers/","customer success stories",{"text":259,"config":260},"Blog",{"href":261,"dataGaName":5,"dataGaLocation":45},"/blog/",{"text":263,"config":264},"Remote",{"href":265,"dataGaName":266,"dataGaLocation":45},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":268,"config":269},"TeamOps",{"href":270,"dataGaName":271,"dataGaLocation":45},"/teamops/","teamops",{"title":273,"items":274},"Connect",[275,280,285,290,295],{"text":276,"config":277},"GitLab Services",{"href":278,"dataGaName":279,"dataGaLocation":45},"/services/","services",{"text":281,"config":282},"Community",{"href":283,"dataGaName":284,"dataGaLocation":45},"/community/","community",{"text":286,"config":287},"Forum",{"href":288,"dataGaName":289,"dataGaLocation":45},"https://forum.gitlab.com/","forum",{"text":291,"config":292},"Events",{"href":293,"dataGaName":294,"dataGaLocation":45},"/events/","events",{"text":296,"config":297},"Partners",{"href":298,"dataGaName":299,"dataGaLocation":45},"/partners/","partners",{"backgroundColor":301,"textColor":302,"text":303,"image":304,"link":308},"#2f2a6b","#fff","Insights for the future of software development",{"altText":305,"config":306},"the source promo card",{"src":307},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":309,"config":310},"Read the latest",{"href":311,"dataGaName":312,"dataGaLocation":45},"/the-source/","the source",{"text":314,"config":315,"lists":317},"Company",{"dataNavLevelOne":316},"company",[318],{"items":319},[320,325,331,333,338,343,348,353,358,363,368],{"text":321,"config":322},"About",{"href":323,"dataGaName":324,"dataGaLocation":45},"/company/","about",{"text":326,"config":327,"footerGa":330},"Jobs",{"href":328,"dataGaName":329,"dataGaLocation":45},"/jobs/","jobs",{"dataGaName":329},{"text":291,"config":332},{"href":293,"dataGaName":294,"dataGaLocation":45},{"text":334,"config":335},"Leadership",{"href":336,"dataGaName":337,"dataGaLocation":45},"/company/team/e-group/","leadership",{"text":339,"config":340},"Team",{"href":341,"dataGaName":342,"dataGaLocation":45},"/company/team/","team",{"text":344,"config":345},"Handbook",{"href":346,"dataGaName":347,"dataGaLocation":45},"https://handbook.gitlab.com/","handbook",{"text":349,"config":350},"Investor relations",{"href":351,"dataGaName":352,"dataGaLocation":45},"https://ir.gitlab.com/","investor relations",{"text":354,"config":355},"Trust Center",{"href":356,"dataGaName":357,"dataGaLocation":45},"/security/","trust center",{"text":359,"config":360},"AI Transparency Center",{"href":361,"dataGaName":362,"dataGaLocation":45},"/ai-transparency-center/","ai transparency center",{"text":364,"config":365},"Newsletter",{"href":366,"dataGaName":367,"dataGaLocation":45},"/company/contact/","newsletter",{"text":369,"config":370},"Press",{"href":371,"dataGaName":372,"dataGaLocation":45},"/press/","press",{"text":374,"config":375,"lists":376},"Contact us",{"dataNavLevelOne":316},[377],{"items":378},[379,382,387],{"text":52,"config":380},{"href":54,"dataGaName":381,"dataGaLocation":45},"talk to sales",{"text":383,"config":384},"Support portal",{"href":385,"dataGaName":386,"dataGaLocation":45},"https://support.gitlab.com","support portal",{"text":388,"config":389},"Customer portal",{"href":390,"dataGaName":391,"dataGaLocation":45},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":393,"login":394,"suggestions":401},"Close",{"text":395,"link":396},"To search repositories and projects, login to",{"text":397,"config":398},"gitlab.com",{"href":59,"dataGaName":399,"dataGaLocation":400},"search login","search",{"text":402,"default":403},"Suggestions",[404,406,410,412,416,420],{"text":74,"config":405},{"href":79,"dataGaName":74,"dataGaLocation":400},{"text":407,"config":408},"Code Suggestions (AI)",{"href":409,"dataGaName":407,"dataGaLocation":400},"/solutions/code-suggestions/",{"text":126,"config":411},{"href":128,"dataGaName":126,"dataGaLocation":400},{"text":413,"config":414},"GitLab on AWS",{"href":415,"dataGaName":413,"dataGaLocation":400},"/partners/technology-partners/aws/",{"text":417,"config":418},"GitLab on Google Cloud",{"href":419,"dataGaName":417,"dataGaLocation":400},"/partners/technology-partners/google-cloud-platform/",{"text":421,"config":422},"Why GitLab?",{"href":87,"dataGaName":421,"dataGaLocation":400},{"freeTrial":424,"mobileIcon":429,"desktopIcon":434,"secondaryButton":437},{"text":425,"config":426},"Start free trial",{"href":427,"dataGaName":50,"dataGaLocation":428},"https://gitlab.com/-/trials/new/","nav",{"altText":430,"config":431},"Gitlab Icon",{"src":432,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":430,"config":435},{"src":436,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":438,"config":439},"Get Started",{"href":440,"dataGaName":441,"dataGaLocation":428},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":443,"mobileIcon":447,"desktopIcon":449},{"text":444,"config":445},"Learn more about GitLab Duo",{"href":79,"dataGaName":446,"dataGaLocation":428},"gitlab duo",{"altText":430,"config":448},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":450},{"src":436,"dataGaName":433,"dataGaLocation":428},{"freeTrial":452,"mobileIcon":457,"desktopIcon":459},{"text":453,"config":454},"Back to pricing",{"href":206,"dataGaName":455,"dataGaLocation":428,"icon":456},"back to pricing","GoBack",{"altText":430,"config":458},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":460},{"src":436,"dataGaName":433,"dataGaLocation":428},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":466,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"title":467,"button":468,"image":473,"config":477,"_id":479,"_type":31,"_source":33,"_file":480,"_stem":481,"_extension":36},"/shared/en-us/banner","is now in public beta!",{"text":469,"config":470},"Try the Beta",{"href":471,"dataGaName":472,"dataGaLocation":45},"/gitlab-duo/agent-platform/","duo banner",{"altText":474,"config":475},"GitLab Duo Agent Platform",{"src":476},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":478},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":483,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":484,"_id":720,"_type":31,"title":721,"_source":33,"_file":722,"_stem":723,"_extension":36},"/shared/en-us/main-footer",{"text":485,"source":486,"edit":492,"contribute":497,"config":502,"items":507,"minimal":712},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":487,"config":488},"View page source",{"href":489,"dataGaName":490,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":493,"config":494},"Edit this page",{"href":495,"dataGaName":496,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":498,"config":499},"Please contribute",{"href":500,"dataGaName":501,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":503,"facebook":504,"youtube":505,"linkedin":506},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[508,555,605,649,678],{"title":204,"links":509,"subMenu":524},[510,514,519],{"text":511,"config":512},"View plans",{"href":206,"dataGaName":513,"dataGaLocation":491},"view plans",{"text":515,"config":516},"Why Premium?",{"href":517,"dataGaName":518,"dataGaLocation":491},"/pricing/premium/","why premium",{"text":520,"config":521},"Why Ultimate?",{"href":522,"dataGaName":523,"dataGaLocation":491},"/pricing/ultimate/","why ultimate",[525],{"title":526,"links":527},"Contact Us",[528,531,533,535,540,545,550],{"text":529,"config":530},"Contact sales",{"href":54,"dataGaName":55,"dataGaLocation":491},{"text":383,"config":532},{"href":385,"dataGaName":386,"dataGaLocation":491},{"text":388,"config":534},{"href":390,"dataGaName":391,"dataGaLocation":491},{"text":536,"config":537},"Status",{"href":538,"dataGaName":539,"dataGaLocation":491},"https://status.gitlab.com/","status",{"text":541,"config":542},"Terms of use",{"href":543,"dataGaName":544,"dataGaLocation":491},"/terms/","terms of use",{"text":546,"config":547},"Privacy statement",{"href":548,"dataGaName":549,"dataGaLocation":491},"/privacy/","privacy statement",{"text":551,"config":552},"Cookie preferences",{"dataGaName":553,"dataGaLocation":491,"id":554,"isOneTrustButton":108},"cookie preferences","ot-sdk-btn",{"title":107,"links":556,"subMenu":564},[557,561],{"text":558,"config":559},"DevSecOps platform",{"href":72,"dataGaName":560,"dataGaLocation":491},"devsecops platform",{"text":130,"config":562},{"href":79,"dataGaName":563,"dataGaLocation":491},"ai-assisted development",[565],{"title":566,"links":567},"Topics",[568,573,578,582,587,591,595,600],{"text":569,"config":570},"CICD",{"href":571,"dataGaName":572,"dataGaLocation":491},"/topics/ci-cd/","cicd",{"text":574,"config":575},"GitOps",{"href":576,"dataGaName":577,"dataGaLocation":491},"/topics/gitops/","gitops",{"text":26,"config":579},{"href":580,"dataGaName":581,"dataGaLocation":491},"/topics/devops/","devops",{"text":583,"config":584},"Version Control",{"href":585,"dataGaName":586,"dataGaLocation":491},"/topics/version-control/","version control",{"text":588,"config":589},"DevSecOps",{"href":590,"dataGaName":22,"dataGaLocation":491},"/topics/devsecops/",{"text":592,"config":593},"Cloud Native",{"href":594,"dataGaName":25,"dataGaLocation":491},"/topics/cloud-native/",{"text":596,"config":597},"AI for Coding",{"href":598,"dataGaName":599,"dataGaLocation":491},"/topics/devops/ai-for-coding/","ai for coding",{"text":601,"config":602},"Agentic AI",{"href":603,"dataGaName":604,"dataGaLocation":491},"/topics/agentic-ai/","agentic ai",{"title":606,"links":607},"Solutions",[608,610,612,617,621,624,628,631,633,636,639,644],{"text":151,"config":609},{"href":146,"dataGaName":151,"dataGaLocation":491},{"text":140,"config":611},{"href":122,"dataGaName":123,"dataGaLocation":491},{"text":613,"config":614},"Agile development",{"href":615,"dataGaName":616,"dataGaLocation":491},"/solutions/agile-delivery/","agile delivery",{"text":618,"config":619},"SCM",{"href":136,"dataGaName":620,"dataGaLocation":491},"source code management",{"text":569,"config":622},{"href":128,"dataGaName":623,"dataGaLocation":491},"continuous integration & delivery",{"text":625,"config":626},"Value stream management",{"href":179,"dataGaName":627,"dataGaLocation":491},"value stream management",{"text":574,"config":629},{"href":630,"dataGaName":577,"dataGaLocation":491},"/solutions/gitops/",{"text":189,"config":632},{"href":191,"dataGaName":192,"dataGaLocation":491},{"text":634,"config":635},"Small business",{"href":196,"dataGaName":197,"dataGaLocation":491},{"text":637,"config":638},"Public sector",{"href":201,"dataGaName":202,"dataGaLocation":491},{"text":640,"config":641},"Education",{"href":642,"dataGaName":643,"dataGaLocation":491},"/solutions/education/","education",{"text":645,"config":646},"Financial services",{"href":647,"dataGaName":648,"dataGaLocation":491},"/solutions/finance/","financial services",{"title":209,"links":650},[651,653,655,657,660,662,664,666,668,670,672,674,676],{"text":221,"config":652},{"href":223,"dataGaName":224,"dataGaLocation":491},{"text":226,"config":654},{"href":228,"dataGaName":229,"dataGaLocation":491},{"text":231,"config":656},{"href":233,"dataGaName":234,"dataGaLocation":491},{"text":236,"config":658},{"href":238,"dataGaName":659,"dataGaLocation":491},"docs",{"text":259,"config":661},{"href":261,"dataGaName":5,"dataGaLocation":491},{"text":254,"config":663},{"href":256,"dataGaName":257,"dataGaLocation":491},{"text":263,"config":665},{"href":265,"dataGaName":266,"dataGaLocation":491},{"text":276,"config":667},{"href":278,"dataGaName":279,"dataGaLocation":491},{"text":268,"config":669},{"href":270,"dataGaName":271,"dataGaLocation":491},{"text":281,"config":671},{"href":283,"dataGaName":284,"dataGaLocation":491},{"text":286,"config":673},{"href":288,"dataGaName":289,"dataGaLocation":491},{"text":291,"config":675},{"href":293,"dataGaName":294,"dataGaLocation":491},{"text":296,"config":677},{"href":298,"dataGaName":299,"dataGaLocation":491},{"title":314,"links":679},[680,682,684,686,688,690,692,696,701,703,705,707],{"text":321,"config":681},{"href":323,"dataGaName":316,"dataGaLocation":491},{"text":326,"config":683},{"href":328,"dataGaName":329,"dataGaLocation":491},{"text":334,"config":685},{"href":336,"dataGaName":337,"dataGaLocation":491},{"text":339,"config":687},{"href":341,"dataGaName":342,"dataGaLocation":491},{"text":344,"config":689},{"href":346,"dataGaName":347,"dataGaLocation":491},{"text":349,"config":691},{"href":351,"dataGaName":352,"dataGaLocation":491},{"text":693,"config":694},"Sustainability",{"href":695,"dataGaName":693,"dataGaLocation":491},"/sustainability/",{"text":697,"config":698},"Diversity, inclusion and belonging (DIB)",{"href":699,"dataGaName":700,"dataGaLocation":491},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":702},{"href":356,"dataGaName":357,"dataGaLocation":491},{"text":364,"config":704},{"href":366,"dataGaName":367,"dataGaLocation":491},{"text":369,"config":706},{"href":371,"dataGaName":372,"dataGaLocation":491},{"text":708,"config":709},"Modern Slavery Transparency Statement",{"href":710,"dataGaName":711,"dataGaLocation":491},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":713},[714,716,718],{"text":541,"config":715},{"href":543,"dataGaName":544,"dataGaLocation":491},{"text":546,"config":717},{"href":548,"dataGaName":549,"dataGaLocation":491},{"text":551,"config":719},{"dataGaName":553,"dataGaLocation":491,"id":554,"isOneTrustButton":108},"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":31,"title":19,"_source":33,"_file":735,"_stem":736,"_extension":36},"/en-us/blog/authors/william-arias","authors",{"name":19,"config":729},{"headshot":730,"ctfId":731},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667549/Blog/Author%20Headshots/warias-headshot.jpg","warias",{"template":733},"BlogAuthor","content:en-us:blog:authors:william-arias.yml","en-us/blog/authors/william-arias.yml","en-us/blog/authors/william-arias",{"_path":738,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"header":739,"eyebrow":740,"blurb":741,"button":742,"secondaryButton":746,"_id":748,"_type":31,"title":749,"_source":33,"_file":750,"_stem":751,"_extension":36},"/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":47,"config":743},{"href":744,"dataGaName":50,"dataGaLocation":745},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":52,"config":747},{"href":54,"dataGaName":55,"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":30,"_type":31,"title":32,"_source":33,"_file":34,"_stem":35,"_extension":36},{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},{"title":17,"description":10,"authors":755,"heroImage":11,"date":20,"body":21,"category":22,"tags":756},[19],[24,25,26],{"slug":28,"featured":6,"template":29},1761814420217]