[{"data":1,"prerenderedAt":722},["ShallowReactive",2],{"/en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines/":3,"navigation-en-us":39,"banner-en-us":468,"footer-en-us":485,"Abubakar Siddiq Ango":694,"next-steps-en-us":707},{"_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/efficient-devsecops-workflows-with-rules-for-conditional-pipelines","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"DevSecOps workflows with conditional CI/CD pipeline rules","CI/CD pipelines can be simple or complex, what makes them efficient are CI rules that define when and how they run.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749669673/Blog/Hero%20Images/engineering.png","https://about.gitlab.com/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to create efficient DevSecOps workflows with rules for conditional CI/CD pipelines\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Abubakar Siddiq Ango\"}],\n        \"datePublished\": \"2023-06-27\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":20,"body":21,"category":22,"tags":23},"How to create efficient DevSecOps workflows with rules for conditional CI/CD pipelines",[19],"Abubakar Siddiq Ango","2023-06-27","CI/CD pipelines can be simple or complex – what makes them efficient are\nrules that define when and how they run. By using rules, you create smarter\nCI/CD pipelines, which increase teams' productivity and allow organizations\nto iterate faster. In this tutorial, you will learn about the different\ntypes of CI/CD pipelines and rules and their use cases.\n\n\n## What is a pipeline?\n\nA pipeline is a top-level component of [continuous\nintegration](https://docs.gitlab.com/ee/ci/introduction/index.html#continuous-integration)\nand [continuous\ndelivery](https://docs.gitlab.com/ee/ci/introduction/index.html#continuous-delivery)/[continuous\ndeployment](https://docs.gitlab.com/ee/ci/introduction/index.html#continuous-deployment),\nand it comprises [jobs](https://docs.gitlab.com/ee/ci/jobs/index.html),\nwhich are lists of tasks to be executed. Jobs are organized in\n[stages](https://docs.gitlab.com/ee/ci/yaml/index.html#stages), which define\nwhen the jobs run.\n\n\nA pipeline can be a [basic\none](https://docs.gitlab.com/ee/ci/pipelines/pipeline_architectures.html#basic-pipelines)\nin which jobs run concurrently in each stage. Pipelines can also be complex,\nlike [parent-child\npipelines](https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html#parent-child-pipelines),\n[merge trains](https://docs.gitlab.com/ee/ci/pipelines/merge_trains.html),\n[multi-project\npipelines](https://docs.gitlab.com/ee/ci/pipelines/downstream_pipelines.html#multi-project-pipelines),\nor the more advanced [Directed Acyclic Graph\npipelines](https://docs.gitlab.com/ee/ci/directed_acyclic_graph/index.html)\n(DAG).\n\n\n![Complex pipeline showing\ndependencies](https://about.gitlab.com/images/blogimages/2023-06-15-efficient-devsecops-workflows-with-rules-for-conditional-pipelines/complex-pipelines.png)\n\n\nA [gitlab-runner\npipeline](https://gitlab.com/gitlab-org/gitlab-runner/-/pipelines/798871212/)\nshowing job dependencies.\n\n{: .note.text-center}\n\n\n![Directed Acyclic\nGraph](https://about.gitlab.com/images/blogimages/2023-06-15-efficient-devsecops-workflows-with-rules-for-conditional-pipelines/dag-pipelines.png)\n\n\nDirected Acyclic Graph pipeline\n\n{: .note.text-center}\n\n\nUse cases determine how complicated a pipeline can get. A use case might\nrequire testing an application and packaging it into a container; the\npipeline can even further deploy the container to an orchestrator like\nKubernetes or a container registry. Another use case might involve building\napplications that target different platforms with varying dependencies,\nwhich is where DAG pipelines shine.\n\n\n## What are CI/CD rules?\n\nCI/CD rules are the key to managing the flow of jobs in a pipeline. One of\nthe powerful features of GitLab CI/CD is the ability to control when a CI/CD\njob runs, which can depend on context, changes made,\n[workflow](https://docs.gitlab.com/ee/ci/yaml/workflow.html) rules, values\nof CI/CD variables, or custom conditions. Aside from using `rules`, you can\nalso control the flow of CI/CD pipelines using:\n\n\n* [`needs`](https://docs.gitlab.com/ee/ci/yaml/index.html#needs):\nestablishes relationships between jobs and used in DAG pipelines\n\n* [`only`](https://docs.gitlab.com/ee/ci/yaml/index.html#only--except):\ndefines when a job should run\n\n* [`except`](https://docs.gitlab.com/ee/ci/yaml/index.html#only--except):\ndefines when a job should not run\n\n* [`workflow`](https://docs.gitlab.com/ee/ci/yaml/workflow.html): controls\nwhen pipelines are created\n\n\n`only` and `except` should not be used with `rules` as this can lead to\nunexpected behavior. It is recommended to use `rules`, learn more in the\nfollowing sections.\n\n\n## What is the `rules` feature?\n\n`rules` determine when and if a job runs in a pipeline. If you have multiple\nrules defined, they are all evaluated in order until a matching rule is\nfound and the job is executed according to the specified configuration.\n\n\n[Rules](https://docs.gitlab.com/ee/ci/yaml/#rules) can be defined using the\nkeywords: `if`, `changes`, `exists`, `allow_failure`, `variables`, `when`\nand `needs`.\n\n\n### `rules:if`\n\nThe `if` keyword evaluates if a job should be added to a pipeline. The\nevaluation is done based on the values of [CI/CD\nvariables](https://docs.gitlab.com/ee/ci/variables/index.html) defined in\nthe scope of the job or pipeline and [predefined CI/CD\nvariables](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html).\n\n\n```yaml\n\njob:\n  script:\n    - echo $(date)\n  rules:\n    - if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == $CI_DEFAULT_BRANCH\n```\n\n\nIn the CI/CD script above, the job prints the current date and time with the\n`echo` command. The job is only executed if the source branch of a merge\nrequest (`CI_MERGE_REQUEST_SOURCE_BRANCH_NAME`) is the same as the project's\ndefault branch (`CI_DEFAULT_BRANCH`) in a [merge request\npipeline](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html).\nYou can use the `==` and `!=` operators for comparison, while `=~` and `!~`\nallow you to compare a variable to a regular expression. You can combine\nmultiple expressions using the `&&` (AND), `||` (OR) operators, and\nparentheses for grouping expressions.\n\n\n### `rules:changes`\n\nWith the `changes` keyword, you can watch for changes to certain files or\nfolders for a job to execute. GitLab uses the output of [Git\ndiffstat](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt\n\n\n```yaml\n\njob:\n  script:\n    - terraform plan\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      changes:\n        - terraform/**/*.tf\n```\n\n\nIn this example, the `terraform plan` is only executed when files with the\n`.tf` extension are changed in the `terraform` folder and its\nsubdirectories. An additional rule ensures the job is executed for [merge\nrequest\npipelines](https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html).\n\n\nThe `changes` rule can look for changes in specific files with `paths`:\n\n\n```yaml\n\njob:\n  script:\n    - terraform plan\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      changes:\n        paths:\n          - terraform/main.tf\n```\n\n\nChanges to files in a source reference (branch, tag, commit) can also be\ncompared against other references in the Git repository. The CI/CD job will\nonly execute when the source reference differs from the [specified reference\nvalue defined in\n`rules:changes:compare_to`](https://docs.gitlab.com/ee/ci/yaml/#ruleschangescompare_to).\nThis value can be a Git commit SHA, tag, or branch name. The following\nexample compares the source reference to the current `production` branch\n(`refs/head/production`).\n\n\n```yaml\n\njob:\n  script:\n    - terraform plan\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      changes:\n        paths:\n          - terraform/main.tf\n        compare_to: 'refs/head/production'\n```\n\n\n### `rules:exists`\n\nLike `changes`, you can execute CI/CD jobs only when specific files exist\n[using `rules:exists`\nrules](https://docs.gitlab.com/ee/ci/yaml/#rulesexists). For example, you\ncan run a job that checks whether a `Gemfile.lock` file exists. The\nfollowing example audits a Ruby project for vulnerable versions of gems or\ninsecure gem sources using the [bundler-audit\nproject](https://github.com/rubysec/bundler-audit).\n\n\n```yaml\n\njob:\n  script:\n    - bundle-audit check --format json --output bundle-audit.json\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      changes:\n        exits:\n          - Gemfile.lock\n```\n\n\n### `rules:allow_failure`\n\nThere are scenarios where the failure of a job should not affect the\nfollowing jobs and stages of the pipeline. This can be useful in use cases\nwhere non-blocking tasks are required as part of a project but don't impact\nthe project in any way. The [`rules:allow_failure`\nrule](https://docs.gitlab.com/ee/ci/yaml/#rulesallow_failure) can be set to\n`true` or `false`. It defaults to `false` implicitly when the rule is not\nspecified.\n\n\n```yaml\n\njob:\n  script:\n    - bundle-audit check --format json --output bundle-audit.json\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\" && $CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED == \"false\"\n      changes:\n        exits:\n          - Gemfile.lock\n      allow_failure: true\n```\n\n\nIn this example, the job can fail only if a merge request event triggers the\npipeline and the target branch is not protected.\n\n\n### `rules:needs`\n\nDisabled by fault,\n[`rules:needs`](https://docs.gitlab.com/ee/ci/yaml/#rulesneeds) was\nintroduced in [GitLab\n16](https://about.gitlab.com/releases/2023/05/22/gitlab-16-0-released/) and\ncan be enabled with the `introduce_rules_with_needs` [feature\nflag](https://docs.gitlab.com/ee/user/feature_flags.html).\n[`needs`](https://docs.gitlab.com/ee/ci/yaml/index.html#needs) is used to\nexecute jobs out of order without waiting for other jobs in a stage to\ncomplete. When used with `rules`, it replaces the job's `needs`\nspecification when the set conditions are met.\n\n\n```yaml\n\nstages:\n  - build\n  - qa\n  - deploy\n\nbuild-dev:\n  stage: build\n  rules:\n    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n  script: echo \"Building dev version...\"\n\nbuild-prod:\n  stage: build\n  rules:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n  script: echo \"Building production version...\"\n\nqa-checks:\n  stage: qa\n  script:\n    - echo \"Running QA checks before publishing to Production....\"\n\ndeploy:\n  stage: deploy\n  needs: ['build-dev']\n  rules:\n    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH\n      needs: ['build-prod', 'qa-checks']\n    - when: on_success # Run the job in other cases\n  script: echo \"Deploying application.\"\n\n```\n\n\nIn the example above, the deploy job has the `build-dev` job as a dependency\nbefore it runs; however, when the commit branch is the project's default\nbranch, its dependency changes to `build-prod` and `qa-checks`. This can\nallow for extra checks to be implemented based on context.\n\n\n### `rules:variables`\n\nIn some situations, you only need certain variables in specific conditions,\nor their values change based on content; you can use the\n[`rules:variables`](https://docs.gitlab.com/ee/ci/yaml/#rulesvariables) rule\nto define variables when specific conditions are met. This also allows to\ncreate more dynamic CI/CD execution workflows.\n\n\n```\n\njob:\n  variables:\n    DEPLOY_VERSION: \"dev\"\n  rules:\n    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH\n      variables:\n        DEPLOY_VERSION: \"stable\"\n  script:\n    - echo \"Deploying $DEPLOY_VERSION version\"\n```\n\n\n### `workflow:rules`\n\nSo far, we have looked at controlling when jobs run in a pipeline using the\n`rules` keyword. Sometimes, you want to control how the entire pipeline\nbehaves: That's where [`workflow:rules` provide a powerful\noption](https://docs.gitlab.com/ee/ci/yaml/#workflowrules). `workflow:rules`\nare evaluated before jobs and take precedence over the job rules. For\nexample, if a job has rules that allow it to run against a specific branch,\nbut the workflow rules set jobs running against the branch to `when: never`,\nthe jobs will not run.\n\n\nAll the features of `rules` mentioned in the previous sections work for\n`workflow:rules`.\n\n\n```yaml\n\nworkflow:\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"schedule\"\n      when: never\n    - if: $CI_PIPELINE_SOURCE == \"push\"\n      when: never\n    - when: always\n```\n\n\nIn the example above, the CI/CD pipeline runs except when a schedule or push\nevent is triggered.\n\n\n## Use cases for CI/CD rules\n\nIn the previous section, we looked at different ways of using the `rules`\nfeature of GitLab CI/CD. In this section, we will explore practical use\ncases.\n\n\n### Developer experience\n\nOne of the benefits of a DevSecOps platform is to allow developers to focus\non what they do best: writing their code and doing as little operations as\npossible. A company's DevOps or Platform team can create CI/CD templates for\ndifferent stages of their development lifecycle and use rules to add CI/CD\njobs to handle specific tasks based on their technology stack. A developer\nonly needs to include a default CI/CD script and pipelines are automatically\ncreated based on files detected, refs used, or defined variables, leading to\nincreased productivity.\n\n\n### Security and quality assurance\n\nA major function of CI/CD pipelines is to catch bugs or vulnerabilities\nbefore they are deployed into production infrastructure. Using CI/CD rules,\nsecurity and quality assurance teams can dynamically run extra checks on\nchanges introduced when certain factors are introduced. For example, malware\nscans can be added when new file extensions not in an approved list are\ndetected, or more advanced performance tests are automatically added when a\ncertain level of change has been introduced to the codebase. With GitLab's\nbuilt-in security, including security in your pipelines can be done with\njust a few lines of code.\n\n\n```yaml\n\ninclude:\n  # Static\n  - template: Jobs/Container-Scanning.gitlab-ci.yml\n  - template: Jobs/Dependency-Scanning.gitlab-ci.yml\n  - template: Jobs/SAST.gitlab-ci.yml\n  - template: Jobs/Secret-Detection.gitlab-ci.yml\n  - template: Jobs/SAST-IaC.gitlab-ci.yml\n  - template: Jobs/Code-Quality.gitlab-ci.yml\n  - template: Security/Coverage-Fuzzing.gitlab-ci.yml\n  # Dynamic\n  - template: Security/DAST.latest.gitlab-ci.yml\n  - template: Security/BAS.latest.gitlab-ci.yml\n  - template: Security/DAST-API.latest.gitlab-ci.yml\n  - template: API-Fuzzing.latest.gitlab-ci.yml\n```\n\n\n### Automation\n\nThe power of CI/CD rules shines through in the (nearly) limitless\npossibilities of automating your CI/CD pipelines. GitLab\n[AutoDevOps](https://docs.gitlab.com/ee/topics/autodevops/) is an example.\nIt uses an opinionated best-practice collection of [GitLab CI/CD\ntemplates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates)\nand rules to detect the technology stack used. AutoDevOps creates relevant\njobs that take your application all the way to production from a push. You\ncan review the [AutoDevOps\ntemplate](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml)\nto learn how it leverages CI/CD rules for greater efficiency.\n\n\n### Using CI/CD components\n\nGrowth comes with several iterations of work and creating best practices.\nWhile building CI/CD pipelines, your DevOps team would have made several\nCI/CD scripts that they repurpose across pipelines using the\n[`include`](https://docs.gitlab.com/ee/ci/yaml/#include) keyword. In [GitLab\n16](https://about.gitlab.com/releases/2023/05/22/gitlab-16-0-released/),\nGitLab [introduced CI/CD\nComponents](https://about.gitlab.com/releases/2023/05/22/gitlab-16-0-released/#cicd-components),\nan experimental feature that allows your team to create reusable CI/CD\ncomponents and publish them as a catalog that can be used to build smarter\nCI/CD pipelines rapidly. You can learn more [about using CI/CD\ncomponents](https://docs.gitlab.com/ee/ci/components/) and the [component\ncatalog\ndirection](https://about.gitlab.com/direction/verify/component_catalog/).\n\n\nGitLab CI/CD enables you to run smarter pipelines, and it does so together\nwith [GitLab Duo, AI-powered workflows](/gitlab-duo/) to help you build more\nsecure software, faster.\n","engineering",[24,25,26,27,28],"tutorial","CI","CD","DevSecOps","DevSecOps platform",{"slug":30,"featured":6,"template":31},"efficient-devsecops-workflows-with-rules-for-conditional-pipelines","BlogPost","content:en-us:blog:efficient-devsecops-workflows-with-rules-for-conditional-pipelines.yml","yaml","Efficient Devsecops Workflows With Rules For Conditional Pipelines","content","en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines.yml","en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines","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":690,"_type":33,"title":691,"_source":35,"_file":692,"_stem":693,"_extension":38},"/shared/en-us/main-footer",{"text":488,"source":489,"edit":495,"contribute":500,"config":505,"items":510,"minimal":682},"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,533,589,618,652],{"title":65,"links":512,"subMenu":516},[513],{"text":28,"config":514},{"href":74,"dataGaName":515,"dataGaLocation":494},"devsecops platform",[517],{"title":207,"links":518},[519,523,528],{"text":520,"config":521},"View plans",{"href":209,"dataGaName":522,"dataGaLocation":494},"view plans",{"text":524,"config":525},"Why Premium?",{"href":526,"dataGaName":527,"dataGaLocation":494},"/pricing/premium/","why premium",{"text":529,"config":530},"Why Ultimate?",{"href":531,"dataGaName":532,"dataGaLocation":494},"/pricing/ultimate/","why ultimate",{"title":534,"links":535},"Solutions",[536,541,543,545,550,555,559,562,566,571,573,576,579,584],{"text":537,"config":538},"Digital transformation",{"href":539,"dataGaName":540,"dataGaLocation":494},"/topics/digital-transformation/","digital transformation",{"text":153,"config":542},{"href":155,"dataGaName":153,"dataGaLocation":494},{"text":142,"config":544},{"href":124,"dataGaName":125,"dataGaLocation":494},{"text":546,"config":547},"Agile development",{"href":548,"dataGaName":549,"dataGaLocation":494},"/solutions/agile-delivery/","agile delivery",{"text":551,"config":552},"Cloud transformation",{"href":553,"dataGaName":554,"dataGaLocation":494},"/topics/cloud-native/","cloud transformation",{"text":556,"config":557},"SCM",{"href":138,"dataGaName":558,"dataGaLocation":494},"source code management",{"text":128,"config":560},{"href":130,"dataGaName":561,"dataGaLocation":494},"continuous integration & delivery",{"text":563,"config":564},"Value stream management",{"href":182,"dataGaName":565,"dataGaLocation":494},"value stream management",{"text":567,"config":568},"GitOps",{"href":569,"dataGaName":570,"dataGaLocation":494},"/solutions/gitops/","gitops",{"text":192,"config":572},{"href":194,"dataGaName":195,"dataGaLocation":494},{"text":574,"config":575},"Small business",{"href":199,"dataGaName":200,"dataGaLocation":494},{"text":577,"config":578},"Public sector",{"href":204,"dataGaName":205,"dataGaLocation":494},{"text":580,"config":581},"Education",{"href":582,"dataGaName":583,"dataGaLocation":494},"/solutions/education/","education",{"text":585,"config":586},"Financial services",{"href":587,"dataGaName":588,"dataGaLocation":494},"/solutions/finance/","financial services",{"title":212,"links":590},[591,593,595,597,600,602,604,606,608,610,612,614,616],{"text":224,"config":592},{"href":226,"dataGaName":227,"dataGaLocation":494},{"text":229,"config":594},{"href":231,"dataGaName":232,"dataGaLocation":494},{"text":234,"config":596},{"href":236,"dataGaName":237,"dataGaLocation":494},{"text":239,"config":598},{"href":241,"dataGaName":599,"dataGaLocation":494},"docs",{"text":262,"config":601},{"href":264,"dataGaName":5,"dataGaLocation":494},{"text":257,"config":603},{"href":259,"dataGaName":260,"dataGaLocation":494},{"text":266,"config":605},{"href":268,"dataGaName":269,"dataGaLocation":494},{"text":279,"config":607},{"href":281,"dataGaName":282,"dataGaLocation":494},{"text":271,"config":609},{"href":273,"dataGaName":274,"dataGaLocation":494},{"text":284,"config":611},{"href":286,"dataGaName":287,"dataGaLocation":494},{"text":289,"config":613},{"href":291,"dataGaName":292,"dataGaLocation":494},{"text":294,"config":615},{"href":296,"dataGaName":297,"dataGaLocation":494},{"text":299,"config":617},{"href":301,"dataGaName":302,"dataGaLocation":494},{"title":317,"links":619},[620,622,624,626,628,630,632,636,641,643,645,647],{"text":324,"config":621},{"href":326,"dataGaName":319,"dataGaLocation":494},{"text":329,"config":623},{"href":331,"dataGaName":332,"dataGaLocation":494},{"text":337,"config":625},{"href":339,"dataGaName":340,"dataGaLocation":494},{"text":342,"config":627},{"href":344,"dataGaName":345,"dataGaLocation":494},{"text":347,"config":629},{"href":349,"dataGaName":350,"dataGaLocation":494},{"text":352,"config":631},{"href":354,"dataGaName":355,"dataGaLocation":494},{"text":633,"config":634},"Sustainability",{"href":635,"dataGaName":633,"dataGaLocation":494},"/sustainability/",{"text":637,"config":638},"Diversity, inclusion and belonging (DIB)",{"href":639,"dataGaName":640,"dataGaLocation":494},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":357,"config":642},{"href":359,"dataGaName":360,"dataGaLocation":494},{"text":367,"config":644},{"href":369,"dataGaName":370,"dataGaLocation":494},{"text":372,"config":646},{"href":374,"dataGaName":375,"dataGaLocation":494},{"text":648,"config":649},"Modern Slavery Transparency Statement",{"href":650,"dataGaName":651,"dataGaLocation":494},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":653,"links":654},"Contact Us",[655,658,660,662,667,672,677],{"text":656,"config":657},"Contact an expert",{"href":56,"dataGaName":57,"dataGaLocation":494},{"text":386,"config":659},{"href":388,"dataGaName":389,"dataGaLocation":494},{"text":391,"config":661},{"href":393,"dataGaName":394,"dataGaLocation":494},{"text":663,"config":664},"Status",{"href":665,"dataGaName":666,"dataGaLocation":494},"https://status.gitlab.com/","status",{"text":668,"config":669},"Terms of use",{"href":670,"dataGaName":671,"dataGaLocation":494},"/terms/","terms of use",{"text":673,"config":674},"Privacy statement",{"href":675,"dataGaName":676,"dataGaLocation":494},"/privacy/","privacy statement",{"text":678,"config":679},"Cookie preferences",{"dataGaName":680,"dataGaLocation":494,"id":681,"isOneTrustButton":110},"cookie preferences","ot-sdk-btn",{"items":683},[684,686,688],{"text":668,"config":685},{"href":670,"dataGaName":671,"dataGaLocation":494},{"text":673,"config":687},{"href":675,"dataGaName":676,"dataGaLocation":494},{"text":678,"config":689},{"dataGaName":680,"dataGaLocation":494,"id":681,"isOneTrustButton":110},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[695],{"_path":696,"_dir":697,"_draft":6,"_partial":6,"_locale":7,"content":698,"config":702,"_id":704,"_type":33,"title":19,"_source":35,"_file":705,"_stem":706,"_extension":38},"/en-us/blog/authors/abubakar-siddiq-ango","authors",{"name":19,"config":699},{"headshot":700,"ctfId":701},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660104/Blog/Author%20Headshots/abuango-headshot.jpg","abuango",{"template":703},"BlogAuthor","content:en-us:blog:authors:abubakar-siddiq-ango.yml","en-us/blog/authors/abubakar-siddiq-ango.yml","en-us/blog/authors/abubakar-siddiq-ango",{"_path":708,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"header":709,"eyebrow":710,"blurb":711,"button":712,"secondaryButton":716,"_id":718,"_type":33,"title":719,"_source":35,"_file":720,"_stem":721,"_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":713},{"href":714,"dataGaName":52,"dataGaLocation":715},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":54,"config":717},{"href":56,"dataGaName":57,"dataGaLocation":715},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758653937157]