[{"data":1,"prerenderedAt":2359},["ShallowReactive",2],{"/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines":3,"navigation-en-us":1576,"banner-en-us":2001,"footer-en-us":2011,"blog-post-authors-en-us-Abubakar Siddiq Ango":2254,"blog-related-posts-en-us-efficient-devsecops-workflows-with-rules-for-conditional-pipelines":2269,"blog-promotions-en-us":2295,"next-steps-en-us":2349},{"id":4,"title":5,"authors":6,"body":8,"category":1552,"date":1553,"description":1554,"extension":1555,"externalUrl":1556,"faq":1556,"featured":1557,"heroImage":1558,"meta":1559,"navigation":854,"path":1560,"seo":1561,"slug":1566,"stem":1567,"tags":1568,"template":1574,"updatedDate":1556,"__hash__":1575},"blogPosts/en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines.md","How to create efficient DevSecOps workflows with rules for conditional CI/CD pipelines",[7],"Abubakar Siddiq Ango",{"type":9,"value":10,"toc":1532},"minimark",[11,15,20,36,62,69,78,84,87,90,94,108,149,163,170,175,204,211,228,289,332,338,348,406,425,434,495,515,583,589,613,673,679,701,770,773,779,817,1087,1098,1104,1114,1188,1194,1214,1222,1290,1293,1297,1303,1307,1310,1314,1317,1461,1465,1486,1490,1520,1528],[12,13,14],"p",{},"CI/CD pipelines can be simple or complex – what makes them efficient are rules that define when and how they run. By using rules, you create smarter CI/CD pipelines, which increase teams' productivity and allow organizations to iterate faster. In this tutorial, you will learn about the different types of CI/CD pipelines and rules and their use cases.",[16,17,19],"h2",{"id":18},"what-is-a-pipeline","What is a pipeline?",[12,21,22,23,29,30,35],{},"A pipeline is a top-level component of continuous integration and continuous delivery/continuous deployment, and it comprises ",[24,25,28],"a",{"href":26,"rel":27},"https://docs.gitlab.com/ci/jobs/",[],"jobs",", which are lists of tasks to be executed. Jobs are organized in ",[24,31,34],{"href":32,"rel":33},"https://docs.gitlab.com/ci/yaml/#stages",[],"stages",", which define when the jobs run.",[12,37,38,39,44,45,50,51,50,56,61],{},"A pipeline can be a ",[24,40,43],{"href":41,"rel":42},"https://docs.gitlab.com/ci/pipelines/pipeline_architectures/#basic-pipelines",[],"basic one"," in which jobs run concurrently in each stage. Pipelines can also be complex, like ",[24,46,49],{"href":47,"rel":48},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#parent-child-pipelines",[],"parent-child pipelines",", ",[24,52,55],{"href":53,"rel":54},"https://docs.gitlab.com/ci/pipelines/merge_trains/",[],"merge trains",[24,57,60],{"href":58,"rel":59},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#multi-project-pipelines",[],"multi-project pipelines",", or the more advanced Directed Acyclic Graph pipelines (DAG).",[12,63,64],{},[65,66],"img",{"alt":67,"src":68},"Complex pipeline showing dependencies","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782397781/blog/Content%20Images/2023-06-15-efficient-devsecops-workflows-with-rules-for-conditional-pipelines/complex-pipelines.png",[12,70,71,72,77],{},"A ",[24,73,76],{"href":74,"rel":75},"https://gitlab.com/gitlab-org/gitlab-runner/-/pipelines/798871212/",[],"gitlab-runner pipeline"," showing job dependencies.",[12,79,80],{},[65,81],{"alt":82,"src":83},"Directed Acyclic Graph","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782397782/blog/Content%20Images/2023-06-15-efficient-devsecops-workflows-with-rules-for-conditional-pipelines/dag-pipelines.png",[12,85,86],{},"Directed Acyclic Graph pipeline",[12,88,89],{},"Use cases determine how complicated a pipeline can get. A use case might require testing an application and packaging it into a container; the pipeline can even further deploy the container to an orchestrator like Kubernetes or a container registry. Another use case might involve building applications that target different platforms with varying dependencies, which is where DAG pipelines shine.",[16,91,93],{"id":92},"what-are-cicd-rules","What are CI/CD rules?",[12,95,96,97,102,103,107],{},"CI/CD rules are the key to managing the flow of jobs in a pipeline. One of the powerful features of GitLab CI/CD is the ability to control when a CI/CD job runs, which can depend on context, changes made, ",[24,98,101],{"href":99,"rel":100},"https://docs.gitlab.com/ci/yaml/workflow/",[],"workflow"," rules, values of CI/CD variables, or custom conditions. Aside from using ",[104,105,106],"code",{},"rules",", you can also control the flow of CI/CD pipelines using:",[109,110,111,122,132,141],"ul",{},[112,113,114,121],"li",{},[24,115,118],{"href":116,"rel":117},"https://docs.gitlab.com/ci/yaml/#needs",[],[104,119,120],{},"needs",": establishes relationships between jobs and used in DAG pipelines",[112,123,124,131],{},[24,125,128],{"href":126,"rel":127},"https://docs.gitlab.com/ci/yaml/#only--except",[],[104,129,130],{},"only",": defines when a job should run",[112,133,134,140],{},[24,135,137],{"href":126,"rel":136},[],[104,138,139],{},"except",": defines when a job should not run",[112,142,143,148],{},[24,144,146],{"href":99,"rel":145},[],[104,147,101],{},": controls when pipelines are created",[12,150,151,153,154,156,157,159,160,162],{},[104,152,130],{}," and ",[104,155,139],{}," should not be used with ",[104,158,106],{}," as this can lead to unexpected behavior. It is recommended to use ",[104,161,106],{},", learn more in the following sections.",[16,164,166,167,169],{"id":165},"what-is-the-rules-feature","What is the ",[104,168,106],{}," feature?",[12,171,172,174],{},[104,173,106],{}," determine when and if a job runs in a pipeline. If you have multiple rules defined, they are all evaluated in order until a matching rule is found and the job is executed according to the specified configuration.",[12,176,177,182,183,50,186,50,189,50,192,50,195,50,198,153,201,203],{},[24,178,181],{"href":179,"rel":180},"https://docs.gitlab.com/ci/yaml/#rules",[],"Rules"," can be defined using the keywords: ",[104,184,185],{},"if",[104,187,188],{},"changes",[104,190,191],{},"exists",[104,193,194],{},"allow_failure",[104,196,197],{},"variables",[104,199,200],{},"when",[104,202,120],{},".",[205,206,208],"h3",{"id":207},"rulesif",[104,209,210],{},"rules:if",[12,212,213,214,216,217,222,223,203],{},"The ",[104,215,185],{}," keyword evaluates if a job should be added to a pipeline. The evaluation is done based on the values of ",[24,218,221],{"href":219,"rel":220},"https://docs.gitlab.com/ci/variables/",[],"CI/CD variables"," defined in the scope of the job or pipeline and ",[24,224,227],{"href":225,"rel":226},"https://docs.gitlab.com/ci/variables/predefined_variables/",[],"predefined CI/CD variables",[229,230,235],"pre",{"className":231,"code":232,"language":233,"meta":234,"style":234},"language-yaml shiki shiki-themes github-light","job:\n  script:\n    - echo $(date)\n  rules:\n    - if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == $CI_DEFAULT_BRANCH\n\n","yaml","",[104,236,237,250,258,268,276],{"__ignoreMap":234},[238,239,242,246],"span",{"class":240,"line":241},"line",1,[238,243,245],{"class":244},"shJU0","job",[238,247,249],{"class":248},"sgsFI",":\n",[238,251,253,256],{"class":240,"line":252},2,[238,254,255],{"class":244},"  script",[238,257,249],{"class":248},[238,259,261,264],{"class":240,"line":260},3,[238,262,263],{"class":248},"    - ",[238,265,267],{"class":266},"sYBdl","echo $(date)\n",[238,269,271,274],{"class":240,"line":270},4,[238,272,273],{"class":244},"  rules",[238,275,249],{"class":248},[238,277,279,281,283,286],{"class":240,"line":278},5,[238,280,263],{"class":248},[238,282,185],{"class":244},[238,284,285],{"class":248},": ",[238,287,288],{"class":266},"$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == $CI_DEFAULT_BRANCH\n",[12,290,291,292,295,296,299,300,303,304,309,310,153,313,316,317,153,320,323,324,327,328,331],{},"In the CI/CD script above, the job prints the current date and time with the ",[104,293,294],{},"echo"," command. The job is only executed if the source branch of a merge request (",[104,297,298],{},"CI_MERGE_REQUEST_SOURCE_BRANCH_NAME",") is the same as the project's default branch (",[104,301,302],{},"CI_DEFAULT_BRANCH",") in a ",[24,305,308],{"href":306,"rel":307},"https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/",[],"merge request pipeline",". You can use the ",[104,311,312],{},"==",[104,314,315],{},"!="," operators for comparison, while ",[104,318,319],{},"=~",[104,321,322],{},"!~"," allow you to compare a variable to a regular expression. You can combine multiple expressions using the ",[104,325,326],{},"&&"," (AND), ",[104,329,330],{},"||"," (OR) operators, and parentheses for grouping expressions.",[205,333,335],{"id":334},"ruleschanges",[104,336,337],{},"rules:changes",[12,339,340,341,343,344],{},"With the ",[104,342,188],{}," keyword, you can watch for changes to certain files or folders for a job to execute. GitLab uses the output of [Git diffstat](",[24,345,346],{"href":346,"rel":347},"https://git-scm.com/docs/git-diff#Documentation/git-diff.txt",[],[229,349,351],{"className":231,"code":350,"language":233,"meta":234,"style":234},"job:\n  script:\n    - terraform plan\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      changes:\n        - terraform/**/*.tf\n\n",[104,352,353,359,365,372,378,389,397],{"__ignoreMap":234},[238,354,355,357],{"class":240,"line":241},[238,356,245],{"class":244},[238,358,249],{"class":248},[238,360,361,363],{"class":240,"line":252},[238,362,255],{"class":244},[238,364,249],{"class":248},[238,366,367,369],{"class":240,"line":260},[238,368,263],{"class":248},[238,370,371],{"class":266},"terraform plan\n",[238,373,374,376],{"class":240,"line":270},[238,375,273],{"class":244},[238,377,249],{"class":248},[238,379,380,382,384,386],{"class":240,"line":278},[238,381,263],{"class":248},[238,383,185],{"class":244},[238,385,285],{"class":248},[238,387,388],{"class":266},"$CI_PIPELINE_SOURCE == \"merge_request_event\"\n",[238,390,392,395],{"class":240,"line":391},6,[238,393,394],{"class":244},"      changes",[238,396,249],{"class":248},[238,398,400,403],{"class":240,"line":399},7,[238,401,402],{"class":248},"        - ",[238,404,405],{"class":266},"terraform/**/*.tf\n",[12,407,408,409,412,413,416,417,420,421,203],{},"In this example, the ",[104,410,411],{},"terraform plan"," is only executed when files with the ",[104,414,415],{},".tf"," extension are changed in the ",[104,418,419],{},"terraform"," folder and its subdirectories. An additional rule ensures the job is executed for ",[24,422,424],{"href":306,"rel":423},[],"merge request pipelines",[12,426,213,427,429,430,433],{},[104,428,188],{}," rule can look for changes in specific files with ",[104,431,432],{},"paths",":",[229,435,437],{"className":231,"code":436,"language":233,"meta":234,"style":234},"job:\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",[104,438,439,445,451,457,463,473,479,486],{"__ignoreMap":234},[238,440,441,443],{"class":240,"line":241},[238,442,245],{"class":244},[238,444,249],{"class":248},[238,446,447,449],{"class":240,"line":252},[238,448,255],{"class":244},[238,450,249],{"class":248},[238,452,453,455],{"class":240,"line":260},[238,454,263],{"class":248},[238,456,371],{"class":266},[238,458,459,461],{"class":240,"line":270},[238,460,273],{"class":244},[238,462,249],{"class":248},[238,464,465,467,469,471],{"class":240,"line":278},[238,466,263],{"class":248},[238,468,185],{"class":244},[238,470,285],{"class":248},[238,472,388],{"class":266},[238,474,475,477],{"class":240,"line":391},[238,476,394],{"class":244},[238,478,249],{"class":248},[238,480,481,484],{"class":240,"line":399},[238,482,483],{"class":244},"        paths",[238,485,249],{"class":248},[238,487,489,492],{"class":240,"line":488},8,[238,490,491],{"class":248},"          - ",[238,493,494],{"class":266},"terraform/main.tf\n",[12,496,497,498,506,507,510,511,514],{},"Changes to files in a source reference (branch, tag, commit) can also be compared against other references in the Git repository. The CI/CD job will only execute when the source reference differs from the ",[24,499,502,503],{"href":500,"rel":501},"https://docs.gitlab.com/ci/yaml/#ruleschangescompare_to",[],"specified reference value defined in ",[104,504,505],{},"rules:changes:compare_to",". This value can be a Git commit SHA, tag, or branch name. The following example compares the source reference to the current ",[104,508,509],{},"production"," branch (",[104,512,513],{},"refs/head/production",").",[229,516,518],{"className":231,"code":517,"language":233,"meta":234,"style":234},"job:\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",[104,519,520,526,532,538,544,554,560,566,572],{"__ignoreMap":234},[238,521,522,524],{"class":240,"line":241},[238,523,245],{"class":244},[238,525,249],{"class":248},[238,527,528,530],{"class":240,"line":252},[238,529,255],{"class":244},[238,531,249],{"class":248},[238,533,534,536],{"class":240,"line":260},[238,535,263],{"class":248},[238,537,371],{"class":266},[238,539,540,542],{"class":240,"line":270},[238,541,273],{"class":244},[238,543,249],{"class":248},[238,545,546,548,550,552],{"class":240,"line":278},[238,547,263],{"class":248},[238,549,185],{"class":244},[238,551,285],{"class":248},[238,553,388],{"class":266},[238,555,556,558],{"class":240,"line":391},[238,557,394],{"class":244},[238,559,249],{"class":248},[238,561,562,564],{"class":240,"line":399},[238,563,483],{"class":244},[238,565,249],{"class":248},[238,567,568,570],{"class":240,"line":488},[238,569,491],{"class":248},[238,571,494],{"class":266},[238,573,575,578,580],{"class":240,"line":574},9,[238,576,577],{"class":244},"        compare_to",[238,579,285],{"class":248},[238,581,582],{"class":266},"'refs/head/production'\n",[205,584,586],{"id":585},"rulesexists",[104,587,588],{},"rules:exists",[12,590,591,592,594,595,603,604,607,608,203],{},"Like ",[104,593,188],{},", you can execute CI/CD jobs only when specific files exist ",[24,596,599,600,602],{"href":597,"rel":598},"https://docs.gitlab.com/ci/yaml/#rulesexists",[],"using ",[104,601,588],{}," rules",". For example, you can run a job that checks whether a ",[104,605,606],{},"Gemfile.lock"," file exists. The following example audits a Ruby project for vulnerable versions of gems or insecure gem sources using the ",[24,609,612],{"href":610,"rel":611},"https://github.com/rubysec/bundler-audit",[],"bundler-audit project",[229,614,616],{"className":231,"code":615,"language":233,"meta":234,"style":234},"job:\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",[104,617,618,624,630,637,643,653,659,666],{"__ignoreMap":234},[238,619,620,622],{"class":240,"line":241},[238,621,245],{"class":244},[238,623,249],{"class":248},[238,625,626,628],{"class":240,"line":252},[238,627,255],{"class":244},[238,629,249],{"class":248},[238,631,632,634],{"class":240,"line":260},[238,633,263],{"class":248},[238,635,636],{"class":266},"bundle-audit check --format json --output bundle-audit.json\n",[238,638,639,641],{"class":240,"line":270},[238,640,273],{"class":244},[238,642,249],{"class":248},[238,644,645,647,649,651],{"class":240,"line":278},[238,646,263],{"class":248},[238,648,185],{"class":244},[238,650,285],{"class":248},[238,652,388],{"class":266},[238,654,655,657],{"class":240,"line":391},[238,656,394],{"class":244},[238,658,249],{"class":248},[238,660,661,664],{"class":240,"line":399},[238,662,663],{"class":244},"        exits",[238,665,249],{"class":248},[238,667,668,670],{"class":240,"line":488},[238,669,491],{"class":248},[238,671,672],{"class":266},"Gemfile.lock\n",[205,674,676],{"id":675},"rulesallow_failure",[104,677,678],{},"rules:allow_failure",[12,680,681,682,689,690,693,694,697,698,700],{},"There are scenarios where the failure of a job should not affect the following jobs and stages of the pipeline. This can be useful in use cases where non-blocking tasks are required as part of a project but don't impact the project in any way. The ",[24,683,686,688],{"href":684,"rel":685},"https://docs.gitlab.com/ci/yaml/#rulesallow_failure",[],[104,687,678],{}," rule"," can be set to ",[104,691,692],{},"true"," or ",[104,695,696],{},"false",". It defaults to ",[104,699,696],{}," implicitly when the rule is not specified.",[229,702,704],{"className":231,"code":703,"language":233,"meta":234,"style":234},"job:\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",[104,705,706,712,718,724,730,741,747,753,759],{"__ignoreMap":234},[238,707,708,710],{"class":240,"line":241},[238,709,245],{"class":244},[238,711,249],{"class":248},[238,713,714,716],{"class":240,"line":252},[238,715,255],{"class":244},[238,717,249],{"class":248},[238,719,720,722],{"class":240,"line":260},[238,721,263],{"class":248},[238,723,636],{"class":266},[238,725,726,728],{"class":240,"line":270},[238,727,273],{"class":244},[238,729,249],{"class":248},[238,731,732,734,736,738],{"class":240,"line":278},[238,733,263],{"class":248},[238,735,185],{"class":244},[238,737,285],{"class":248},[238,739,740],{"class":266},"$CI_PIPELINE_SOURCE == \"merge_request_event\" && $CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED == \"false\"\n",[238,742,743,745],{"class":240,"line":391},[238,744,394],{"class":244},[238,746,249],{"class":248},[238,748,749,751],{"class":240,"line":399},[238,750,663],{"class":244},[238,752,249],{"class":248},[238,754,755,757],{"class":240,"line":488},[238,756,491],{"class":248},[238,758,672],{"class":266},[238,760,761,764,766],{"class":240,"line":574},[238,762,763],{"class":244},"      allow_failure",[238,765,285],{"class":248},[238,767,769],{"class":768},"sYu0t","true\n",[12,771,772],{},"In this example, the job can fail only if a merge request event triggers the pipeline and the target branch is not protected.",[205,774,776],{"id":775},"rulesneeds",[104,777,778],{},"rules:needs",[12,780,781,782,788,789,794,795,798,799,804,805,810,811,813,814,816],{},"Disabled by fault, ",[24,783,786],{"href":784,"rel":785},"https://docs.gitlab.com/ci/yaml/#rulesneeds",[],[104,787,778],{}," was introduced in ",[24,790,793],{"href":791,"rel":792},"https://docs.gitlab.com/releases/16/gitlab-16-0-released/",[],"GitLab 16"," and can be enabled with the ",[104,796,797],{},"introduce_rules_with_needs"," ",[24,800,803],{"href":801,"rel":802},"https://docs.gitlab.com/administration/feature_flags/list/",[],"feature flag",". ",[24,806,808],{"href":116,"rel":807},[],[104,809,120],{}," is used to execute jobs out of order without waiting for other jobs in a stage to complete. When used with ",[104,812,106],{},", it replaces the job's ",[104,815,120],{}," specification when the set conditions are met.",[229,818,820],{"className":231,"code":819,"language":233,"meta":234,"style":234},"stages:\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",[104,821,822,828,836,843,850,856,863,872,878,889,899,904,912,921,928,940,950,955,963,972,979,987,992,1000,1009,1024,1031,1043,1061,1077],{"__ignoreMap":234},[238,823,824,826],{"class":240,"line":241},[238,825,34],{"class":244},[238,827,249],{"class":248},[238,829,830,833],{"class":240,"line":252},[238,831,832],{"class":248},"  - ",[238,834,835],{"class":266},"build\n",[238,837,838,840],{"class":240,"line":260},[238,839,832],{"class":248},[238,841,842],{"class":266},"qa\n",[238,844,845,847],{"class":240,"line":270},[238,846,832],{"class":248},[238,848,849],{"class":266},"deploy\n",[238,851,852],{"class":240,"line":278},[238,853,855],{"emptyLinePlaceholder":854},true,"\n",[238,857,858,861],{"class":240,"line":391},[238,859,860],{"class":244},"build-dev",[238,862,249],{"class":248},[238,864,865,868,870],{"class":240,"line":399},[238,866,867],{"class":244},"  stage",[238,869,285],{"class":248},[238,871,835],{"class":266},[238,873,874,876],{"class":240,"line":488},[238,875,273],{"class":244},[238,877,249],{"class":248},[238,879,880,882,884,886],{"class":240,"line":574},[238,881,263],{"class":248},[238,883,185],{"class":244},[238,885,285],{"class":248},[238,887,888],{"class":266},"$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH\n",[238,890,892,894,896],{"class":240,"line":891},10,[238,893,255],{"class":244},[238,895,285],{"class":248},[238,897,898],{"class":266},"echo \"Building dev version...\"\n",[238,900,902],{"class":240,"line":901},11,[238,903,855],{"emptyLinePlaceholder":854},[238,905,907,910],{"class":240,"line":906},12,[238,908,909],{"class":244},"build-prod",[238,911,249],{"class":248},[238,913,915,917,919],{"class":240,"line":914},13,[238,916,867],{"class":244},[238,918,285],{"class":248},[238,920,835],{"class":266},[238,922,924,926],{"class":240,"line":923},14,[238,925,273],{"class":244},[238,927,249],{"class":248},[238,929,931,933,935,937],{"class":240,"line":930},15,[238,932,263],{"class":248},[238,934,185],{"class":244},[238,936,285],{"class":248},[238,938,939],{"class":266},"$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n",[238,941,943,945,947],{"class":240,"line":942},16,[238,944,255],{"class":244},[238,946,285],{"class":248},[238,948,949],{"class":266},"echo \"Building production version...\"\n",[238,951,953],{"class":240,"line":952},17,[238,954,855],{"emptyLinePlaceholder":854},[238,956,958,961],{"class":240,"line":957},18,[238,959,960],{"class":244},"qa-checks",[238,962,249],{"class":248},[238,964,966,968,970],{"class":240,"line":965},19,[238,967,867],{"class":244},[238,969,285],{"class":248},[238,971,842],{"class":266},[238,973,975,977],{"class":240,"line":974},20,[238,976,255],{"class":244},[238,978,249],{"class":248},[238,980,982,984],{"class":240,"line":981},21,[238,983,263],{"class":248},[238,985,986],{"class":266},"echo \"Running QA checks before publishing to Production....\"\n",[238,988,990],{"class":240,"line":989},22,[238,991,855],{"emptyLinePlaceholder":854},[238,993,995,998],{"class":240,"line":994},23,[238,996,997],{"class":244},"deploy",[238,999,249],{"class":248},[238,1001,1003,1005,1007],{"class":240,"line":1002},24,[238,1004,867],{"class":244},[238,1006,285],{"class":248},[238,1008,849],{"class":266},[238,1010,1012,1015,1018,1021],{"class":240,"line":1011},25,[238,1013,1014],{"class":244},"  needs",[238,1016,1017],{"class":248},": [",[238,1019,1020],{"class":266},"'build-dev'",[238,1022,1023],{"class":248},"]\n",[238,1025,1027,1029],{"class":240,"line":1026},26,[238,1028,273],{"class":244},[238,1030,249],{"class":248},[238,1032,1034,1036,1038,1040],{"class":240,"line":1033},27,[238,1035,263],{"class":248},[238,1037,185],{"class":244},[238,1039,285],{"class":248},[238,1041,1042],{"class":266},"$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH\n",[238,1044,1046,1049,1051,1054,1056,1059],{"class":240,"line":1045},28,[238,1047,1048],{"class":244},"      needs",[238,1050,1017],{"class":248},[238,1052,1053],{"class":266},"'build-prod'",[238,1055,50],{"class":248},[238,1057,1058],{"class":266},"'qa-checks'",[238,1060,1023],{"class":248},[238,1062,1064,1066,1068,1070,1073],{"class":240,"line":1063},29,[238,1065,263],{"class":248},[238,1067,200],{"class":244},[238,1069,285],{"class":248},[238,1071,1072],{"class":266},"on_success",[238,1074,1076],{"class":1075},"sAwPA"," # Run the job in other cases\n",[238,1078,1080,1082,1084],{"class":240,"line":1079},30,[238,1081,255],{"class":244},[238,1083,285],{"class":248},[238,1085,1086],{"class":266},"echo \"Deploying application.\"\n",[12,1088,1089,1090,1092,1093,153,1095,1097],{},"In the example above, the deploy job has the ",[104,1091,860],{}," job as a dependency before it runs; however, when the commit branch is the project's default branch, its dependency changes to ",[104,1094,909],{},[104,1096,960],{},". This can allow for extra checks to be implemented based on context.",[205,1099,1101],{"id":1100},"rulesvariables",[104,1102,1103],{},"rules:variables",[12,1105,1106,1107,1113],{},"In some situations, you only need certain variables in specific conditions, or their values change based on content; you can use the ",[24,1108,1111],{"href":1109,"rel":1110},"https://docs.gitlab.com/ci/yaml/#rulesvariables",[],[104,1112,1103],{}," rule to define variables when specific conditions are met. This also allows to create more dynamic CI/CD execution workflows.",[229,1115,1117],{"className":231,"code":1116,"language":233,"meta":234,"style":234},"job:\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",[104,1118,1119,1125,1132,1142,1148,1158,1165,1175,1181],{"__ignoreMap":234},[238,1120,1121,1123],{"class":240,"line":241},[238,1122,245],{"class":244},[238,1124,249],{"class":248},[238,1126,1127,1130],{"class":240,"line":252},[238,1128,1129],{"class":244},"  variables",[238,1131,249],{"class":248},[238,1133,1134,1137,1139],{"class":240,"line":260},[238,1135,1136],{"class":244},"    DEPLOY_VERSION",[238,1138,285],{"class":248},[238,1140,1141],{"class":266},"\"dev\"\n",[238,1143,1144,1146],{"class":240,"line":270},[238,1145,273],{"class":244},[238,1147,249],{"class":248},[238,1149,1150,1152,1154,1156],{"class":240,"line":278},[238,1151,263],{"class":248},[238,1153,185],{"class":244},[238,1155,285],{"class":248},[238,1157,1042],{"class":266},[238,1159,1160,1163],{"class":240,"line":391},[238,1161,1162],{"class":244},"      variables",[238,1164,249],{"class":248},[238,1166,1167,1170,1172],{"class":240,"line":399},[238,1168,1169],{"class":244},"        DEPLOY_VERSION",[238,1171,285],{"class":248},[238,1173,1174],{"class":266},"\"stable\"\n",[238,1176,1177,1179],{"class":240,"line":488},[238,1178,255],{"class":244},[238,1180,249],{"class":248},[238,1182,1183,1185],{"class":240,"line":574},[238,1184,263],{"class":248},[238,1186,1187],{"class":266},"echo \"Deploying $DEPLOY_VERSION version\"\n",[205,1189,1191],{"id":1190},"workflowrules",[104,1192,1193],{},"workflow:rules",[12,1195,1196,1197,1199,1200,804,1207,1209,1210,1213],{},"So far, we have looked at controlling when jobs run in a pipeline using the ",[104,1198,106],{}," keyword. Sometimes, you want to control how the entire pipeline behaves: That's where ",[24,1201,1204,1206],{"href":1202,"rel":1203},"https://docs.gitlab.com/ci/yaml/#workflowrules",[],[104,1205,1193],{}," provide a powerful option",[104,1208,1193],{}," are evaluated before jobs and take precedence over the job rules. For example, if a job has rules that allow it to run against a specific branch, but the workflow rules set jobs running against the branch to ",[104,1211,1212],{},"when: never",", the jobs will not run.",[12,1215,1216,1217,1219,1220,203],{},"All the features of ",[104,1218,106],{}," mentioned in the previous sections work for ",[104,1221,1193],{},[229,1223,1225],{"className":231,"code":1224,"language":233,"meta":234,"style":234},"workflow:\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",[104,1226,1227,1233,1239,1250,1260,1271,1279],{"__ignoreMap":234},[238,1228,1229,1231],{"class":240,"line":241},[238,1230,101],{"class":244},[238,1232,249],{"class":248},[238,1234,1235,1237],{"class":240,"line":252},[238,1236,273],{"class":244},[238,1238,249],{"class":248},[238,1240,1241,1243,1245,1247],{"class":240,"line":260},[238,1242,263],{"class":248},[238,1244,185],{"class":244},[238,1246,285],{"class":248},[238,1248,1249],{"class":266},"$CI_PIPELINE_SOURCE == \"schedule\"\n",[238,1251,1252,1255,1257],{"class":240,"line":270},[238,1253,1254],{"class":244},"      when",[238,1256,285],{"class":248},[238,1258,1259],{"class":266},"never\n",[238,1261,1262,1264,1266,1268],{"class":240,"line":278},[238,1263,263],{"class":248},[238,1265,185],{"class":244},[238,1267,285],{"class":248},[238,1269,1270],{"class":266},"$CI_PIPELINE_SOURCE == \"push\"\n",[238,1272,1273,1275,1277],{"class":240,"line":391},[238,1274,1254],{"class":244},[238,1276,285],{"class":248},[238,1278,1259],{"class":266},[238,1280,1281,1283,1285,1287],{"class":240,"line":399},[238,1282,263],{"class":248},[238,1284,200],{"class":244},[238,1286,285],{"class":248},[238,1288,1289],{"class":266},"always\n",[12,1291,1292],{},"In the example above, the CI/CD pipeline runs except when a schedule or push event is triggered.",[16,1294,1296],{"id":1295},"use-cases-for-cicd-rules","Use cases for CI/CD rules",[12,1298,1299,1300,1302],{},"In the previous section, we looked at different ways of using the ",[104,1301,106],{}," feature of GitLab CI/CD. In this section, we will explore practical use cases.",[205,1304,1306],{"id":1305},"developer-experience","Developer experience",[12,1308,1309],{},"One of the benefits of a DevSecOps platform is to allow developers to focus on what they do best: writing their code and doing as little operations as possible. A company's DevOps or Platform team can create CI/CD templates for different stages of their development lifecycle and use rules to add CI/CD jobs to handle specific tasks based on their technology stack. A developer only needs to include a default CI/CD script and pipelines are automatically created based on files detected, refs used, or defined variables, leading to increased productivity.",[205,1311,1313],{"id":1312},"security-and-quality-assurance","Security and quality assurance",[12,1315,1316],{},"A major function of CI/CD pipelines is to catch bugs or vulnerabilities before they are deployed into production infrastructure. Using CI/CD rules, security and quality assurance teams can dynamically run extra checks on changes introduced when certain factors are introduced. For example, malware scans can be added when new file extensions not in an approved list are detected, or more advanced performance tests are automatically added when a certain level of change has been introduced to the codebase. With GitLab's built-in security, including security in your pipelines can be done with just a few lines of code.",[229,1318,1320],{"className":231,"code":1319,"language":233,"meta":234,"style":234},"include:\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",[104,1321,1322,1329,1334,1346,1357,1368,1379,1390,1401,1412,1417,1428,1439,1450],{"__ignoreMap":234},[238,1323,1324,1327],{"class":240,"line":241},[238,1325,1326],{"class":244},"include",[238,1328,249],{"class":248},[238,1330,1331],{"class":240,"line":252},[238,1332,1333],{"class":1075},"  # Static\n",[238,1335,1336,1338,1341,1343],{"class":240,"line":260},[238,1337,832],{"class":248},[238,1339,1340],{"class":244},"template",[238,1342,285],{"class":248},[238,1344,1345],{"class":266},"Jobs/Container-Scanning.gitlab-ci.yml\n",[238,1347,1348,1350,1352,1354],{"class":240,"line":270},[238,1349,832],{"class":248},[238,1351,1340],{"class":244},[238,1353,285],{"class":248},[238,1355,1356],{"class":266},"Jobs/Dependency-Scanning.gitlab-ci.yml\n",[238,1358,1359,1361,1363,1365],{"class":240,"line":278},[238,1360,832],{"class":248},[238,1362,1340],{"class":244},[238,1364,285],{"class":248},[238,1366,1367],{"class":266},"Jobs/SAST.gitlab-ci.yml\n",[238,1369,1370,1372,1374,1376],{"class":240,"line":391},[238,1371,832],{"class":248},[238,1373,1340],{"class":244},[238,1375,285],{"class":248},[238,1377,1378],{"class":266},"Jobs/Secret-Detection.gitlab-ci.yml\n",[238,1380,1381,1383,1385,1387],{"class":240,"line":399},[238,1382,832],{"class":248},[238,1384,1340],{"class":244},[238,1386,285],{"class":248},[238,1388,1389],{"class":266},"Jobs/SAST-IaC.gitlab-ci.yml\n",[238,1391,1392,1394,1396,1398],{"class":240,"line":488},[238,1393,832],{"class":248},[238,1395,1340],{"class":244},[238,1397,285],{"class":248},[238,1399,1400],{"class":266},"Jobs/Code-Quality.gitlab-ci.yml\n",[238,1402,1403,1405,1407,1409],{"class":240,"line":574},[238,1404,832],{"class":248},[238,1406,1340],{"class":244},[238,1408,285],{"class":248},[238,1410,1411],{"class":266},"Security/Coverage-Fuzzing.gitlab-ci.yml\n",[238,1413,1414],{"class":240,"line":891},[238,1415,1416],{"class":1075},"  # Dynamic\n",[238,1418,1419,1421,1423,1425],{"class":240,"line":901},[238,1420,832],{"class":248},[238,1422,1340],{"class":244},[238,1424,285],{"class":248},[238,1426,1427],{"class":266},"Security/DAST.latest.gitlab-ci.yml\n",[238,1429,1430,1432,1434,1436],{"class":240,"line":906},[238,1431,832],{"class":248},[238,1433,1340],{"class":244},[238,1435,285],{"class":248},[238,1437,1438],{"class":266},"Security/BAS.latest.gitlab-ci.yml\n",[238,1440,1441,1443,1445,1447],{"class":240,"line":914},[238,1442,832],{"class":248},[238,1444,1340],{"class":244},[238,1446,285],{"class":248},[238,1448,1449],{"class":266},"Security/DAST-API.latest.gitlab-ci.yml\n",[238,1451,1452,1454,1456,1458],{"class":240,"line":923},[238,1453,832],{"class":248},[238,1455,1340],{"class":244},[238,1457,285],{"class":248},[238,1459,1460],{"class":266},"API-Fuzzing.latest.gitlab-ci.yml\n",[205,1462,1464],{"id":1463},"automation","Automation",[12,1466,1467,1468,1473,1474,1479,1480,1485],{},"The power of CI/CD rules shines through in the (nearly) limitless possibilities of automating your CI/CD pipelines. GitLab ",[24,1469,1472],{"href":1470,"rel":1471},"https://docs.gitlab.com/topics/autodevops/",[],"AutoDevOps"," is an example. It uses an opinionated best-practice collection of ",[24,1475,1478],{"href":1476,"rel":1477},"https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates",[],"GitLab CI/CD templates"," and rules to detect the technology stack used. AutoDevOps creates relevant jobs that take your application all the way to production from a push. You can review the ",[24,1481,1484],{"href":1482,"rel":1483},"https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml",[],"AutoDevOps template"," to learn how it leverages CI/CD rules for greater efficiency.",[205,1487,1489],{"id":1488},"using-cicd-components","Using CI/CD components",[12,1491,1492,1493,1499,1500,1503,1504,1509,1510,1515,1516,203],{},"Growth comes with several iterations of work and creating best practices. While building CI/CD pipelines, your DevOps team would have made several CI/CD scripts that they repurpose across pipelines using the ",[24,1494,1497],{"href":1495,"rel":1496},"https://docs.gitlab.com/ci/yaml/#include",[],[104,1498,1326],{}," keyword. In ",[24,1501,793],{"href":791,"rel":1502},[],", GitLab ",[24,1505,1508],{"href":1506,"rel":1507},"https://docs.gitlab.com/releases/16/gitlab-16-0-released/#cicd-components",[],"introduced CI/CD Components",", an experimental feature that allows your team to create reusable CI/CD components and publish them as a catalog that can be used to build smarter CI/CD pipelines rapidly. You can learn more ",[24,1511,1514],{"href":1512,"rel":1513},"https://docs.gitlab.com/ci/components/",[],"about using CI/CD components"," and the ",[24,1517,1519],{"href":1512,"rel":1518},[],"component catalog documentation",[12,1521,1522,1523,1527],{},"GitLab CI/CD enables you to run smarter pipelines, and it does so together with ",[24,1524,1526],{"href":1525},"/gitlab-duo-agent-platform/","GitLab Duo, AI-powered workflows"," to help you build more secure software, faster.",[1529,1530,1531],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":234,"searchDepth":252,"depth":252,"links":1533},[1534,1535,1536,1546],{"id":18,"depth":252,"text":19},{"id":92,"depth":252,"text":93},{"id":165,"depth":252,"text":1537,"children":1538},"What is the rules feature?",[1539,1540,1541,1542,1543,1544,1545],{"id":207,"depth":260,"text":210},{"id":334,"depth":260,"text":337},{"id":585,"depth":260,"text":588},{"id":675,"depth":260,"text":678},{"id":775,"depth":260,"text":778},{"id":1100,"depth":260,"text":1103},{"id":1190,"depth":260,"text":1193},{"id":1295,"depth":252,"text":1296,"children":1547},[1548,1549,1550,1551],{"id":1305,"depth":260,"text":1306},{"id":1312,"depth":260,"text":1313},{"id":1463,"depth":260,"text":1464},{"id":1488,"depth":260,"text":1489},"engineering","2023-06-27","CI/CD pipelines can be simple or complex, what makes them efficient are CI rules that define when and how they run.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749669673/Blog/Hero%20Images/engineering.png",{},"/en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines",{"title":1562,"description":1554,"ogTitle":1562,"ogDescription":1554,"noIndex":1557,"ogImage":1558,"ogUrl":1563,"ogSiteName":1564,"ogType":1565,"canonicalUrls":1563},"DevSecOps workflows with conditional CI/CD pipeline rules","https://about.gitlab.com/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines","https://about.gitlab.com","article","efficient-devsecops-workflows-with-rules-for-conditional-pipelines","en-us/blog/efficient-devsecops-workflows-with-rules-for-conditional-pipelines",[1569,1570,1571,1572,1573],"tutorial","CI","CD","DevSecOps","DevSecOps platform","BlogPost","vEV0tp6mOXig1OB0baAwGR-LJbR6BDODY1K799XLEIs",{"logo":1577,"freeTrial":1582,"sales":1587,"login":1592,"items":1597,"search":1921,"minimal":1952,"duo":1971,"switchNav":1980,"pricingDeployment":1991},{"config":1578},{"href":1579,"dataGaName":1580,"dataGaLocation":1581},"/","gitlab logo","header",{"text":1583,"config":1584},"Get free trial",{"href":1585,"dataGaName":1586,"dataGaLocation":1581},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":1588,"config":1589},"Request a demo",{"href":1590,"dataGaName":1591,"dataGaLocation":1581},"/sales/?contact-topic=request-demo","sales",{"text":1593,"config":1594},"Sign in",{"href":1595,"dataGaName":1596,"dataGaLocation":1581},"https://gitlab.com/users/sign_in/","sign in",[1598,1626,1725,1730,1844,1899],{"text":1599,"config":1600,"menu":1602},"Platform",{"dataNavLevelOne":1601},"platform",{"type":1603,"columns":1604},"cards",[1605,1611,1618],{"title":1599,"description":1606,"link":1607},"The intelligent orchestration platform for DevSecOps",{"text":1608,"config":1609},"Explore our Platform",{"href":1610,"dataGaName":1601,"dataGaLocation":1581},"/platform/",{"title":1612,"description":1613,"link":1614},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":1615,"config":1616},"Meet GitLab Duo",{"href":1525,"dataGaName":1617,"dataGaLocation":1581},"gitlab duo agent platform",{"title":1619,"description":1620,"link":1621},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":1622,"config":1623},"Learn more",{"href":1624,"dataGaName":1625,"dataGaLocation":1581},"/why-gitlab/","why gitlab",{"text":1627,"left":854,"config":1628,"menu":1630},"Product",{"dataNavLevelOne":1629},"solutions",{"type":1631,"link":1632,"columns":1636,"feature":1704},"lists",{"text":1633,"config":1634},"View all Solutions",{"href":1635,"dataGaName":1629,"dataGaLocation":1581},"/solutions/",[1637,1660,1683],{"title":1464,"description":1638,"link":1639,"items":1644},"CI/CD and automation to accelerate deployment",{"config":1640},{"icon":1641,"href":1642,"dataGaName":1643,"dataGaLocation":1581},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[1645,1649,1652,1656],{"text":1646,"config":1647},"CI/CD",{"href":1648,"dataGaLocation":1581,"dataGaName":1646},"/solutions/continuous-integration/",{"text":1612,"config":1650},{"href":1525,"dataGaLocation":1581,"dataGaName":1651},"gitlab duo agent platform - product menu",{"text":1653,"config":1654},"Source Code Management",{"href":1655,"dataGaLocation":1581,"dataGaName":1653},"/solutions/source-code-management/",{"text":1657,"config":1658},"Automated Software Delivery",{"href":1642,"dataGaLocation":1581,"dataGaName":1659},"Automated software delivery",{"title":1661,"description":1662,"link":1663,"items":1668},"Security","Deliver code faster without compromising security",{"config":1664},{"href":1665,"dataGaName":1666,"dataGaLocation":1581,"icon":1667},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1669,1673,1678],{"text":1670,"config":1671},"Application Security Testing",{"href":1665,"dataGaName":1672,"dataGaLocation":1581},"Application security testing",{"text":1674,"config":1675},"Software Supply Chain Security",{"href":1676,"dataGaLocation":1581,"dataGaName":1677},"/solutions/supply-chain/","Software supply chain security",{"text":1679,"config":1680},"Software Compliance",{"href":1681,"dataGaName":1682,"dataGaLocation":1581},"/solutions/software-compliance/","software compliance",{"title":1684,"link":1685,"items":1690},"Measurement",{"config":1686},{"icon":1687,"href":1688,"dataGaName":1689,"dataGaLocation":1581},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[1691,1695,1699],{"text":1692,"config":1693},"Visibility & Measurement",{"href":1688,"dataGaLocation":1581,"dataGaName":1694},"Visibility and Measurement",{"text":1696,"config":1697},"Value Stream Management",{"href":1698,"dataGaLocation":1581,"dataGaName":1696},"/solutions/value-stream-management/",{"text":1700,"config":1701},"Analytics & Insights",{"href":1702,"dataGaLocation":1581,"dataGaName":1703},"/solutions/analytics-and-insights/","Analytics and insights",{"title":1705,"type":1631,"items":1706},"GitLab for",[1707,1713,1719],{"text":1708,"config":1709},"Enterprise",{"icon":1710,"href":1711,"dataGaLocation":1581,"dataGaName":1712},"Building","/enterprise/","enterprise",{"text":1714,"config":1715},"Small Business",{"icon":1716,"href":1717,"dataGaLocation":1581,"dataGaName":1718},"Work","/small-business/","small business",{"text":1720,"config":1721},"Public Sector",{"icon":1722,"href":1723,"dataGaLocation":1581,"dataGaName":1724},"Organization","/solutions/public-sector/","public sector",{"text":1726,"config":1727},"Pricing",{"href":1728,"dataGaName":1729,"dataGaLocation":1581,"dataNavLevelOne":1729},"/pricing/","pricing",{"text":1731,"config":1732,"menu":1734},"Resources",{"dataNavLevelOne":1733},"resources",{"type":1631,"link":1735,"columns":1739,"feature":1833},{"text":1736,"config":1737},"View all resources",{"href":1738,"dataGaName":1733,"dataGaLocation":1581},"/resources/",[1740,1773,1800],{"title":1741,"items":1742},"Getting started",[1743,1748,1753,1758,1763,1768],{"text":1744,"config":1745},"Install",{"href":1746,"dataGaName":1747,"dataGaLocation":1581},"/install/","install",{"text":1749,"config":1750},"Quick start guides",{"href":1751,"dataGaName":1752,"dataGaLocation":1581},"/get-started/","quick setup checklists",{"text":1754,"config":1755},"Learn",{"href":1756,"dataGaLocation":1581,"dataGaName":1757},"https://university.gitlab.com/","learn",{"text":1759,"config":1760},"Product documentation",{"href":1761,"dataGaName":1762,"dataGaLocation":1581},"https://docs.gitlab.com/","product documentation",{"text":1764,"config":1765},"Best practice videos",{"href":1766,"dataGaName":1767,"dataGaLocation":1581},"/getting-started-videos/","best practice videos",{"text":1769,"config":1770},"Integrations",{"href":1771,"dataGaName":1772,"dataGaLocation":1581},"/integrations/","integrations",{"title":1774,"items":1775},"Discover",[1776,1781,1786,1791,1795],{"text":1777,"config":1778},"Customer success stories",{"href":1779,"dataGaName":1780,"dataGaLocation":1581},"/customers/","customer success stories",{"text":1782,"config":1783},"Blog",{"href":1784,"dataGaName":1785,"dataGaLocation":1581},"/blog/","blog",{"text":1787,"config":1788},"Demo Hub",{"href":1789,"dataGaName":1790,"dataGaLocation":1581},"/demo-hub/","demo hub",{"text":1792,"config":1793},"The Source",{"href":1794,"dataGaName":1785,"dataGaLocation":1581},"/the-source/",{"text":1796,"config":1797},"Remote",{"href":1798,"dataGaName":1799,"dataGaLocation":1581},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1801,"items":1802},"Connect",[1803,1808,1813,1818,1823,1828],{"text":1804,"config":1805},"GitLab Services",{"href":1806,"dataGaName":1807,"dataGaLocation":1581},"/services/","services",{"text":1809,"config":1810},"Contribute",{"href":1811,"dataGaName":1812,"dataGaLocation":1581},"https://contributors.gitlab.com","contribute",{"text":1814,"config":1815},"Community",{"href":1816,"dataGaName":1817,"dataGaLocation":1581},"/community/","community",{"text":1819,"config":1820},"Forum",{"href":1821,"dataGaName":1822,"dataGaLocation":1581},"https://forum.gitlab.com/","forum",{"text":1824,"config":1825},"Events",{"href":1826,"dataGaName":1827,"dataGaLocation":1581},"/events/","events",{"text":1829,"config":1830},"Partners",{"href":1831,"dataGaName":1832,"dataGaLocation":1581},"/partners/","partners",{"config":1834,"title":1837,"text":1838,"link":1839},{"background":1835,"textColor":1836},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":1840,"config":1841},"Read the latest",{"href":1842,"dataGaName":1843,"dataGaLocation":1581},"/whats-new/","whats new",{"text":1845,"config":1846,"menu":1848},"Company",{"dataNavLevelOne":1847},"company",{"type":1631,"columns":1849},[1850],{"items":1851},[1852,1857,1862,1864,1869,1874,1879,1884,1889,1894],{"text":1853,"config":1854},"About",{"href":1855,"dataGaName":1856,"dataGaLocation":1581},"/company/","about",{"text":1858,"config":1859,"footerGa":1861},"Jobs",{"href":1860,"dataGaName":28,"dataGaLocation":1581},"/jobs/",{"dataGaName":28},{"text":1824,"config":1863},{"href":1826,"dataGaName":1827,"dataGaLocation":1581},{"text":1865,"config":1866},"Leadership",{"href":1867,"dataGaName":1868,"dataGaLocation":1581},"/company/team/e-group/","leadership",{"text":1870,"config":1871},"Handbook",{"href":1872,"dataGaName":1873,"dataGaLocation":1581},"https://handbook.gitlab.com/","handbook",{"text":1875,"config":1876},"Investor relations",{"href":1877,"dataGaName":1878,"dataGaLocation":1581},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1880,"config":1881},"Trust Center",{"href":1882,"dataGaName":1883,"dataGaLocation":1581},"/security/","trust center",{"text":1885,"config":1886},"AI Transparency Center",{"href":1887,"dataGaName":1888,"dataGaLocation":1581},"/ai-transparency-center/","ai transparency center",{"text":1890,"config":1891},"Newsletter",{"href":1892,"dataGaName":1893,"dataGaLocation":1581},"/company/contact/#contact-forms","newsletter",{"text":1895,"config":1896},"Press",{"href":1897,"dataGaName":1898,"dataGaLocation":1581},"/press/","press",{"text":1900,"config":1901,"menu":1902},"Contact us",{"dataNavLevelOne":1847},{"type":1631,"columns":1903},[1904],{"items":1905},[1906,1911,1916],{"text":1907,"config":1908},"Talk to sales",{"href":1909,"dataGaName":1910,"dataGaLocation":1581},"/sales/","talk to sales",{"text":1912,"config":1913},"Support portal",{"href":1914,"dataGaName":1915,"dataGaLocation":1581},"https://support.gitlab.com/hc/en-us","support portal",{"text":1917,"config":1918},"Customer portal",{"href":1919,"dataGaName":1920,"dataGaLocation":1581},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1922,"login":1923,"suggestions":1930},"Close",{"text":1924,"link":1925},"To search repositories and projects, login to",{"text":1926,"config":1927},"gitlab.com",{"href":1595,"dataGaName":1928,"dataGaLocation":1929},"search login","search",{"text":1931,"default":1932},"Suggestions",[1933,1935,1939,1941,1945,1949],{"text":1612,"config":1934},{"href":1525,"dataGaName":1612,"dataGaLocation":1929},{"text":1936,"config":1937},"Code Suggestions (AI)",{"href":1938,"dataGaName":1936,"dataGaLocation":1929},"/solutions/code-suggestions/",{"text":1646,"config":1940},{"href":1648,"dataGaName":1646,"dataGaLocation":1929},{"text":1942,"config":1943},"GitLab on AWS",{"href":1944,"dataGaName":1942,"dataGaLocation":1929},"/partners/technology-partners/aws/",{"text":1946,"config":1947},"GitLab on Google Cloud",{"href":1948,"dataGaName":1946,"dataGaLocation":1929},"/partners/technology-partners/google-cloud-platform/",{"text":1950,"config":1951},"Why GitLab?",{"href":1624,"dataGaName":1950,"dataGaLocation":1929},{"freeTrial":1953,"mobileIcon":1958,"desktopIcon":1963,"secondaryButton":1966},{"text":1954,"config":1955},"Start free trial",{"href":1956,"dataGaName":1586,"dataGaLocation":1957},"https://gitlab.com/-/trials/new/","nav",{"altText":1959,"config":1960},"Gitlab Icon",{"src":1961,"dataGaName":1962,"dataGaLocation":1957},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1959,"config":1964},{"src":1965,"dataGaName":1962,"dataGaLocation":1957},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1967,"config":1968},"Get Started",{"href":1969,"dataGaName":1970,"dataGaLocation":1957},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1972,"mobileIcon":1976,"desktopIcon":1978},{"text":1973,"config":1974},"Learn more about GitLab Duo",{"href":1525,"dataGaName":1975,"dataGaLocation":1957},"gitlab duo",{"altText":1959,"config":1977},{"src":1961,"dataGaName":1962,"dataGaLocation":1957},{"altText":1959,"config":1979},{"src":1965,"dataGaName":1962,"dataGaLocation":1957},{"button":1981,"mobileIcon":1986,"desktopIcon":1988},{"text":1982,"config":1983},"/switch",{"href":1984,"dataGaName":1985,"dataGaLocation":1957},"#contact","switch",{"altText":1959,"config":1987},{"src":1961,"dataGaName":1962,"dataGaLocation":1957},{"altText":1959,"config":1989},{"src":1990,"dataGaName":1962,"dataGaLocation":1957},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1992,"mobileIcon":1997,"desktopIcon":1999},{"text":1993,"config":1994},"Back to pricing",{"href":1728,"dataGaName":1995,"dataGaLocation":1957,"icon":1996},"back to pricing","GoBack",{"altText":1959,"config":1998},{"src":1961,"dataGaName":1962,"dataGaLocation":1957},{"altText":1959,"config":2000},{"src":1965,"dataGaName":1962,"dataGaLocation":1957},{"title":2002,"titleMobile":2003,"button":2004,"config":2009},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":1622,"config":2005},{"href":2006,"dataGaName":2007,"dataGaLocation":2008},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":2010,"disabled":1557},"release",{"data":2012},{"text":2013,"source":2014,"edit":2020,"contribute":2025,"config":2030,"items":2035,"minimal":2243},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":2015,"config":2016},"View page source",{"href":2017,"dataGaName":2018,"dataGaLocation":2019},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2021,"config":2022},"Edit this page",{"href":2023,"dataGaName":2024,"dataGaLocation":2019},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2026,"config":2027},"Please contribute",{"href":2028,"dataGaName":2029,"dataGaLocation":2019},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2031,"facebook":2032,"youtube":2033,"linkedin":2034},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2036,2083,2135,2179,2211],{"title":1726,"links":2037,"subMenu":2052},[2038,2042,2047],{"text":2039,"config":2040},"View plans",{"href":1728,"dataGaName":2041,"dataGaLocation":2019},"view plans",{"text":2043,"config":2044},"Why Premium?",{"href":2045,"dataGaName":2046,"dataGaLocation":2019},"/pricing/premium/","why premium",{"text":2048,"config":2049},"Why Ultimate?",{"href":2050,"dataGaName":2051,"dataGaLocation":2019},"/pricing/ultimate/","why ultimate",[2053],{"title":2054,"links":2055},"Contact Us",[2056,2059,2061,2063,2068,2073,2078],{"text":2057,"config":2058},"Contact sales",{"href":1909,"dataGaName":1591,"dataGaLocation":2019},{"text":1912,"config":2060},{"href":1914,"dataGaName":1915,"dataGaLocation":2019},{"text":1917,"config":2062},{"href":1919,"dataGaName":1920,"dataGaLocation":2019},{"text":2064,"config":2065},"Status",{"href":2066,"dataGaName":2067,"dataGaLocation":2019},"https://status.gitlab.com/","status",{"text":2069,"config":2070},"Terms of use",{"href":2071,"dataGaName":2072,"dataGaLocation":2019},"/terms/","terms of use",{"text":2074,"config":2075},"Privacy statement",{"href":2076,"dataGaName":2077,"dataGaLocation":2019},"/privacy/","privacy statement",{"text":2079,"config":2080},"Cookie preferences",{"dataGaName":2081,"dataGaLocation":2019,"id":2082,"isOneTrustButton":854},"cookie preferences","ot-sdk-btn",{"title":1627,"links":2084,"subMenu":2092},[2085,2088],{"text":1573,"config":2086},{"href":1610,"dataGaName":2087,"dataGaLocation":2019},"devsecops platform",{"text":2089,"config":2090},"AI-Assisted Development",{"href":1525,"dataGaName":2091,"dataGaLocation":2019},"ai-assisted development",[2093],{"title":2094,"links":2095},"Topics",[2096,2101,2106,2111,2116,2120,2125,2130],{"text":2097,"config":2098},"CICD",{"href":2099,"dataGaName":2100,"dataGaLocation":2019},"/topics/ci-cd/","cicd",{"text":2102,"config":2103},"GitOps",{"href":2104,"dataGaName":2105,"dataGaLocation":2019},"/topics/gitops/","gitops",{"text":2107,"config":2108},"DevOps",{"href":2109,"dataGaName":2110,"dataGaLocation":2019},"/topics/devops/","devops",{"text":2112,"config":2113},"Version Control",{"href":2114,"dataGaName":2115,"dataGaLocation":2019},"/topics/version-control/","version control",{"text":1572,"config":2117},{"href":2118,"dataGaName":2119,"dataGaLocation":2019},"/topics/devsecops/","devsecops",{"text":2121,"config":2122},"Cloud Native",{"href":2123,"dataGaName":2124,"dataGaLocation":2019},"/topics/cloud-native/","cloud native",{"text":2126,"config":2127},"AI for Coding",{"href":2128,"dataGaName":2129,"dataGaLocation":2019},"/topics/devops/ai-for-coding/","ai for coding",{"text":2131,"config":2132},"Agentic AI",{"href":2133,"dataGaName":2134,"dataGaLocation":2019},"/topics/agentic-ai/","agentic ai",{"title":2136,"links":2137},"Solutions",[2138,2140,2142,2147,2151,2154,2158,2161,2163,2166,2169,2174],{"text":1670,"config":2139},{"href":1665,"dataGaName":1670,"dataGaLocation":2019},{"text":1659,"config":2141},{"href":1642,"dataGaName":1643,"dataGaLocation":2019},{"text":2143,"config":2144},"Agile development",{"href":2145,"dataGaName":2146,"dataGaLocation":2019},"/solutions/agile-delivery/","agile delivery",{"text":2148,"config":2149},"SCM",{"href":1655,"dataGaName":2150,"dataGaLocation":2019},"source code management",{"text":2097,"config":2152},{"href":1648,"dataGaName":2153,"dataGaLocation":2019},"continuous integration & delivery",{"text":2155,"config":2156},"Value stream management",{"href":1698,"dataGaName":2157,"dataGaLocation":2019},"value stream management",{"text":2102,"config":2159},{"href":2160,"dataGaName":2105,"dataGaLocation":2019},"/solutions/gitops/",{"text":1708,"config":2162},{"href":1711,"dataGaName":1712,"dataGaLocation":2019},{"text":2164,"config":2165},"Small business",{"href":1717,"dataGaName":1718,"dataGaLocation":2019},{"text":2167,"config":2168},"Public sector",{"href":1723,"dataGaName":1724,"dataGaLocation":2019},{"text":2170,"config":2171},"Education",{"href":2172,"dataGaName":2173,"dataGaLocation":2019},"/solutions/education/","education",{"text":2175,"config":2176},"Financial services",{"href":2177,"dataGaName":2178,"dataGaLocation":2019},"/solutions/finance/","financial services",{"title":1731,"links":2180},[2181,2183,2185,2187,2190,2192,2195,2197,2199,2201,2203,2205,2207,2209],{"text":1744,"config":2182},{"href":1746,"dataGaName":1747,"dataGaLocation":2019},{"text":1749,"config":2184},{"href":1751,"dataGaName":1752,"dataGaLocation":2019},{"text":1754,"config":2186},{"href":1756,"dataGaName":1757,"dataGaLocation":2019},{"text":1759,"config":2188},{"href":1761,"dataGaName":2189,"dataGaLocation":2019},"docs",{"text":1782,"config":2191},{"href":1784,"dataGaName":1785,"dataGaLocation":2019},{"text":2193,"config":2194},"What's new",{"href":1842,"dataGaName":1843,"dataGaLocation":2019},{"text":1777,"config":2196},{"href":1779,"dataGaName":1780,"dataGaLocation":2019},{"text":1796,"config":2198},{"href":1798,"dataGaName":1799,"dataGaLocation":2019},{"text":1804,"config":2200},{"href":1806,"dataGaName":1807,"dataGaLocation":2019},{"text":1809,"config":2202},{"href":1811,"dataGaName":1812,"dataGaLocation":2019},{"text":1814,"config":2204},{"href":1816,"dataGaName":1817,"dataGaLocation":2019},{"text":1819,"config":2206},{"href":1821,"dataGaName":1822,"dataGaLocation":2019},{"text":1824,"config":2208},{"href":1826,"dataGaName":1827,"dataGaLocation":2019},{"text":1829,"config":2210},{"href":1831,"dataGaName":1832,"dataGaLocation":2019},{"title":1845,"links":2212},[2213,2215,2217,2219,2221,2223,2227,2232,2234,2236,2238],{"text":1853,"config":2214},{"href":1855,"dataGaName":1847,"dataGaLocation":2019},{"text":1858,"config":2216},{"href":1860,"dataGaName":28,"dataGaLocation":2019},{"text":1865,"config":2218},{"href":1867,"dataGaName":1868,"dataGaLocation":2019},{"text":1870,"config":2220},{"href":1872,"dataGaName":1873,"dataGaLocation":2019},{"text":1875,"config":2222},{"href":1877,"dataGaName":1878,"dataGaLocation":2019},{"text":2224,"config":2225},"Sustainability",{"href":2226,"dataGaName":2224,"dataGaLocation":2019},"/sustainability/",{"text":2228,"config":2229},"Diversity, inclusion and belonging (DIB)",{"href":2230,"dataGaName":2231,"dataGaLocation":2019},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1880,"config":2233},{"href":1882,"dataGaName":1883,"dataGaLocation":2019},{"text":1890,"config":2235},{"href":1892,"dataGaName":1893,"dataGaLocation":2019},{"text":1895,"config":2237},{"href":1897,"dataGaName":1898,"dataGaLocation":2019},{"text":2239,"config":2240},"Modern Slavery Transparency Statement",{"href":2241,"dataGaName":2242,"dataGaLocation":2019},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2244},[2245,2248,2251],{"text":2246,"config":2247},"Terms",{"href":2071,"dataGaName":2072,"dataGaLocation":2019},{"text":2249,"config":2250},"Cookies",{"dataGaName":2081,"dataGaLocation":2019,"id":2082,"isOneTrustButton":854},{"text":2252,"config":2253},"Privacy",{"href":2076,"dataGaName":2077,"dataGaLocation":2019},[2255],{"id":2256,"title":7,"body":1556,"config":2257,"content":2259,"description":1556,"extension":2263,"meta":2264,"navigation":854,"path":2265,"seo":2266,"stem":2267,"__hash__":2268},"blogAuthors/en-us/blog/authors/abubakar-siddiq-ango.yml",{"template":2258},"BlogAuthor",{"name":7,"config":2260},{"headshot":2261,"ctfId":2262},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660104/Blog/Author%20Headshots/abuango-headshot.jpg","abuango","yml",{},"/en-us/blog/authors/abubakar-siddiq-ango",{},"en-us/blog/authors/abubakar-siddiq-ango","u5Jv4JxCpfmcGQuXEU4Lr5xVBJP9LAB2NkXRMLeYwPE",[2270,2279,2287],{"title":2271,"description":2272,"heroImage":2273,"category":1552,"date":2274,"authors":2275,"slug":2278,"externalUrl":1556},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[2276,2277],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":2280,"description":2281,"heroImage":2282,"category":1552,"date":2283,"authors":2284,"slug":2286,"externalUrl":1556},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[2285],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":2288,"description":2289,"heroImage":2290,"category":1552,"date":2291,"authors":2292,"slug":2294,"externalUrl":1556},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[2293],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":2296},[2297,2311,2323,2335],{"id":2298,"categories":2299,"header":2301,"text":2302,"button":2303,"image":2308},"ai-modernization",[2300],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":2304,"config":2305},"Get your AI maturity score",{"href":2306,"dataGaName":2307,"dataGaLocation":1785},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":2309},{"src":2310},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2312,"categories":2313,"header":2315,"text":2302,"button":2316,"image":2320},"devops-modernization",[2314,2119],"product","Are you just managing tools or shipping innovation?",{"text":2317,"config":2318},"Get your DevOps maturity score",{"href":2319,"dataGaName":2307,"dataGaLocation":1785},"/assessments/devops-modernization-assessment/",{"config":2321},{"src":2322},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2324,"categories":2325,"header":2327,"text":2302,"button":2328,"image":2332},"security-modernization",[2326],"security","Are you trading speed for security?",{"text":2329,"config":2330},"Get your security maturity score",{"href":2331,"dataGaName":2307,"dataGaLocation":1785},"/assessments/security-modernization-assessment/",{"config":2333},{"src":2334},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2336,"paths":2337,"header":2340,"text":2341,"button":2342,"image":2347},"github-azure-migration",[2338,2339],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":2343,"config":2344},"See how GitLab compares to GitHub",{"href":2345,"dataGaName":2346,"dataGaLocation":1785},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2348},{"src":2322},{"header":2350,"blurb":2351,"button":2352,"secondaryButton":2357},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":2353,"config":2354},"Get your free trial",{"href":2355,"dataGaName":1586,"dataGaLocation":2356},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":2057,"config":2358},{"href":1909,"dataGaName":1591,"dataGaLocation":2356},1786803759024]